C、C++函數和類庫詳解(VC++版)(未完成)
es源文件包含項目使用的附加資源的腳本文件。可以在項目的.rc文件的頂部包括.rc2文件。.rc2文件用於存放由多個不同項目使用的資源。不必為不同的項目多次創建相同的資源,而是可以將它們放在一個.rc2文件中,然後將該.rc2文件包括在主.rc文件中。一個項目最多只能有一個附加資源的腳本文件。Projname.defProjname源文件DLL項目的模塊定義文件。對於控制項,它提供控制項的名稱和說明以及運行時堆的大小。一個項目最多只能有一個模塊定義文件。Projname.icoProjname
es資源文件項目或控制項的圖標文件。該圖標在應用程序最小化時出現。它還用在應用程序的「關於」框中。默認情況下,MFC提供MFC圖標,ATL提供ATL圖標。ProjnameDoc.icoProjname
es資源文件包括文檔/視圖結構支持的MFC項目的圖標文件。Toolbar.bmpProjname
es資源文件表示工具欄或調色板中的應用程序或控制項的點陣圖文件。該點陣圖包含在項目的資源文件中。初始工具欄和狀態欄在CMainFrame類中構造。2 函數庫2.1 函數模板(未完成)函數名稱xxx頭文件#include <xxx.h>#include <xxx.h>庫文件#pragma comment(lib, "xxx.lib")函數功能函數主要功能說明。函數聲明類型 函數名 (類型 參數1,類型 參數2,……);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.2 內存分配2.2.1 realloc函數名稱realloc頭文件#include <stdlib.h>#include <malloc.h>庫文件無函數功能調整一塊已分配的舊內存的長度,或者直接分配一塊新內存。函數聲明void * realloc (void * ptr,size_t size);函數參數ptr,[輸入]:已分配的舊內存指針。如果為NULL,表示直接分配一塊新內存,此時本函數就類似malloc()函數。size,[輸入]:新內存的長度,單位位元組。如果為0,表示釋放已分配的舊內存。如果新內存比舊內存大,再把舊內存的數據全部拷貝過來,新內存的指針與舊內存可能一樣,也可能不一樣,擴大的內存部分里的數據是未被初始化過的。如果新內存比舊內存小,就會把舊內存截斷作為新內存,新內存的指針與舊內存一樣,被截斷的數據會丟失。如果新內存和舊內存一樣大,將不做任何改動。返回值非NULL:新內存的指針。NULL:失敗,已分配的舊內存的長度、指針和數據都不會改變。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明如果內存不再使用時,記得調用free()釋放內存,防止內存泄露。分配的內存是全局的,在整個進程內有效。舊內存必須是先前通過調用malloc(), calloc(), 或realloc()函數分配的。2.2.2 malloc函數名稱malloc頭文件#include <stdlib.h>#include <malloc.h>庫文件無函數功能分配一塊指定長度的內存。函數聲明void * malloc (size_t size);函數參數size,[輸入]:存放內存的長度的值,單位位元組。返回值非NULL:分配的內存的指針。NULL:失敗,調用errno變數查看錯誤碼。錯誤碼ENOMEM:內存不足。線程安全是原子操作是其他說明如果內存不再使用時,記得調用free()釋放內存,防止內存泄露。分配的內存是全局的,整個進程都可以使用。分配的內存里的數據是未被初始化過的。2.2.3 calloc函數名稱calloc頭文件#include <stdlib.h>#include <malloc.h>庫文件無函數功能分配一塊nmemb個子塊長度為size的內存,子塊與子塊之間是連續的,等同於malloc ( nmemb * size)。函數聲明void * calloc (size_t nmemb,size_t size);函數參數nmemb,[輸入]:存放多少個子塊的值。size,[輸入]:存放每個子塊長度的值,單位位元組。返回值非NULL:內存的指針。NULL:失敗,調用errno變數查看錯誤碼。錯誤碼ENOMEM:內存不足。線程安全是原子操作是其他說明如果內存不再使用時,記得調用free()釋放內存,防止內存泄露。分配的內存是全局的,在整個進程內有效。內存里的數據是全部被初始化為0。2.2.4 _msize函數名稱_msize頭文件#include <malloc.h>庫文件無函數功能用於獲取alloc()相關函數或new分配的內存的實際可用的長度,單位位元組,此長度等於分配內存時指定的長度。函數聲明size_t _msize (void * memblock);函數參數memblock,[輸入]:存放alloc()相關函數或new分配的內存指針。本參數必須是有效指針,且為起始指針,不能為內存中間位置的指針,不能為NULL,否則導致意外結果。返回值正整數:分配內存的長度,單位位元組。錯誤碼無線程安全是原子操作是其他說明2.2.5 free函數名稱free頭文件#include <malloc.h>庫文件無函數功能釋放調用alloc()系列函數分配的內存。函數聲明void free (void * memblock);函數參數memblock,[輸入]:存放調用alloc()系列函數分配的內存的內存指針,不能為無效內存指針,否則會內存讀寫錯誤。返回值無錯誤碼無線程安全是原子操作是其他說明2.3 shell命令2.3.1 _popen(未完成)函數名稱_popen頭文件#include <stdio.h>庫文件無函數功能另啟動一個進程執行shell命令,並建立一條管道,可以將shell命令進程的標準輸入或輸出重定向到這條管道上,調用進程就可以通過這條管道讀取shell命令啟動的進程的標準輸出,或者也可以輸出數據到該進程的標準輸入。只能建立一條管道,一條管道只能重定向標準輸入或者標準輸出,不能同時重定向。函數聲明FILE * _popen (const char * command,const char * mode);函數參數command,[輸入]:存放shell命令字元串的指針,此命令對應的可執行文件必須是控制台程序,如果是窗口程序就會導致錯誤。例如:"dir /a"是控制台程序,但不能是"calc"(calc是計算器程序)。如果要重定向串口程序,參考:http://msdn.microsoft.com/zh-cn/library/ms682499.aspx。mode,[輸入]:重定向方式,"r"表示重定向標準輸出,"w"表示重定向標準輸入,"t"表示文本模式,"b"表示二進位模式。"r"和"w"二選一,"t"和"b"二選一。例如:"rt"、"rb"、"wt"、"wb"。返回值NULL:失敗,讀取errno變數查看錯誤碼。其他:管道的文件描述符。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明返回的文件描述符可以調用fgets()、fputs()、fscanf()、fprintf()等函數來操作標準輸入或標準輸出。返回的文件描述符在使用完後必須調用feof()函數關閉。shell命令啟動的進程不會隨調用進程的退出而退出,而是在執行完後自己退出。2.3.2 system(未完成)函數名稱system頭文件#include <stdlib.h>庫文件無函數功能執行一個shell命令,調用/bin/sh -c "shell命令"來另啟動一個進程執行,命令執行完後此函數才返回。執行命令期間,SIGCHLD信號被鎖定,SIGINT和SIGQUIT信號被忽略。函數聲明int system (const char * command);函數參數command,[輸入]:要執行的shell命令的字元串。返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明此函數在使用/bin/sh啟動執行shell命令時,會丟掉調用進程的setuid和setgid位。2.3.3 Sleep函數名稱Sleep頭文件#include <Windows.h>庫文件#pragma comment(lib, "Kernel32.lib")函數功能使當前線程暫停運行一段時間,暫停期間線程不佔用CPU資源,且會進行消息循環。函數聲明VOID Sleep (DWORD dwMilliseconds);函數參數dwMilliseconds,[輸入]:存放要暫停運行多少毫秒的值,為INFINITE宏表示無限暫停,為0表示讓出一次本線程的時間片給其他線程(用時很短)。返回值無錯誤碼無線程安全是原子操作是其他說明本函數的準確性會受到軟硬體環境的影響。2.3.4 Beep(未完成)函數名稱Beep頭文件#include <Windows.h>庫文件#pragma comment(lib, "Kernel32.lib")函數功能讓計算機發出警笛聲。函數聲明BOOL Beep (DWORD dwFreq,DWORD dwDuration);函數參數dwFreq,[輸入]:存放警笛聲的頻率的值,頻率越高聲音越大,單位Hz,範圍37 Hz至32767 Hz。dwDuration,[輸入]:存放警笛聲的持續時間的值,單位毫秒,如果本參數為負數,表示不發出警笛聲。返回值非0:成功。0:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明2.3.5 GetModuleFileName(未完成)函數名稱GetModuleFileName頭文件#include <Windows.h>庫文件#pragma comment(lib, "Kernel32.lib")函數功能獲取指定模塊的程序文件的絕對路徑字元串,存放到指定的內存。函數聲明DWORD GetModuleFileName (HMODULE hModule,LPSTR lpFilename,DWORD nSize);函數參數hModule,[輸入]:一個模塊的句柄。如果是一個DLL模塊的句柄,就獲取DLL庫文件的絕對路徑字元串;如果是一個應用程序的實例句柄,就獲取該應用程序的可執行文件的絕對路徑字元串。如果本參數為NULL,表示獲取本進程可執行文件的絕對路徑字元串,在DLL模塊中調用也是如此。lpFilename,[輸出]:存放絕對路徑字元串的內存指針。nSize,[輸入]:存放絕對路徑字元串的內存的最大長度。返回值正整數:如果絕對路徑字元串的內存的最大長度足夠大,就返回絕對路徑字元串的長度,不包括 ;如果不夠大,就返回絕對路徑字元串截斷後的長度,包括 ,並設置ERROR_INSUFFICIENT_BUFFER錯誤碼,但winXP系統設置ERROR_SUCCESS錯誤碼。0:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明如果一個DLL模塊被多個進程載入,獲取到的絕對路徑字元串可能不一樣。_pgmptr全局變數會在進程啟動前自動初始化成本進程可執行文件的絕對路徑字元串的內存指針。2.3.6 SetCurrentDirectory(未完成)函數名稱SetCurrentDirectory頭文件#include <Windows.h>庫文件#pragma comment(lib, "Kernel32.lib")函數功能設置本程序的當前活動目錄。函數聲明BOOL SetCurrentDirectory (LPCSTR lpPathName);函數參數lpPathName,[輸入]:存放當前活動目錄字元串的內存指針,可以是相對或絕對目錄。返回值非0:成功。0:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.4 文件2.4.1 打開或創建文件2.4.1.1 open(未完成)函數名稱open頭文件#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>函數功能用普通模式打開指定的文件,同時還可以創建文件。普通模式是指當輸出數據到文件時,會直接輸出到文件,等到數據已經輸出到文件後才返回,可以保證輸出成功,但會減慢輸出操作。函數聲明int open (const char * pathname,int flags);函數參數pathname,[輸入]:存放要打開的文件的路徑字元串的內存指針,可以是相對或絕對的路徑。不能為NULL。flags,[輸入]:打開文件時使用的模式和許可權。可以是(用"|"選一至多個):O_RDONLY:以只讀方式打開文件。O_WRONLY:以只寫方式打開文件。O_RDWR:以可讀寫方式打開文件。以上三種標記只能使用一個,以下的標記沒有限制。O_CREAT:如果使用此標記,表示如果要打開的文件不存在則創建並打開該文件,如果要打開的文件存在,則直接打開;如果不使用此標記,表示如果要打開的文件不存在,則立即返回失敗並設置ENOENT錯誤碼,如果要打開的文件存在,則直接打開。O_EXCL:如果使用此標記,並使用O_CREAT標記,表示如果要打開的文件不存在,則創建並打開該文件,如果要打開的文件存在,則立即返回失敗並設置EEXIST錯誤碼。此外,若O_CREAT與O_EXCL同時設置,並且欲打開的文件為符號連接,則會打開文件失敗。如果使用此標記,必須同時使用O_CREAT標記。此標記一般用於檢測文件是否是本進程創建的。O_NOCTTY:如果使用此標記,表示如果要打開的文件為終端機設備時,則不會將該終端機當成進程式控制制終端機。O_TRUNC:如果使用此標記,並使用可寫方式打開,表示把要打開的文件的長度清為0,而原來存於該文件的數據也會消失。O_APPEND:如果使用此標記,表示每次寫文件時都會從文件末尾開始,在NFS文件系統上,如果多個進程同時追加寫入同一個文件時,有可能會導致寫入結果錯亂,因為在此文件系統上的追加功能不是原子操作;如果不使用此標記,表示每次寫文件時從文件指針開始。O_NONBLOCK:如果使用此標記,表示以非阻塞方式操作打開文件,也就是無論有無數據讀取或等待,都會立即返回。O_NDELAY:同O_NONBLOCK。O_SYNC:以同步的方式打開文件。O_NOFOLLOW:如果參數pathname 所指的文件為一符號連接,則會令打開文件失敗。O_DIRECTORY:如果參數pathname 所指的文件並非為一目錄,則會令打開文件失敗。此為Linux2.2以後特有的旗標,以避免一些系統安全問題。參數mode 則有下列數種組合,只有在建立新文件時才會生效,此外真正建文件時的許可權會受到umask值所影響,因此該文件許可權應該為(mode-umaks)。S_IRWXU:00700 許可權,表示該文件所有者具有可讀、可寫及可執行的許可權。S_IRUSR:00400許可權,表示該文件所有者具有可讀取的許可權。S_IWUSR:00200 許可權,表示該文件所有者具有可寫入的許可權。S_IXUSR:00100 許可權,表示該文件所有者具有可執行的許可權。S_IRWXG:00070許可權,表示該文件所有組具有可讀、可寫及可執行的許可權。S_IRGRP:00040 許可權,表示該文件所有組具有可讀的許可權。S_IWGRP:00020許可權,表示該文件所有組具有可寫入的許可權。S_IXGRP:00010 許可權,表示該文件所有組具有可執行的許可權。S_IRWXO:00007許可權,表示其他用戶具有可讀、可寫及可執行的許可權。S_IROTH:00004 許可權,表示其他用戶具有可讀的許可權S_IWOTH:00002許可權,表示其他用戶具有可寫入的許可權。S_IXOTH:00001 許可權,表示其他用戶具有可執行的許可權。返回值-1:失敗,調用errno變數查看錯誤碼。其他:被打開文件的普通模式文件描述符。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明要讀取或寫入某個文件,必須要先打開該文件。文件使用完畢後,記得調用close()函數關閉文件描述符,釋放資源。2.4.1.2 fopen(未完成)函數名稱fopen頭文件#include <stdio.h>函數功能用緩存模式打開指定的文件,同時還可以創建文件。緩存模式是指當輸出數據到文件時,會先輸出到緩存,函數就立即返回,然後等緩存滿了系統再一次性輸出到文件,可以減少輸出數據次數,加速輸出效率,但會延遲輸出操作,存在丟數據的可能。函數聲明FILE * fopen (const char * filename,const char * mode);函數參數filename,[輸入]:存放要打開的文件的路徑字元串的內存指針,路徑要加文件名,可以是相對或絕對的路徑。mode,[輸入]:存放用什麼方式打開文件的字元串的內存指針。返回值NULL:失敗,調用errno變數查看錯誤碼。其他:被打開文件的緩存模式文件描述符。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明要讀取或寫入某個文件,必須要先打開該文件。文件使用完畢後,記得調用fclose()函數關閉文件描述符,釋放資源。可以調用fflush()函數將緩存里的數據立即輸出到文件。2.4.1.3 CreateFile(未完成)函數名稱CreateFile頭文件#include <Windows.h>函數功能打開指定的文件,同時還可以創建文件。函數聲明HANDLE CreateFile (LPCTSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile);函數參數lpFileName,[輸入]:存放要打開的文件的路徑字元串的內存指針。dwDesiredAccess,[輸入]:參數說明。參數1,[輸入|輸出|輸入&輸出]:參數說明。參數1,[輸入|輸出|輸入&輸出]:參數說明。參數1,[輸入|輸出|輸入&輸出]:參數說明。參數1,[輸入|輸出|輸入&輸出]:參數說明。參數1,[輸入|輸出|輸入&輸出]:參數說明。返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.4.2 讀取文件2.4.2.1 fread(未完成)函數名稱fread頭文件#include <xxx.h>#include <xxx.h>函數功能函數主要功能說明。函數聲明類型 函數名 (類型 參數1, 類型 參數2, ……);函數參數參數1:[輸入|輸出|輸入&輸出],參數說明。參數2:[輸入|輸出|輸入&輸出],參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知其他說明…………2.4.3 寫入文件2.4.3.1 fprintf(未完成)函數名稱xxx頭文件#include <xxx.h>#include <xxx.h>函數功能函數主要功能說明。函數聲明類型 函數名 (類型 參數1, 類型 參數2, ……);函數參數參數1:[輸入|輸出|輸入&輸出],參數說明。參數2:[輸入|輸出|輸入&輸出],參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知其他說明"
"會被自動轉換為"
"。2.4.3.2 fputs(未完成)函數名稱fputs頭文件#include <stdio.h>函數功能將字元串輸出到文件。函數聲明int fputs (const char * str,FILE * stream);函數參數str,[輸入]:存放要輸出的字元串的內存指針。stream,[輸入]:存放要輸出的文件的緩存模式文件描述符。返回值大於等於0:輸出了多少個位元組。-1:失敗。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明如果是直接輸出字元串,不格式化輸出時,fputs()函數效率比fprintf()函數效率高很多。2.4.3.3 vprintf(未完成)函數名稱xxx頭文件#include <xxx.h>#include <xxx.h>函數功能函數主要功能說明。函數聲明類型 函數名 (類型 參數1, 類型 參數2, ……);函數參數參數1:[輸入|輸出|輸入&輸出],參數說明。參數2:[輸入|輸出|輸入&輸出],參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知其他說明…………2.4.4 監測文件2.4.4.1 select(未完成)函數名稱select頭文件#include <Ws2tcpip.h>函數功能阻塞檢查一個或多個套接字是否處於可讀、可寫或錯誤的狀態。函數聲明int select (int nfds,fd_set FAR * readfds,fd_set FAR * writefds,fd_set FAR * exceptfds,const struct timeval FAR * timeout);函數參數nfds,[輸入]:此參數無意義,直接填0,此參數只是為了與Berkeley套接字兼容。readfds,[輸入&輸出]:輸入時,存放需要檢查可讀狀態的套接字組的內存指針,不需要就填NULL。writefds,[輸入&輸出]:輸入時,存放需要檢查可寫狀態的套接字組的內存指針,不需要就填NULL。exceptfds,[輸入&輸出]:輸入時,存放需要檢查錯誤狀態的套接字組的內存指針,不需要就填NULL。timeout,[輸入&輸出]:輸入時,存放阻塞檢查的超時時間的結構體的內存指針。為NULL表示超時時間為無限。為0秒0微秒表示不阻塞立即返回。返回值SOCKET_ERROR宏:失敗,調用WSAGetLastError()函數查看錯誤碼。0:成功,但在阻塞檢查的超時時間內沒有任何套接字處於需要檢查的狀態。大於0:成功,已經有多少個套接字處於需要檢查的狀態。線程安全是其他說明2.4.4.2 FindFirstChangeNotification(未完成)函數名稱FindFirstChangeNotification頭文件#include <Windows.h>函數功能監視指定的目錄中的變化,並返回變化通知句柄。不能監視文件,只能監視目錄。每一個變化通知句柄會對應一個唯一的通知隊列,當指定的目錄有要監視的變化行為時,操作系統就會自動把這條變化通知追加到變化通知句柄對應的通知隊列里。函數聲明HANDLE FindFirstChangeNotification (LPCTSTR lpPathName,BOOL bWatchSubtree,DWORD dwNotifyFilter);函數參數lpPathName,[輸入]:存放要監視的目錄的路徑字元串的內存指針,不能為文件的路徑。bWatchSubtree,[輸入]:存放是否要監視目錄的子項,TRUE表示要,FALSE表示不要。dwNotifyFilter,[輸入]:存放要監視哪些變化,可以是(用"|"選一至多個):FILE_NOTIFY_CHANGE_FILE_NAME:只監視文件名稱的變化。不監視目錄名稱的變化。FILE_NOTIFY_CHANGE_DIR_NAME:只監視目錄名稱的變化。不監視文件名稱的變化。FILE_NOTIFY_CHANGE_ATTRIBUTES:監視文件和目錄的屬性的變化。FILE_NOTIFY_CHANGE_SIZE:監視文件實際大小的變化。不監視文件內容和目錄實際大小的變化。FILE_NOTIFY_CHANGE_LAST_WRITE:監視文件的最後修改時間的變化。FILE_NOTIFY_CHANGE_LAST_ACCESS:監視文件的最後訪問時間的變化。FILE_NOTIFY_CHANGE_CREATION:監視文件的創建時間的變化。FILE_NOTIFY_CHANGE_SECURITY:監視安全屬性的變化。返回值INVALID_HANDLE_VALUE:失敗,調用GetLastError()函數查看錯誤碼。其他:變化通知句柄。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明此函數返回的變化通知句柄可以調用WaitForSingleObject()函數等待通知隊列里什麼時候有變化通知,當等待到有變化通知後,WaitForSingleObject()函數會立即返回,然後應該調用FindNextChangeNotification()函數移除最老的一條通知,要不然再次調用WaitForSingleObject()函數時,會因為通知隊列里有變化通知而立即返回。此函數返回的變化通知句柄只能監視是否有變化,無法知道具體的變化文件。變化通知句柄使用完後需要調用FindCloseChangeNotification()函數釋放句柄資源。此系列函數無法區分通知隊列里存放的具體是哪個文件或目錄的哪種變化的通知,只知道有變化。2.4.4.3 FindNextChangeNotification(未完成)函數名稱FindNextChangeNotification頭文件#include <Windows.h>函數功能根據FindFirstChangeNotification()函數獲取的變化通知句柄,移除變化通知句柄對應的通知隊列里最老的一條通知,如果通知隊列里無通知,此函數也返回成功。函數聲明BOOL FindNextChangeNotification (HANDLE hChangeHandle);函數參數hChangeHandle,[輸入]:存放變化通知句柄。返回值非0:成功。0:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明2.4.4.4 FindCloseChangeNotification(未完成)函數名稱FindCloseChangeNotification頭文件#include <Windows.h>函數功能關閉FindFirstChangeNotification()函數獲取的變化通知句柄,並釋放句柄資源。函數聲明BOOL FindCloseChangeNotification (HANDLE hChangeHandle);函數參數hChangeHandle,[輸入]:存放變化通知句柄的值。返回值非0:成功。0:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明2.4.4.5 ReadDirectoryChangesW(未完成)函數名稱ReadDirectoryChangesW頭文件#include <Windows.h>函數功能監視一個目錄下的所有改動。函數聲明BOOL ReadDirectoryChangesW (HANDLE hDirectory,LPVOID lpBuffer,DWORD nBufferLength,BOOL bWatchSubtree,DWORD dwNotifyFilter,LPDWORD lpBytesReturned,LPOVERLAPPED lpOverlapped,LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);函數參數參數1:[輸入|輸出|輸入&輸出],參數說明。參數2:[輸入|輸出|輸入&輸出],參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.4.5 移動、複製、刪除、重命名文件2.4.5.1 SHFileOperation(未完成)函數名稱SHFileOperation頭文件#include <Shellapi.h>函數功能以Shell命令方式移動、複製、刪除、重命名文件或目錄,並指定是否顯示操作過程窗口。函數聲明int SHFileOperation (LPSHFILEOPSTRUCT lpFileOp);函數參數lpFileOp,[輸入&輸出]:輸入時,存放對指定文件或目錄的指定操作的Shell命令文件操作結構體的內存指針。詳見SHFILEOPSTRUCT結構體詳解。輸出時,存放其他信息。返回值0:成功,如果用戶取消了操作,也返回成功。非0:失敗。在lpFileOp參數輸出時的fAnyOperationsAborted成員變數查看錯誤碼或具體情況。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.4.6 移動文件2.4.6.1 MoveFile(未完成)函數名稱MoveFile頭文件#include <Windows.h>函數功能移動一個已存在的文件或目錄(包括子項)到其他路徑。函數聲明BOOL MoveFile (LPCSTR lpExistingFileName,LPCSTR lpNewFileName);函數參數lpExistingFileName,[輸入]:存放要移動的文件或目錄的路徑字元串的內存指針。lpNewFileName,[輸入]:存放移動後的文件或目錄的路徑字元串的內存指針,此路徑在移動前不能是已存在的,可以為相對或絕對路徑。如果要移動文件,本參數的路徑字元串需包含新文件名,不能只包含新文件所在目錄。如果要移動目錄,本參數的路徑字元串需包含新目錄名,不能只包含新目錄所在目錄。要移動的文件與移動後的文件可以不在同一分區里,但要移動的目錄與移動後的目錄必須在同一分區里。文件或目錄的屬性與移動前一致。返回值非0:成功。0:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼ERROR_FILE_EXISTS(80)宏:移動後的文件或目錄已存在。EXXXX:錯誤碼說明。……線程安全是原子操作否其他說明2.4.6.2 MoveFileEx(未完成)函數名稱MoveFile頭文件#include <Windows.h>函數功能移動一個已存在的文件或目錄(包括子項)到其他路徑。函數聲明BOOL MoveFileEx (LPCTSTR lpExistingFileName,LPCTSTR lpNewFileName,DWORD dwFlags);函數參數lpExistingFileName,[輸入]:存放要移動的文件或目錄的路徑字元串的內存指針。lpNewFileName,[輸入]:存放移動後的文件或目錄的路徑字元串的內存指針,此路徑在移動前不能是已存在的,可以為相對或絕對路徑。如果要移動文件,本參數的路徑字元串需包含新文件名,不能只包含新文件所在目錄。如果要移動目錄,本參數的路徑字元串需包含新目錄名,不能只包含新目錄所在目錄。要移動的文件可以與移動後的文件不在同一分區里,但要移動的目錄必須與移動後的目錄在同一分區里。文件或目錄的屬性移動後與移動前一致。dwFlags,[輸入]:移動文件時的一些行為,可以為(用"|"選零至多個):MOVEFILE_REPLACE_EXISTING:如果設置本標記,表示如果移動後的文件或目錄已存在,就將其替換。如果不設置本標記,表示如果移動後的文件或目錄已存在,就報錯。MOVEFILE_COPY_ALLOWED:如果設置本標記,則允許要移動的文件或目錄與移動後的文件或目錄在不同的分區里。如果不設置本標記,則不允許,並報ERROR_NOT_SAME_DEVICE錯誤。MOVEFILE_DELAY_UNTIL_REBOOT:移動操作在系統下次重新啟動時正式進行。這樣便可改換系統文件。如果設置本標記,本函數會把要移動的文件的信息寫入到註冊表項HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerPendingFileRenameOperations下,此時本函數的返回值只說明寫入註冊表的操作是否成功。返回值非0:成功。0:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼ERROR_FILE_EXISTS(80)宏:移動後的文件或目錄的路徑已存在。EXXXX:錯誤碼說明。……線程安全是原子操作否其他說明2.4.7 刪除文件2.4.7.1 DeleteFile(未完成)函數名稱DeleteFile頭文件#include <Windows.h>函數功能刪除一個指定的已存在的文件。函數聲明BOOL DeleteFile (LPCTSTR lpFileName);函數參數lpFileName,[輸入]:存放要刪除的文件的路徑字元串的內存指針,可以為相對或絕對路徑,不能為NULL。返回值非0:成功。0:失敗,調用GetlastError()函數查看錯誤碼。錯誤碼ERROR_FILE_NOT_FOUND宏:要刪除的文件不存在。ERROR_ACCESS_DENIED宏:要刪除的文件拒絕訪問,可能文件是只讀文件,或正在被打開,或正在被內存映射等。……線程安全是原子操作是其他說明如果要刪除只讀文件,需要先把文件的只讀屬性去掉。調用本函數的進程必須具有該文件的刪除許可權,或者具有該文件所在父目錄的刪除子項許可權。本函數不能刪除目錄,刪除非空目錄可以調用SHFileOperation()函數,刪除空目錄可以調用RemoveDirectory()函數。如果要刪除的文件已經被打開,或被內存映射,本函數返回失敗。本函數是給要刪除的文件做刪除標記,而不是立即刪除,當該文件的句柄被全部關閉時,文件會被自動刪除。在該文件被做刪除標記期間,如果還有進程調用CreateFile()函數來打開文件,會返回ERROR_ACCESS_DENIED錯誤。如果要刪除的文件是一個Symbolic link符號鏈接文件,則只會刪除符號鏈接文件,不會刪除被鏈接的文件。如果要刪除被鏈接的文件,可以調用CreateFile()函數並設置FILE_FLAG_DELETE_ON_CLOSE標記。本函數是直接永久刪除文件,不會把文件移動到回收站。2.4.8 查找文件2.4.8.1 FindFirstFile(未完成)函數名稱FindFirstFile頭文件#include <Windows.h>庫文件#pragma comment(lib, "Kernel32.lib")函數功能在指定的路徑下查找名稱相匹配的一個或多個文件或目錄,返回查找句柄。函數聲明HANDLE FindFirstFile (LPCTSTR lpFileName,LPWIN32_FIND_DATA lpFindFileData);函數參數lpFileName,[輸入]:存放要查找的路徑字元串的內存指針,支持通配符。例如:"C:\*","D:\doc\file.doc"。本參數不能為NULL,或非路徑字元串。如果本參數是含有通配符的路徑,調用進程必須具有上級目錄的訪問許可權。lpFindFileData,[輸出]:存放第一個查找到的文件或目錄的屬性的結構體的內存指針。本參數不能為NULL。返回值INVALID_HANDLE_VALUE:失敗,調用GetLastError()函數查看錯誤碼。其他:成功,查找句柄。錯誤碼ERROR_FILE_NOT_FOUND:沒有查找到文件。EXXXX:錯誤碼說明。……線程安全是原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明如果是查找多個文件或目錄,可以根據本函數返回的查找句柄循環調用FindNextFile()函數獲取文件信息。如果是查找多個文件或目錄,本函數會匹配"."和".."目錄。例如:查找"C:\*"路徑,會查找出" C:\."和" C:\.."目錄本函數返回的查找句柄在不使用後,必須調用FindClose()函數釋放句柄。2.4.9 文件屬性2.4.9.1 GetFileSize(未完成)函數名稱GetFileSize頭文件#include <Windows.h>函數功能獲取指定文件的大小,不是佔用空間,且不支持文件夾。函數聲明DWORD GetFileSize (HANDLE hFile,LPDWORD lpFileSizeHigh);函數參數hFile,[輸入]:存放文件句柄的值。可以調用CreateFile()函數獲取文件句柄。lpFileSizeHigh,[輸出]:存放接收文件大小的變數的內存指針,單位位元組,可以為NULL。返回值INVALID_HANDLE_VALUE宏:失敗,調用GetLastError()查看錯誤碼。其他:文件的大小,單位位元組。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明獲取到的是文件的實時大小,不是操作系統緩存記住的大小。2.4.10 路徑字元串2.4.10.1 路徑截斷與合併2.4.10.1.1 PathFindFileName函數名稱PathFindFileName頭文件#include <Shlwapi.h>#pragma comment(lib, "Shlwapi.lib")函數功能獲取路徑字元串里的文件名子串的起始指針。函數聲明char * PathFindFileName (const char * pPath);函數參數pPath,[輸入]:路徑字元串。返回值文件名子串的起始指針錯誤碼無線程安全是原子操作是其他說明示例:路徑字元串:"c:pathfile"文件名子串:"file"路徑字元串:"c:path"文件名子串:"path"路徑字元串:"c:path"文件名子串:"path"路徑字元串:"c:"文件名子串:"c:"路徑字元串:"c:"文件名子串:"c:"路徑字元串:"path"文件名子串:"path"路徑字元串:""文件名子串:""2.4.10.1.2 PathFindExtension函數名稱PathFindExtension頭文件#include <Shlwapi.h>#pragma comment(lib, "Shlwapi.lib")函數功能獲取路徑字元串里的文件的擴展名子串的起始指針。如果擴展名出現空格,將返回失敗。函數聲明char * PathFindExtension (const char * pPath);函數參數pPath,[輸入]:路徑字元串的內存指針。返回值文件擴展名前的"."字元指針:成功。路徑字元串的" "字元指針:失敗。錯誤碼無線程安全是原子操作是其他說明一個正確的文件擴展名不能出現空格。示例:路徑字元串:"abc.txt"擴展名子串:".txt"路徑字元串:"abc.txt "擴展名子串:""路徑字元串:"abc."擴展名子串:"."路徑字元串:"abc"擴展名子串:""GetModuleFileName 得到模塊路徑名PathRemoveArgs 去除路徑的參數PathRemoveBackslash 去除路徑最後的反斜杠「」PathAddBackslash 在路徑最後加上反斜杠「」PathRemoveBlanks 去除路徑前後的空格PathAddExtension 在文件路徑後面加上擴展名PathRemoveExtension 去除文件路徑擴展名PathRenameExtension 更改文件路徑擴展名PathRemoveFileSpec 去除文件名,得到目錄PathUnquoteSpaces 去除路徑中的首尾空格PathQuoteSpaces 判斷路徑中是否有空格,有的話,就是用「」引號把整個路徑包含起來PathAppend 將一個路徑追加到另一個路徑後面PathCombine 合併兩個路徑PathSkipRoot 去掉路徑中的磁碟符或UNC部分。PathStripPath 去掉路徑中的目錄部分,得到文件名。PathStripToRoot 去掉路徑的文件部分,得到根目錄。PathCompactPath 根據像素值生成符合長度的路徑。如原始路徑: C:path1path2sample.txt根據120像素截斷後為: C:pat...sample.txt根據25像素截斷後為: ...sample.txtPathCompactPathEx 根據字元個數來生成符合長度的路徑。PathSetDlgItemPath 將路徑數據設置到對話框的子控制項上。PathUndecorate 去除路徑中的修飾——具體還沒看明白,MSDN的例子只是去掉了括弧。PathUnExpandEnvStrings 將路徑中部分數據替換為系統環境變數格式2.4.10.2 路徑查找比較函數PathFindOnPath 從路徑中查找路徑PathFindExtension 查找路徑的擴展名PathFindFileName 獲取路徑的文件名PathFindNextComponent 查找匹配路徑(不太熟悉)PathFindSuffixArray 查找給定的文件名是否有給定的後綴。PathGetArgs 獲取路徑參數PathGetCharType 獲取路徑字元類型PathGetDriveNumber 根據邏輯盤符返回驅動器序號2.4.10.3 路徑轉換函數PathRelativePathTo 創建一個路徑到另一個路徑的相對路徑。PathResolve 將一個相對路徑或絕對路徑轉換為一個合格的路徑,這個理解起來比較拗口。PathCanonicalize 規範化路徑。將格式比較亂的路徑整理成規範的路徑格式。PathBuildRoot 根據給定的磁碟序號創建根目錄路徑CreateDirectory 創建目錄GetShortPathName 將長路徑轉為8.3格式的短路徑格式GetLongPathName 將短路徑格式轉為長路徑。PathGetShortPath 將長路徑轉為短路徑格式(8.3格式)PathCreateFromUrl 將URL路徑轉為MS-DOS格式PathMakePretty 把路徑全部轉為小寫,增加可讀性。PathMakeSystemFolder 給路徑增加系統屬性PathUnmakeSystemFolder 去除路徑中的系統屬性。PathMakeUniqueName 從模板創建統一的路徑格式——沒用過,不熟悉PathProcessCommand 生成一個可執行的路徑,比如有參數的,會自動將路徑用「」包含。這在ShellExecute中比較有用。2.4.10.4 路徑驗證函數PathCleanupSpec 去除路徑中不合法的字元PathCommonPrefix 比較並提取兩個路徑相同的前綴PathFileExists 驗證路徑是否存在PathMatchSpec 判斷路徑是否匹配製定的擴展名。PathIsDirectory 判斷路徑是否是一個有效的目錄PathIsFileSpec 驗證路徑是否一個文件名(有可能是一個路徑)PathIsExe 驗證路徑是否是可執行文件。注意:不僅僅是.exe,還有.bat,.com,.src等PathIsRoot 路徑是否為根路徑PathIsRelative 判斷路徑是否是相對路徑PathIsContentType 檢測文件是否為制定類型。例如:PathIsContentType( 「hello.txt」 ,「text/plain」 ) 返回TRUEPathIsContentType( 「hello.txt」 ,「image/gif」 ) 返回FALSEPathIsHTMLFile 判斷路徑是否是html文件類型——根據系統註冊類型判斷。PathIsLFNFileSpec 判斷路徑是否是長路徑格式PathIsNetworkPath 判斷路徑是否是一個網路路徑。PathIsPrefix 判斷路徑是否含有指定前綴PathIsSameRoot 判斷路徑是否有相同根目錄PathIsSlow 判斷路徑是否是一個高度延遲的網路連接——我也不太明白是啥意思。PathIsSystemFolder 判斷路徑是否有系統屬性(屬性可以自己設定)PathIsUNC 路徑是否是UNC格式(網路路徑)PathIsUNCServer 路徑是否是UNC伺服器PathIsUNCServerShare 路徑是否僅僅是UNC的共享路徑格式PathIsURL 路徑是否是http格式。PathYetAnotherMakeUniqueName 基於已存在的文件,自動創建一個唯一的文件名。比較有用,比如存在「新建文件」,此函數會創建文件名「新建文件(2)」。2.4.11 標準輸入、輸出和出錯2.4.11.1 ungetc函數名稱ungetc頭文件#include <stdio.h>庫文件無函數功能把一個字元退回到標準輸入文件中的第一個字元,下一次將讀出此字元,不會將此字元寫到文件中和設備上,只將字元退回到標準I/O庫的流緩存區中,此字元不能被正在調用的輸入流函數讀出。函數聲明int ungetc (int c,FILE * stream);函數參數c,[輸入]:要退回的字元,只能是ASCII碼的字元,值為0-255。stream,[輸入]:標準輸入文件句柄,也就是stdin。返回值EOF:失敗。其他:退回的字元c參數。錯誤碼線程安全是 或 否 或 未知其他說明2.4.11.2 printf(未完成)函數名稱printf頭文件#include <stdio.h>庫文件無函數功能格式化輸出字元串到標準輸出文件。格式化輸出字元串就是指可以將一些變數按照一定的格式組合成一個字元串,然後輸出到指定的位置。函數聲明int printf (const char * format,...);函數參數format,[輸入]:存放格式化字元串的內存指針,不能為NULL。格式化字元串主要是使用"%"號來進行轉義的,用於描述動態參數的輸出格式,轉義格式如下:格式%[對齊方式][符號][標誌][對齊填充][最少輸出長度][.精度][長度]格式類型對齊方式無輸出右對齊。-輸出左對齊。符號無輸出數值為正時不冠以任何符號,為負時冠以"-"負號。+輸出數值為正時冠以"+"正號,為負時冠以"-"負號。空格輸出數值為正時冠以" "空格,為負時冠以"-"負號。標誌#如果格式類型為o,則在輸出時加前綴0;如果格式類型為x,則在輸出時加前綴0x;如果格式類型為X,則在輸出時加前綴0X;如果格式類型為e、E、f、F,則總是輸出小數點,即使精度設置為0;如果格式類型為g、G,則除了數值為0外總是顯示小數點;如果格式類型為其他類,則無意義;對齊填充無如果為右對齊,左邊填充空格。如果為左對齊,右邊填充空格。0如果為右對齊,左邊填充"0"。如果為左對齊,右邊填充空格。最少輸出長度無輸出時按照實際長度輸出。十進位整數用來表示最少輸出長度。如果實際長度超過該長度,就按實際長度輸出。如果實際長度少於該長度,則按對齊方式輸出。*最少輸出長度從動態參數中指定,必須是不超過long型的整數。精度無輸出時按照標準精度輸出。.十進位整數精度格式符以"."開頭,後跟十進位整數。如果輸出數字,則表示小數的位數;若實際位數大於所定義的精度數,則四捨五入。若不足則右邊補0。如果輸出的是字元串,則表示輸出字元的個數;若實際位數大於所定義的精度數,則截去超過的部分。若不足則原樣輸出。*精度從動態參數中指定,必須是不超過long型的整數。長度h和整數格式類型一起使用,表示一個short int 或者 unsigned short int 類型數值。例如:「%hu」、「%hx」和「%6.4hd」l和整數格式類型一起使用,表示一個long int 或者unsigned long int 類型值。例如:「%ld」和「%8lu」ll和整數格式類型一起使用,表示一個long long int或 unsigned long long int 類型值 (C99標準)。例如:「%lld」和「%8llu」L和浮點轉換說明符一起使用,表示一個long double值。例如:「%Lf」和「%10.4Le」j和整數轉換說明符一起使用,表示一個intmax_t或uintmax_t值。示例:「%jd」和「%8jX」t和整數轉換說明符一起使用,表示一個ptrdiff_t值(與兩個指針之間的差相對應的類型) (C99標準)。例如:「%td」和「%12ti」z和整數轉換說明符一起使用,表示一個size_t值(sizeof返回的類型) (C99標準)。例如:「%zd」和「%12zx」格式類型c輸出單個ASCII碼字元d輸出有符號十進位整數i輸出有符號十進位整數e以「科學記數法」的形式輸出有符號十進位浮點數,如2.451e+02E以「科學記數法」的形式輸出有符號十進位浮點數,如2.451E+02f輸出有符號十進位浮點數,不帶精度時,保留6位小數g選用e或f格式中較短寬度的一個輸出十進位浮點數,不輸出無效零G選用E或f格式中較短寬度的一個輸出十進位浮點數,不輸出無效零o輸出無符號八進位整數p輸出指針變數的無符號十六進位地址值s輸出char類型字元串S輸出wchar_t類型字元串u輸出無符號十進位整數x輸出無符號小寫十六進位整數,不能輸出有符號的,如1a2b3c4dX輸出無符號大寫十六進位整數,不能輸出有符號的,如1A2B3C4D%輸出字元"%"I64配合u、d等,可以輸入輸出64位整數。VC++平台有效。如%I64u,%I64d。注意大寫。...,[輸入]:存放格式化字元串中轉義的各個參數。返回值輸出字元串的長度,單位位元組。錯誤碼無線程安全是原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明printf("[%d]", 123);輸出:[123]printf("[%10d]", 123);輸出:[ 123]printf("[%*d]", 5, 123);輸出:[ 123]printf("[%*d]", (long long)5, 123);輸出:[ 0]printf("[%-10d]", 123);輸出:[123 ]printf("[%+d]", 123);輸出:[+123]printf("[% d]", 123);輸出:[ 123]printf("[%#o]", 123);輸出:[0173]printf("[%#x]", 123);輸出:[0x7B]printf("[%#f]", 123.0);輸出:[123.000000]2.4.11.3 scanf(未完成)函數名稱scanf頭文件#include <stdio.h>庫文件無函數功能從標準輸入文件格式化輸入字元串。格式化輸入字元串就是指從指定的位置輸入字元串,然後將字元串按照一定的格式拆分並存放到變數。函數聲明int scanf (const char * format,...);函數參數format,[輸入]:存放格式化字元串的內存指針,不能為NULL。格式化字元串主要是使用"%"號來進行轉義的,用於描述動態參數的輸出格式,轉義格式如下:格式%[標誌][最少輸出長度][.精度][長度]格式類型標誌#如果格式類型為o,則在輸出時加前綴0;如果格式類型為x,則在輸出時加前綴0x;如果格式類型為X,則在輸出時加前綴0X;如果格式類型為e、E、f、F,則當結果總是輸出小數點;如果格式類型為g、G,則除了數值為0外總是顯示小數點;如果格式類型為其他類,則無意義;最多輸入長度無輸出時按照實際長度輸出。十進位整數用來表示最少輸出長度。如果實際長度超過該長度,就按實際長度輸出。如果實際長度少於該長度,則按對齊方式輸出。*最少輸出長度從動態參數中指定,必須是不超過long型的整數。長度h和整數格式類型一起使用,表示一個short int 或者 unsigned short int 類型數值。例如:「%hu」、「%hx」和「%6.4hd」l和整數格式類型一起使用,表示一個long int 或者unsigned long int 類型值。例如:「%ld」和「%8lu」ll和整數格式類型一起使用,表示一個long long int或 unsigned long long int 類型值 (C99標準)。例如:「%lld」和「%8llu」L和浮點轉換說明符一起使用,表示一個long double值。例如:「%Lf」和「%10.4Le」j和整數轉換說明符一起使用,表示一個intmax_t或uintmax_t值。示例:「%jd」和「%8jX」t和整數轉換說明符一起使用,表示一個ptrdiff_t值(與兩個指針之間的差相對應的類型) (C99標準)。例如:「%td」和「%12ti」z和整數轉換說明符一起使用,表示一個size_t值(sizeof返回的類型) (C99標準)。例如:「%zd」和「%12zx」格式類型c輸出單個ASCII碼字元d輸出十進位有符號整數i輸出十進位有符號整數e以「科學記數法」的形式輸出十進位有符號浮點數,如2.451e+02E以「科學記數法」的形式輸出十進位有符號浮點數,如2.451E+02f輸出十進位的有符號浮點數,不帶域寬時,保留6位小數g選用e或f格式中較短寬度的一個輸出十進位浮點數,不輸出無效零G選用E或f格式中較短寬度的一個輸出十進位浮點數,不輸出無效零o輸出無符號八進位整數p輸出指針的無符號十六進位地址值s輸出char類型字元串S輸出wchar_t類型字元串u輸出無符號十進位整數x輸出無符號小寫十六進位整數 (不輸出前綴Ox),如1a2b3c4dX輸出無符號大寫十六進位整數 (不輸出前綴Ox),如1A2B3C4D%輸出字元"%"I64配合u、d等,可以輸入輸出64位整數。MSVC平台有效。如%I64u,%I64d。注意大寫...,[輸出]:存放格式化字元串中轉義的各個參數。返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.5 內存映射文件文件內存映射後,讀取速度很快,比把文件內容一次性讀取到內存再讀取內存還要快。CreateFileMapping 創建內存映射文件句柄,使用前必須已經打開了該文件,不能映射長度為0的文件的,否則報1006錯誤。MapViewOfFile 具體將文件中的哪一段映射到內存。UnmapViewOfFile 釋放映射的內存。CloseHandle 關閉內存映射句柄。2.6 文件系統2.6.1 分區剩餘空間2.6.1.1 GetDiskFreeSpaceEx(未完成)函數名稱GetDiskFreeSpaceEx頭文件#include <Windows.h>函數功能獲取指定分區的用戶可用空間、用戶總空間和總可用空間。函數聲明BOOL WINAPI GetDiskFreeSpaceEx(LPCTSTR lpDirectoryName,PULARGE_INTEGER lpFreeBytesAvailable,PULARGE_INTEGER lpTotalNumberOfBytes,PULARGE_INTEGER lpTotalNumberOfFreeBytes);函數參數lpDirectoryName,[輸入]:存放分區上的一個目錄字元串的內存指針,為NULL表示當前活動目錄所在分區。例如:"C:"、"C:"、"C:windows"都表示C盤,"."表示當前活動目錄所在分區。目錄字元串後面不能加文件名,否側會失敗。目錄字元串只要在指定分區上即可,必須已經存在。調用進程對該分區必須具有FILE_LIST_DIRECTORY許可權。lpFreeBytesAvailable,[輸出]:存放用於存放用戶可用空間的結構體的內存指針,單位位元組,不需要就填NULL。用戶可用空間是指啟動本程序的用戶對指定分區的可用空間,如果啟用了磁碟配額,此參數有可能小於指定分區的總可用空間。lpTotalNumberOfBytes,[輸出]:存放用於存放用戶總空間的結構體的內存指針,不需要就填NULL。用戶總空間是指啟動本程序的用戶對指定分區的可用空間與已用空間之和,如果啟用了磁碟配額,此參數有可能小於指定分區的總空間。lpTotalNumberOfFreeBytes,[輸出]:存放用於存放總可用空間的結構體的內存指針,不需要就填NULL。總可用空間是指分區的總可用空間。返回值非0:成功。0:失敗。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明本函數獲取的分區為光碟機時,lpFreeBytesAvailable和lpTotalNumberOfFreeBytes參數輸出0,除非刻錄光碟機內有空白可寫光碟。2.7 時鐘地球分為24個時區:中時區(+0)、東一區(+1)、東二區(+2)、東三區(+3)、東四區(+4)、東五區(+5)、東六區(+6)、東七區(+7)、東八區(+8)、東九區(+9)、東十區(+10)、東十一區(+11)、東西十二區(+/-12)、西十一區(-11)、西十區(-10)、西九區(-9)、西八區(-8)、西七區(-7)、西六區(-6)、西五區(-5)、西四區(-4)、西三區(-3)、西二區(-2)、西一區(-1)。中時區也叫UTC通用協調時、UTC協調世界時、GMT格林尼治時,簡稱協調時。本地時區也叫本地時,是在操作系統中設定的,例如:北京地區,那就是東八區北京時間。UTC協調時的1970年1月1日00:00:00為計算機起始時刻,所有的計算機時鐘最早只能設置到這個時刻。北京時(東八區)的計算機起始時刻為1970年1月1日08:00:00。2.7.1 高精度性能計數器2.7.1.1 QueryPerformanceFrequency(未完成)函數名稱QueryPerformanceFrequency頭文件#include <Windows.h>函數功能查看當前高精度性能計數器的時鐘頻率,如果硬體不支持高精度性能計數器本函數會返回失敗。函數聲明BOOL QueryPerformanceFrequency (LARGE_INTEGER * lpFrequency);函數參數lpFrequency,[輸出]:存放當前高精度性能計數器的時鐘頻率的共用體變數的內存指針。返回值非0:成功。0:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明高精度性能計數器的時鐘頻率就是每秒累加多少次,頻率越高,精度也就越高。2.7.1.2 QueryPerformanceCounter(未完成)函數名稱QueryPerformanceCounter頭文件#include <Windows.h>函數功能查看當前高精度性能計數器的數值,如果硬體不支持高精度性能計數器本函數會返回失敗。函數聲明BOOL QueryPerformanceCounter (LARGE_INTEGER * lpPerformanceCount);函數參數lpPerformanceCount,[輸出]:存放當前高精度性能計數器的數值的共用體變數的內存指針。返回值非0:成功。0:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明在多處理器的計算機上,每個處理器都有獨立的高精度性能計數器,所以多次調用此函數會返回不同處理器的數值。如果要為線程指定處理器相關性,請使用SetThreadAffinityMask()函數。當前高精度性能計數器的數值除以時鐘頻率就是計算機已經運行了多少秒。記錄兩個時刻的高精度性能計數器的數值,相減後得出間隔時間,然後除以時鐘頻率就知道時隔多少秒,多少毫秒,甚至是微秒。2.7.2 獲取時區2.7.2.1 GetTimeZoneInformation(未完成)函數名稱GetTimeZoneInformation頭文件#include <Windows.h>庫文件無函數功能獲取當前系統的時區。函數聲明DWORD WINAPI GetTimeZoneInformation (LPTIME_ZONE_INFORMATION lpTimeZoneInformation);函數參數lpTimeZoneInformation,[輸出]:參數說明。返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.7.3 設置時區2.7.3.1 SetTimeZoneInformation(未完成)函數名稱SetTimeZoneInformation頭文件#include <xxx.h>#include <xxx.h>庫文件#pragma comment(lib, "xxx.lib")函數功能函數主要功能說明。函數聲明類型 函數名 (類型 參數1,類型 參數2,……);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.7.4 獲取時鐘2.7.4.1 time函數名稱time頭文件#include <time.h>庫文件無函數功能獲取當前系統時鐘,從計算機起始時刻到現在所走的秒數。函數聲明time_t time (time_t * timer);__time32_t _time32 (__time32_t * timer);__time64_t _time64 (__time64_t * timer);函數參數_Time,[輸出]:存放從計算機起始時刻到現在所走的秒數的變數的內存指針,不需要就填為NULL。返回值正整數:從計算機起始時刻到現在所走的秒數。-1:失敗。錯誤碼無線程安全是原子操作是其他說明本函數是直接獲取的秒數,無論在哪個時區都是一樣。如果調用_time32()函數,則當前操作系統的時鐘不能超過協調時的2038年1月19日 03:14:07,否則會返回失敗。如果調用_time64()函數,則當前操作系統的時鐘不能超過協調時的3000年12月31日 23:59:59,否則會返回失敗。time()函數直接內聯到_time64()函數,如果定義了_USE_32BIT_TIME_T宏,則內聯到_time32()函數。2.7.4.2 GetSystemTimeAsFileTime函數名稱GetSystemTimeAsFileTime頭文件#include <Windows.h>庫文件#pragma comment(lib, "Kernel32.lib")函數功能獲取當前系統時鐘,並轉換為文件時間結構體,獲取到的是內存緩存時間,比實際時間大約相差1秒。函數聲明VOID GetSystemTimeAsFileTime (LPFILETIME lpSystemTimeAsFileTime);函數參數lpSystemTimeAsFileTime,[輸出]:存放當前系統時間的文件時間結構體的內存指針。返回值無錯誤碼無線程安全是原子操作是其他說明2.7.4.3 GetTickcount(未完成)函數名稱GetTickcount頭文件#include <Winbase.h>庫文件#pragma comment(lib, "Kernel32.lib")函數功能獲取從操作系統啟動到現在走了多少毫秒,當關機、重啟、達到最大值4294967295(約49.71天)後,該值會自動清0。函數聲明DWORD GetTickCount (void);函數參數無返回值從操作系統啟動到現在走了多少毫秒錯誤碼無線程安全是原子操作是其他說明本函數獲取的時長不是實時變化的,而是由操作系統每隔10ms至16ms更新一次。如果擔心達到最大值後清0,可以使用GetTickCount64()函數。2.7.4.4 GetTickcount64(未完成)函數名稱GetTickcount64頭文件#include <Winbase.h>庫文件#pragma comment(lib, "Kernel32.lib")函數功能獲取從操作系統啟動到現在走了多少毫秒,當關機、重啟、達到最大值18446744073709551616(約213503982334.6天)後,該值會自動清0。函數聲明ULONGLONG GetTickCount (void);函數參數無返回值從操作系統啟動到現在走了多少毫秒錯誤碼無線程安全是原子操作是其他說明本函數獲取的時長不是實時變化的,而是由操作系統每隔10ms至16ms更新一次。2.7.5 設置時鐘2.7.5.1 settimeofday函數名稱settimeofday頭文件#include <time.h>函數功能設置當前操作系統的時鐘和時區。函數聲明int settimeofday (const struct timeval * tv, const struct timezone * tz);函數參數tv,[輸入]:將當前操作系統的時鐘要設置的時間,從1970年1月1日00:00:00到要設置的時間一共走了多少秒,為NULL表示不設置。tz,[輸入]:要設置當前操作系統的時區信息,為NULL表示不設置。返回值0:成功。-1:失敗,並設置errno錯誤碼變數。線程安全是其他說明調用此函數需要進程具有root許可權。2.7.6 時鐘轉換2.7.6.1 localtime_s函數名稱localtime_s頭文件#include <time.h>庫文件無函數功能把從本地時的計算機起始時刻到現在所走的秒數轉換成日曆,並存放到指定的日曆結構體。函數聲明errno_t localtime_s (struct tm * _Tm,const time_t * _Time);函數參數_Tm,[輸出]:存放轉換後的日曆結構體的內存指針,不能為NULL。_Time,[輸入]:存放秒數變數的內存指針,本地時的計算機起始時刻到現在所走的秒數,不能為NULL。返回值0:成功。EINVAL宏:失敗,日曆結構體的內存指針或秒數變數的內存指針是無效的。錯誤碼無線程安全是原子操作是其他說明本函數是轉換成本地時的,轉換成協調時用gmtime_s()函數。2.7.6.2 gmtime_s函數名稱gmtime_s頭文件#include <time.h>庫文件無函數功能把從協調時的計算機起始時刻到現在所走的秒數轉換成日曆,並存放到指定的日曆結構體。函數聲明errno_t gmtime_s (struct tm * _tm,const __time_t * time);函數參數_tm,[輸出]:存放轉換後日曆結構體的內存指針,不能為NULL。time,[輸入]:存放秒數變數的內存指針,協調時的計算機起始時刻到現在所走的秒數,不能為NULL。返回值0:成功。EINVAL宏:失敗,日曆結構體的內存指針或秒數變數的內存指針是無效的。錯誤碼無線程安全是原子操作是其他說明本函數是轉換成協調時的,轉換成本地時用localtime_s()函數。2.7.6.3 mktime函數名稱mktime頭文件#include <time.h>庫文件無函數功能把本地時的日曆結構體轉換為從計算機起始時刻到日曆結構體描述的那一時刻所走的秒數。函數聲明time_t mktime (struct tm * timeptr);__time32_t _mktime32 (struct tm * timeptr);__time64_t _mktime64 (struct tm * timeptr);函數參數timeptr,[輸入]:存放本地時日曆結構體的內存指針,只根據日曆結構體的tm_sec、tm_min、tm_hour、tm_mday、tm_mon成員變數轉換,不能為NULL。返回值-1:失敗,調用errno變數查看錯誤碼。其他:所走的秒數。錯誤碼EINVAL宏:日曆結構體的內存指針是無效的,或者要轉換的日曆超過了範圍。線程安全是原子操作是其他說明本函數是根據本地時的日曆轉換的。如果調用_mktime32()函數,則日曆不能超過UTC時間2038年1月19日 03:14:07、CST時間2038年1月19日 11:14:07,否則會返回失敗。如果調用_mktime64()函數,則日曆不能超過UTC時間3000年12月31日 23:59:59、CST時間3001年1月1日 7:59:59,否則會返回失敗。mktime()函數直接內聯到_mktime64()函數,如果定義了_USE_32BIT_TIME_T宏,則內聯到_mktime32()函數。2.8 信號2.8.1 signal(未完成)函數名稱signal頭文件#include < signal.h>函數功能對指定的信號設置捕捉函數,只會捕捉一次該信號。函數聲明sighandler_t signal (int signum,sighandler_t handler);函數參數signum,[輸入]:要捕捉的信號,可以是(選一至一個):SIGINT:interrupt(Ctrl+C中斷)SIGILL:illegal instruction - invalid function image(非法指令)SIGFPE:floating point exception(浮點異常)SIGSEGV:segment violation(段錯誤)SIGTERM:Software termination signal from kill(Kill發出的軟體終止)SIGBREAK:Ctrl-Break sequence(Ctrl+Break中斷)SIGABRT:abnormal termination triggered by abort call(Abort)handler,[輸入]:本參數可以是信號捕捉函數的指針,信號捕捉函數聲明必須是void sighandler (int signum),信號捕捉函數第一個參數表示捕捉到的信號碼,信號捕捉函數只會捕捉一次該信號,如果需要多次捕捉,可以考慮在信號捕捉函數里再次設置指定信號的捕捉函數;本參數也可以是(選一至一個):SIG_DFL:此信號交由系統預設捕捉處理,本進程不再捕捉。SIG_IGN:忽略掉該信號而不做任何處理。返回值handler參數:成功。SIG_ERR:失敗,並設置errno。錯誤碼EINVAL:參數錯誤。線程安全是原子操作是其他說明SIGKILL和SIGSTOP信號無法被阻塞、捕捉或忽略的。SIGSEGV和SIGABRT信號捕捉函數是在主線程中執行的,執行時會中斷主線程的執行,不會中斷進程其他線程的執行,執行完後主線程又回到之前中斷的位置繼續執行。但是所有的SIGSEGV和SIGABRT信號捕捉函數都是在主線程中執行,如果信號捕捉函數在執行時,進程再次捕捉到SIGSEGV或SIGABRT信號,則立即暫停當前執行的信號捕捉函數,開始執行剛剛捕捉到的信號對應的信號捕捉函數,執行完後再回到之前被暫停的信號捕捉函數繼續執行。如果進程再次捕捉到信號,以此類推。如果被暫停的信號捕捉函數非常多的時候,可能會導致堆棧溢出。SIGINT和SIGBREAK信號捕捉函數是在新的線程中執行的,執行時不會中斷進程其他線程的執行。但是所有的SIGINT和SIGBREAK信號捕捉函數都是在同一個線程中執行,如果信號捕捉函數在執行時,進程再次捕捉到SIGINT或SIGBREAK信號,則立即暫停當前執行的信號捕捉函數,開始執行剛剛捕捉到的信號對應的信號捕捉函數,執行完後再回到之前被暫停的信號捕捉函數繼續執行。如果進程再次捕捉到信號,以此類推。如果被暫停的信號捕捉函數非常多的時候,可能會造成堆棧溢出。Windows下不存在信號打斷的問題。2.9 套接字2.9.1 WSAStartup(未完成)函數名稱WSAStartup頭文件#include <Ws2tcpip.h>庫文件#pragma comment(lib, "Ws2_32.lib")函數功能函數主要功能說明。函數聲明類型 函數名 (類型 參數1,類型 參數2,……);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.9.2 socket(未完成)函數名稱socket頭文件#include <Ws2tcpip.h>庫文件#pragma comment(lib, "Ws2_32.lib")函數功能創建一個套接字句柄。函數聲明SOCKET socket (int af,int type,int protocol);函數參數af,[輸入]:存放套接字使用的地址族的值,可以為(選一至一個):AF_UNSPEC宏(0x0000):不指定ADDRESS FAMILY地址族,根據protocol協議參數確定地址族。AF_INET宏(0x0002):IPv4地址族。AF_IPX宏(0x0006):IPX/SPX地址族,要求系統必須安裝了NWLink IPX/SPX NetBIOS兼容傳輸協議。Windows Vista及以後的系統都不支持本地址族。AF_APPLETALK宏(0x0010):AppleTalk地址族,要求系統必須安裝了AppleTalk協議。Windows Vista及以後的系統都不支持本地址族。AF_NETBIOS宏(0x0011):NETBIOS地址族,要求系統必須安裝了Windows Sockets provider for NetBIOS。Windows Sockets provider for NetBIOS僅支持32位系統,且32位系統被默認裝上。Windows Sockets provider for NetBIOS不支持64位系統(包括Windows 7、Windows Server 2008、Windows Vista、Windows Server 2003、Windows XP)。使用本地址族的套接字協議必須為SOCK_DGRAM。Windows Sockets provider for NetBIOS沒有直接關聯到NetBIOS編程介面。NetBIOS編程介面在Windows Vista、Windows Server 2008及以後的系統都不支持。AF_INET6宏(0x0017):IPv6地址族。AF_IRDA宏(0x001A):紅外數據組織(IrDA)地址族,要求操作系統必須安裝了紅外埠和驅動程序。AF_BTH宏(0x0020):藍牙地址族,要求操作系統必須安裝了藍牙適配器和驅動程序。Windows XP SP2及以後的系統才支持本地址族。type,[輸入]:存放套接字使用的類型的值,可以為(選一至一個):SOCK_STREAM宏(0x0001):提供有序的、可靠的、雙向的、基於連接、並有帶外數據的位元組流傳送機制,af地址族參數必須是AF_INET或AF_INET6,protocol協議參數必須是IPPROTO_TCP。SOCK_DGRAM宏(0x0002):支持無連接的、不可靠的和使用固定大小(通常很小)緩衝區的數據報傳送機制,af地址族參數必須是AF_INET或AF_INET6,protocol協議參數必須是IPPROTO_UDP。SOCK_RAW宏(0x0003):A socket type that provides a raw socket that allows an application to manipulate the next upper-layer protocol header. To manipulate the IPv4 header, the IP_HDRINCL socket option must be set on the socket. To manipulate the IPv6 header, the IPV6_HDRINCL socket option must be set on the socket.SOCK_RDM宏(0x0004):A socket type that provides a reliable message datagram. An example of this type is the Pragmatic General Multicast (PGM) multicast protocol implementation in Windows, often referred to as reliable multicast programming.This type value is only supported if the Reliable Multicast Protocol is installed.SOCK_SEQPACKET宏(0x0005):A socket type that provides a pseudo-stream packet based on datagrams.protocol,[輸入]:存放套接字使用的協議的值,可以為(選一至一個):IPPROTO_ICMP宏(0x0001):ICMP(Internet Control Message Protocol)網路控制消息協議。af地址族參數必須是AF_UNSPEC或AF_INET或AF_INET6,type類型參數必須是SOCK_RAW。Windows XP及以後的系統才支持本協議。IPPROTO_IGMP宏(0x0002):IGMP(Internet Group Management Protocol)網路組管理協議。af地址族參數必須是AF_UNSPEC或AF_INET或AF_INET6,type類型參數必須是SOCK_RAW。Windows XP及以後的系統才支持本協議。BTHPROTO_RFCOMM宏(0x0003):Bluetooth RFCOMM(Bluetooth Radio Frequency Communications)藍牙射頻通信協議。af地址族參數必須是AF_BTH,type類型參數必須是SOCK_STREAM。Windows XP SP2及以後的系統才支持本協議。IPPROTO_TCP宏(0x0006):TCP(Transmission Control Protocol)傳輸控制協議。af地址族參數必須是AF_INET或AF_INET6,type類型參數必須是SOCK_STREAM。IPPROTO_UDP宏(0x0011):UDP(User Datagram Protocol)用戶數據報協議。af地址族參數必須是AF_INET或AF_INET6,type類型參數必須是SOCK_DGRAM。IPPROTO_ICMPV6宏(0x003A):ICMPv6(Internet Control Message Protocol Version 6)網路控制消息協議版本6。af地址族參數必須是AF_UNSPEC或AF_INET或AF_INET6,type類型參數必須是SOCK_RAW。Windows XP及以後的系統才支持本協議。IPPROTO_PGM宏(0x0071):PGM(Pragmatic General Multicast Protocol)實際通用多播協議。af地址族參數必須是AF_INET,type類型參數必須是SOCK_RDM。系統需要先安裝本協議才支持。返回值INVALID_SOCKET宏(-0x0001):失敗,調用WSAGetLastError()函數查看錯誤碼。其他:成功,返回值就是套接字句柄。錯誤碼WSANOTINITIALISED:必須在調用WSAStartup()函數成功後才能調用本函數。WSAENETDOWN:The network subsystem or the associated service provider has failed.WSAEAFNOSUPPORT:The specified address family is not supported. For example, an application tried to create a socket for the AF_IRDA address family but an infrared adapter and device driver is not installed on the local computer.WSAEINPROGRESS:A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.WSAEMFILE:No more socket descriptors are available.WSAEINVAL:An invalid argument was supplied. This error is returned if the af parameter is set to AF_UNSPEC and the type and protocol parameter are unspecified.WSAENOBUFS:No buffer space is available. The socket cannot be created.WSAEPROTONOSUPPORT:The specified protocol is not supported.WSAEPROTOTYPE:The specified protocol is the wrong type for this socket.WSAEPROVIDERFAILEDINIT:The service provider failed to initialize. This error is returned if a layered service provider (LSP) or namespace provider was improperly installed or the provider fails to operate correctly.WSAESOCKTNOSUPPORT:The specified socket type is not supported in this address family.WSAINVALIDPROVIDER:The service provider returned a version other than 2.2.WSAINVALIDPROCTABLE:The service provider returned an invalid or incomplete procedure table to the WSPStartup.線程安全是原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明2.9.3 accept(未完成)函數名稱accept頭文件#include <Winsock2.h>庫文件#pragma comment(lib, "Ws2_32.lib")函數功能函數主要功能說明。函數聲明類型 函數名 (類型 參數1,類型 參數2,……);函數參數參數1:[輸入|輸出|輸入&輸出],參數說明。參數2:[輸入|輸出|輸入&輸出],參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.9.4 connect(未完成)函數名稱connect頭文件#include <Winsock2.h>庫文件#pragma comment(lib, "Ws2_32.lib")函數功能函數主要功能說明。函數聲明類型 函數名 (類型 參數1,類型 參數2,……);函數參數參數1:[輸入|輸出|輸入&輸出],參數說明。參數2:[輸入|輸出|輸入&輸出],參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.9.5 recv(未完成)函數名稱recv頭文件#include <Winsock2.h>庫文件#pragma comment(lib, "Ws2_32.lib")函數功能接收套接字的遠端發送過來的數據。函數聲明int recv(SOCKET s,char * buf,int len,int flags);函數參數s,[輸入]:存放套接字句柄的值。buf,[輸出]:存放接收遠端發來的數據的內存指針。len,[輸出]:存放接收遠端發來的數據的內存長度,單位位元組。flags,[輸出]:存放其他功能標記的值,可以是(用"|"選零至多個):MSG_PEEK(0x0002):如果設置本標記,表示預讀接收到的數據。將遠端發來的數據複製到buf參數中,但不會將遠端發來的數據從接收緩存區中刪除。如果不設置本標記,表示取出接收到的數據。將遠端發來的數據複製到buf參數中,並從接收緩存區中刪除。MSG_OOB(0x0001):如果設置本標記,表示處理OOB帶外數據。如果不設置本標記,表示不處理OOB帶外數據。MSG_WAITALL(0x0008):如果設置本標記,表示本函數僅當以下事件發生時才返回:1) buf參數已經被完全填滿。2) 連接已經關閉。3) 接收數據的請求已經取消,或有錯誤發生。注意:如果操作系統不支持本標記、或套接字為非阻塞模式,則不能設置本標記,否則報WSAEOPNOTSUPP錯誤。Also, if MSG_WAITALL is specified along with MSG_OOB, MSG_PEEK, or MSG_PARTIAL, then this call will fail with WSAEOPNOTSUPP. This flag is not supported on datagram sockets or message-oriented sockets.如果不設置本標記,阻塞模式下,表示本函數一旦接收到了數據就返回,非阻塞模式下,有沒有接收到數據都返回。返回值0:失敗,原因為套接字已正常關閉。SOCKET_ERROR(-0x0001):失敗,調用WSAGetLastError()查看錯誤碼。其他:接收到的數據的長度。錯誤碼WSANOTINITIALISED(0x276D):應用程序沒有調用WSAStartup()函數,或者WSAStartup()函數失敗,因此必須在調用WSAStartup()函數成功後才能調用本函數。WSAENETDOWN:The network subsystem has failed.WSAEFAULT:The buf parameter is not completely contained in a valid part of the user address space.WSAENOTCONN:The socket is not connected.WSAEINTR:The (blocking) call was canceled through WSACancelBlockingCall.WSAEINPROGRESS:A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.WSAENETRESET:For a connection-oriented socket, this error indicates that the connection has been broken due to keep-alive activity that detected a failure while the operation was in progress. For a datagram socket, this error indicates that the time to live has expired.WSAENOTSOCK:The descriptor is not a socket.WSAEOPNOTSUPP(0x273D):參考的對象類型不支持嘗試的操作。MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, OOB data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only send operations.WSAESHUTDOWN:The socket has been shut down; it is not possible to receive on a socket after shutdown has been invoked with how set to SD_RECEIVE or SD_BOTH.WSAEWOULDBLOCK:The socket is marked as nonblocking and the receive operation would block.WSAEMSGSIZE:The message was too large to fit into the specified buffer and was truncated.WSAEINVAL:The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled or (for byte stream sockets only) len was zero or negative.WSAECONNABORTED:The virtual circuit was terminated due to a time-out or other failure. The application should close the socket as it is no longer usable.WSAETIMEDOUT:The connection has been dropped because of a network failure or because the peer system failed to respond.WSAECONNRESET:The virtual circuit was reset by the remote side executing a hard or abortive close. The application should close the socket as it is no longer usable. On a UDP-datagram socket, this error would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message.線程安全是原子操作是其他說明本函數工作原理:1、 如果是阻塞模式的TCP套接字:1) 如果接收緩存區中有數據,本函數就會將接收緩存區中數據一次性儘可能多的讀取出來,然後就返回成功。2) 如果接收緩存區中沒有數據,本函數就會一直等待到有數據,一次性儘可能多的讀取出來,然後就返回成功。3) 如果接收緩存區的長度為0,就將全部要發送的數據直接傳給操作系統,等待操作系統處理完,然後就返回成功。4) 發送緩存區的長度為0時,阻塞時間將明顯增長,比發送緩存區的長度為1時要長很多。這麼做可以提升發送數據的實時性,但會降低效率。2、 如果是非阻塞模式的TCP套接字:1) 如果發送緩存區能夠容納要發送的數據,本函數就會將要發送的數據一次性寫入到發送緩存區,然後就返回成功。2) 如果發送緩存區不夠容納要發送的數據,本函數就會先將一部分要發送的數據寫入到發送緩存區,然後等待操作系統將發送緩存區中的數據取走,再將剩餘的要發送的數據寫入到發送緩存區,以此類推,直到將全部要發送的數據寫入到發送緩存區,然後就返回成功。但是,如果本函數發現不能在很短的時間內將全部要發送的數據寫入到發送緩存區,就不會寫入任何數據,然後就返回失敗,並報WSAEWOULDBLOCK錯誤。3) 如果發送緩存區的長度為0,就將全部要發送的數據直接傳給操作系統,等待操作系統處理完,然後就返回成功。4) 發送緩存區的長度為0時,非阻塞模式的TCP套接字也將阻塞,不會報WSAEWOULDBLOCK錯誤。這麼做可以提升發送數據的實時性,但會降低效率。2.9.6 send(未完成)函數名稱send頭文件#include <Winsock2.h>庫文件#pragma comment(lib, "Ws2_32.lib")函數功能使用已連接的套接字發送數據給遠端。函數聲明int send (SOCKET s,const char * buf,int len,int flags);函數參數s,[輸入]:存放套接字句柄的值。buf,[輸入]:存放要發送的數據的內存指針。len,[輸入]:存放要發送的數據的內存長度,單位位元組。flags,[輸入]:存放發送數據時的標記,可以是(用"|"選零至多個):MSG_DONTROUTE:Specifies that the data should not be subject to routing. A Windows Sockets service provider can choose to ignore this flag.MSG_OOB:Sends OOB data (stream-style socket such as SOCK_STREAM only.返回值SOCKET_ERROR(-0x0001):失敗,調用WSAGetLastError()函數查看錯誤碼。其他:已成功發送的數據的長度,單位位元組,一般和len參數相同,也可能比len參數小。錯誤碼WSANOTINITIALISED(0x276D):應用程序沒有調用WSAStartup()函數,或者WSAStartup()函數失敗,因此必須在調用WSAStartup()函數成功後才能調用本函數。WSAENETDOWN(0x2742):套接字操作遇到了一個已死的網路。WSAEACCES(0x271D):以一種訪問許可權不允許的方式做了一個訪問套接字的嘗試。The requested address is a broadcast address, but the appropriate flag was not set. Call setsockopt with the SO_BROADCAST socket option to enable use of the broadcast address.WSAEINTR(0x2714):一個封鎖操作被對WSACancelBlockingCall()函數的調用中斷。A blocking Windows Sockets 1.1 call was canceled through WSACancelBlockingCall.WSAEINPROGRESS(0x2734):目前正在執行一個阻止性操作。A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.WSAEFAULT(0x271E):系統檢測到在一個調用中嘗試使用指針參數時的無效指針地址。The buf parameter is not completely contained in a valid part of the user address space.WSAENETRESET(0x2744):當該操作在進行中,由於保持活動的操作檢測到一個故障,該連接中斷。The connection has been broken due to the keep-alive activity detecting a failure while the operation was in progress.WSAENOBUFS(0x2747):由於系統緩衝區空間不足或隊列已滿,不能執行套接字上的操作。No buffer space is available.WSAENOTCONN(0x2749):由於套接字沒有連接並且(當使用一個 sendto 調用發送數據報套接字時)沒有提供地址,發送或接收數據的請求沒有被接受。The socket is not connected.WSAENOTSOCK(0x2736):在一個非套接字上嘗試了一個操作。The descriptor is not a socket.WSAEOPNOTSUPP(0x273D):參考的對象類型不支持嘗試的操作。MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, OOB data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only receive operations.WSAESHUTDOWN(0x274A):由於以前的關閉調用,套接字在那個方向已經關閉,發送或接收數據的請求沒有被接受。The socket has been shut down; it is not possible to send on a socket after shutdown has been invoked with how set to SD_SEND or SD_BOTH.WSAEWOULDBLOCK(0x2733):無法立即完成一個非阻止性套接字操作。The socket is marked as nonblocking and the requested operation would block.WSAEMSGSIZE(0x2738):一個在數據報套接字上發送的消息大於內部消息緩衝區或其他一些網路限制,或該用戶用於接收數據報的緩衝區比數據報小。The socket is message oriented, and the message is larger than the maximum supported by the underlying transport.WSAEHOSTUNREACH(0x2751):套接字操作嘗試一個無法連接的主機。The remote host cannot be reached from this host at this time.WSAEINVAL(0x2726):提供了一個無效的參數。The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled.WSAECONNABORTED(0x2745):你的主機中的軟體中止了一個已建立的連接。The virtual circuit was terminated due to a time-out or other failure. The application should close the socket as it is no longer usable.WSAECONNRESET(0x2746):遠程主機強迫關閉了一個現有的連接。The virtual circuit was reset by the remote side executing a hard or abortive close. For UDP sockets, the remote host was unable to deliver a previously sent UDP datagram and responded with a "Port Unreachable" ICMP packet. The application should close the socket as it is no longer usable.WSAETIMEDOUT(0x274C):由於連接方在一段時間後沒有正確答覆或連接的主機沒有反應,連接嘗試失敗。The connection has been dropped, because of a network failure or because the system on the other end went down without notice.線程安全是原子操作是其他說明本函數返回成功並不代表遠端已經接收到數據,如果想保證對方能收到,建議讓遠端收到後給回執。本函數工作原理:1、 如果是阻塞模式的TCP套接字:1) 如果發送緩存區能夠容納要發送的數據,本函數就會將要發送的數據一次性寫入到發送緩存區,然後就返回成功。2) 如果發送緩存區不夠容納要發送的數據,本函數就會先將一部分要發送的數據寫入到發送緩存區,然後等待操作系統將發送緩存區中的數據取走,再將剩餘的要發送的數據寫入到發送緩存區,以此類推,直到將全部要發送的數據寫入到發送緩存區,然後就返回成功。如果發送數據的超時時間已到,也會立即返回,返回值為已發送的數據長度。3) 如果發送緩存區的長度為0,就將全部要發送的數據直接傳給操作系統,等待操作系統處理完,然後就返回成功。如果發送數據的超時時間已到,也會立即返回,返回值為已發送的數據長度。4) 發送緩存區的長度為0時,阻塞時間將明顯增長,比發送緩存區的長度為1時要長很多。這麼做可以提升發送數據的實時性,但會降低效率。2、 如果是非阻塞模式的TCP套接字:1) 如果發送緩存區能夠容納要發送的數據,本函數就會將要發送的數據一次性寫入到發送緩存區,然後就返回成功。2) 如果發送緩存區不夠容納要發送的數據,本函數就會先將一部分要發送的數據寫入到發送緩存區,然後等待操作系統將發送緩存區中的數據取走,再將剩餘的要發送的數據寫入到發送緩存區,以此類推,直到將全部要發送的數據寫入到發送緩存區,然後就返回成功。但是,如果本函數發現不能在很短的時間內將全部要發送的數據寫入到發送緩存區,就不會寫入任何數據,然後就返回失敗,並報WSAEWOULDBLOCK錯誤。3) 如果發送緩存區的長度為0,就將全部要發送的數據直接傳給操作系統,等待操作系統處理完,然後就返回成功。4) 發送緩存區的長度為0時,非阻塞模式的TCP套接字也將阻塞,不會報WSAEWOULDBLOCK錯誤。這麼做可以提升發送數據的實時性,但會降低效率。2.9.7 getaddrinfo(未完成)函數名稱getaddrinfo頭文件#include <Ws2tcpip.h>#pragma comment(lib, "Ws2_32.lib")函數功能根據指定的主機名和服務名或埠號獲取多個地址信息。函數聲明INT getaddrinfo (PCSTR pNodeName,PCSTR pServiceName,const ADDRINFOA * pHints,PADDRINFOA * ppResult);函數參數參數1:[輸入|輸出|輸入&輸出],參數說明。參數2:[輸入|輸出|輸入&輸出],參數說明。……返回值0:成功。非0:Windows套接字錯誤碼,也可調用WSAGetLastError()查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………函數功能:函數聲明:int getaddrinfo (const char * node,const char * service,const struct addrinfo * hints,struct addrinfo ** res);函數參數:參數1:參數說明。參數2:參數說明。……返回值 :0:成功。EAI_ADDRFAMILY:The specified network host does not have any network addresses in the requested address family.EAI_AGAIN:The name server returned a temporary failure indication. Try again later.EAI_BADFLAGS:ai_flags contains invalid flags.EAI_FAIL:The name server returned a permanent failure indication.EAI_FAMILY:The requested address family is not supported at all.EAI_MEMORY:Out of memory.EAI_NODATA:The specified network host exists, but does not have any network addresses defined.EAI_NONAME:The node or service is not known; or both node and service are NULL; or AI_NUMERICSERV was specified in hints.ai_flags and service was not a numeric port-number string.EAI_SERVICE:The requested service is not available for the requested socket type. It may be available through another socket type.EAI_SOCKTYPE:The requested socket type is not supported at all.EAI_SYSTEM:Other system error, check errno for details.線程安全:是注意事項:…………2.9.8 getnameinfo(未完成)頭文件 :#include< sys/socket.h>#include< netdb.h>函數名稱:getnameinfo函數功能:函數主要功能說明。函數聲明:int getnameinfo (const struct sockaddr * sa,socklen_t salen,char *host,size_t hostlen,char *serv,size_t servlen,int flags);函數參數:返回值 :0:成功。EAI_AGAIN:The name could not be resolved at this time. Try again later.EAI_BADFLAGS:The flags argument has an invalid value.EAI_FAIL:A nonrecoverable error occurred.EAI_FAMILY:The address family was not recognized, or the address length was invalid for the specified family.EAI_MEMORY:Out of memory.EAI_NONAME:The name does not resolve for the supplied arguments. NI_NAMEREQD is set and the host"s name cannot be located, or neither hostname nor service name were requested.EAI_OVERFLOW:The buffer pointed to by host or serv was too small.EAI_SYSTEM:A system error occurred. The error code can be found in errno.線程安全:是注意事項:2.9.9 getifaddrs(未完成)頭文件 :#include< sys/types.h>#include< ifaddrs.h>函數名稱:getifaddrs函數功能:獲取網路設備的IP地址。函數聲明:int getifaddrs (struct ifaddrs ** ifap);函數參數:0:成功。-1:失敗,並設置errno錯誤碼變數。返回值 :返回值1:返回值說明。返回值2:返回值說明。……線程安全:是 或 否 或 未知注意事項:struct ifaddrs{struct ifaddrs * ifa_next; //指向鏈表的下一個成員char * ifa_name; //網路設備名字元串unsigned int ifa_flags; //Flags from SIOCGIFFLAGSstruct sockaddr * ifa_addr; //Address of interfacestruct sockaddr * ifa_netmask; //Netmask of interfaceunion{struct sockaddr * ifu_broadaddr; // Broadcast address of interfacestruct sockaddr * ifu_dstaddr; // Point-to-point destination address}ifa_ifu;#define ifa_broadaddr ifa_ifu.ifu_broadaddr#define ifa_dstaddr ifa_ifu.ifu_dstaddrvoid * ifa_data; // Address-specific data};ifa_next指向鏈表的下一個成員;ifa_name是介面名稱,以0結尾的字元串,比如eth0,lo;ifa_flags是介面的標識位(比如當IFF_BROADCAST或IFF_POINTOPOINT設置到此標識位時,影響聯合體變數ifu_broadaddr存儲廣播地址或ifu_dstaddr記錄點對點地址);ifa_netmask存儲該介面的子網掩碼;結構體變數存儲廣播地址或點對點地址(見括弧介紹ifa_flags);ifa_data存儲了該介面協議族的特殊信息,它通常是NULL(一般不關注他)。使用完後,必須使用freeifaddrs()函數釋放內存。2.9.10 select(未完成)函數名稱select頭文件#include <Winsock2.h>庫文件#pragma comment(lib, "Ws2_32.lib")函數功能阻塞檢查一個或多個套接字是否處於可讀狀態、可寫狀態、異常狀態。函數聲明int select (int nfds,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,const struct timeval * timeout);函數參數nfds,[輸入]:本參數無意義,只是為了兼容伯克利套接字。readfds,[輸入]:存放需要檢查是否處於可讀狀態的套接字集,如果為NULL,表示不檢查可讀狀態。可讀狀態分為:如果TCP服務端套接字處於監聽狀態,表示可以接受TCP連接請求,如果調用accept()函數會立即返回。表示套接字可以接收數據,包括帶外數據(如果打開SO_OOBINLINE選項),可以調用recv()、WSARecv()、WSARecvFrom()、recvfrom()函數接收到數據。表示已經連接的TCP套接字已經被關閉、重置、或終止,如果調用recv()、WSARecv()、WSARecvFrom()、recvfrom()函數會立即返回。writefds,[輸入]:存放需要檢查是否處於可寫狀態的套接字集,如果為NULL,表示不檢查可寫狀態。可寫狀態分為:如果套接字處於正在連接中(非阻塞套接字調用connect()函數後),表示連接成功,並可以調用send()、sendto()函數發送出數據。表示套接字可以發送數據,可以調用send()、sendto()函數發送出數據。exceptfds,[輸入]:存放需要檢查是否處於異常狀態的套接字集,如果為NULL,表示不檢查異常狀態。異常狀態分為:表示套接字可以接收帶外數據(如果關閉SO_OOBINLINE選項)。如果套接字處於正在連接中(非阻塞套接字調用connect()函數後),表示連接失敗。表示已經連接的TCP套接字已經被關閉、重置、或終止。timeout,[輸入]:存放阻塞檢查的超時時間。如果為0秒0毫秒,表示不阻塞立即完成。如果為NULL,表示不限制超時時間。返回值SOCKET_ERROR宏(-0x0001):失敗,並清空所有套接字集,調用WSAGetLastError()函數查看錯誤碼。0:成功,不清空任何套接字集,但在阻塞檢查的超時時間內沒有任何套接字處於需要檢查的狀態。大於0:成功,三個套接字集一共有多少個套接字處於需要檢查的狀態,並把每個套接字集中不處於需要檢查的狀態的套接字刪除掉,只保留處於需要檢查的狀態的套接字,調用FD_ISSET()宏函數判斷。錯誤碼WSANOTINITIALISED:必須在調用WSAStartup()函數成功後才能調用本函數。WSAEFAULT:The Windows Sockets implementation was unable to allocate needed resources for its internal operations, or the readfds, writefds, exceptfds, or timeval parameters are not part of the user address space.WSAENETDOWN:The network subsystem has failed.WSAEINVAL:The time-out value is not valid, or all three descriptor parameters were null.WSAEINTR:A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.WSAEINPROGRESS:A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.WSAENOTSOCK:One of the descriptor sets contains an entry that is not a socket.線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明套接字集使用方法:FD_SETSIZE宏:定義一個套接字集結構體變數最多容納多少個套接字,默認為64,如果需要修改本宏,應在定義套接字集結構體變數前修改。fd_set stFdset;:定義套接字集結構體變數。FD_ZERO (fd_set * fdset) 宏函數:清空fdset套接字集內的所有套接字。FD_SET (int fd, fd_set * fdset) 宏函數:向fdset套接字集內添加一個fd套接字。FD_CLR (int fd, fd_set * fdset) 宏函數:從fdset套接字集內刪除一個fd套接字。FD_ISSET (int fd, fd_set * fdset) 宏函數:判斷fdset套接字集內是否存在fd套接字,返回值為非0表示存在,為0表示不存在。2.9.11 getsockopt(未完成)函數名稱getsockopt頭文件#include <Winsock2.h>庫文件#pragma comment(lib, "Ws2_32.lib")函數功能獲取指定的套接字選項的值。函數聲明int getsockopt(SOCKET s,int level,int optname,char FAR * optval,int FAR * optlen);函數參數s,[輸入]:存放套接字句柄。level,[輸入]:存放套接字選項的等級。optname,[輸入]:存放套接字選項的名稱。optval,[輸出]:存放獲取到的套接字選項的值的變數的內存指針。optlen,[輸入&輸出]:輸入時,存放獲取到的套接字選項的值的變數的內存長度的變數的內存指針。輸出時,存放實際獲取到的套接字選項的值的變數的內存長度。返回值0:成功。SOCKET_ERROR:失敗,調用WSAGetLastError()函數查看錯誤碼。錯誤碼WSANOTINITIALISED:應用程序沒有調用WSAStartup()函數,或者WSAStartup()函數失敗,因此必須在調用WSAStartup()函數成功後才能調用本函數。WSAENETDOWN:Note The network subsystem has failed.WSAEFAULT:One of the optval or the optlen parameters is not a valid part of the user address space, or the optlen parameter is too small.WSAEINPROGRESS:A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.WSAEINVAL:套接字選項的等級是未知的或無效的。WSAENOPROTOOPT:在指定的套接字選項在套接字選項的等級中是未知的或不支持的。WSAENOTSOCK:指定的不是一個套接字句柄。線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.9.12 WSAGetLastError(未完成)函數名稱WSAGetLastError頭文件#include <Winsock2.h>庫文件#pragma comment(lib, "Ws2_32.lib")函數功能獲取當前線程最近一次Winsock套接字操作的錯誤碼。函數聲明int WSAGetLastError(void);函數參數無返回值當前線程最近一次Winsock套接字操作的錯誤碼。錯誤碼無線程安全是原子操作是其他說明2.9.13 WSASetLastError(未完成)函數名稱WSASetLastError頭文件#include <Winsock2.h>庫文件#pragma comment(lib, "Ws2_32.lib")函數功能設置當前線程最近一次Winsock套接字操作的錯誤碼。函數聲明int WSASetLastError(int iError);函數參數iError,[輸入]:存放Winsock套接字操作的錯誤碼。返回值無錯誤碼WSANOTINITIALISED:應用程序沒有調用WSAStartup()函數,或者WSAStartup()函數失敗,因此必須在調用WSAStartup()函數成功後才能調用本函數。線程安全是原子操作是其他說明通過本函數設置後,後續的Winsock套接字操作可能會再次修改錯誤碼。2.10 軟硬體設備2.10.1 通用2.10.1.1 DeviceIoControl(未完成)函數名稱DeviceIoControl頭文件#include <Windows.h>函數功能直接發送控制代碼到指定的設備,讓該設備來執行相應的操作。函數聲明BOOL DeviceIoControl (HANDLE hDevice,DWORD dwIoControlCode,LPVOID lpInBuffer,DWORD nInBufferSize,LPVOID lpOutBuffer,DWORD nOutBufferSize,LPDWORD lpBytesReturned,LPOVERLAPPED lpOverlapped);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.10.1.2 NtQuerySystemInformation(未完成)函數名稱NtQuerySystemInformation頭文件#include <Winternl.h>#include <Ntstatus.h>庫文件#pragma comment(lib, "Ntdll.lib")函數功能函數主要功能說明。函數聲明NTSTATUS NtQuerySystemInformation (SYSTEM_INFORMATION_CLASS SystemInformationClass,PVOID SystemInformation,ULONG SystemInformationLength,PULONG ReturnLength);函數參數SystemInformationClass,[輸入]:存放要獲取什麼類型的系統信息的標記,可以為(選一至一個):SystemBasicInformation枚舉(0):Returns the number of processors in the system in a SYSTEM_BASIC_INFORMATION structure. Use the GetSystemInfo function instead.SystemPerformanceInformation枚舉(2):Returns an opaque SYSTEM_PERFORMANCE_INFORMATION structure that can be used to generate an unpredictable seed for a random number generator. Use the CryptGenRandom function instead.SystemTimeOfDayInformation枚舉(3):Returns an opaque SYSTEM_TIMEOFDAY_INFORMATION structure that can be used to generate an unpredictable seed for a random number generator. Use the CryptGenRandom function instead.SystemProcessInformation枚舉(5):獲取所有進程的進程信息,並存放到SYSTEM_PROCESS_INFORMATION結構體數組中,用結構體的NextEntryOffset成員變數遍曆數組。進程信息包括進程使用的處理數、峰值頁面文件的使用量以及進程已分配的內存頁的數量等。SystemProcessorPerformanceInformation枚舉(8):獲取每個CPU處理器核心的的當前累計的空閑時間、內核時間、用戶時間,並存放到SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION結構體數組中。用本函數ReturnLength參數返回的長度除以單個SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION結構體的長度,就是SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION結構體數組的元素個數,也就是CPU核心總數。SystemInterruptInformation枚舉(23):Returns an opaque SYSTEM_INTERRUPT_INFORMATION structure that can be used to generate an unpredictable seed for a random number generator. Use the CryptGenRandom function instead.SystemExceptionInformation枚舉(33):Returns an opaque SYSTEM_EXCEPTION_INFORMATION structure that can be used to generate an unpredictable seed for a random number generator. Use the CryptGenRandom function instead.SystemRegistryQuotaInformation枚舉(37):Returns a SYSTEM_REGISTRY_QUOTA_INFORMATION structure.SystemLookasideInformation枚舉(45):Returns an opaque SYSTEM_LOOKASIDE_INFORMATION structure that can be used to generate an unpredictable seed for a random number generator. Use the CryptGenRandom function instead.SystemQueryPerformanceCounterInformation枚舉(134):Returns a SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION structure that can be used to determine whether the system requires a kernel transition to retrieve the high-resolution performance counter information through a QueryPerformanceCounter function call.SystemInformation,[輸入&輸出]:參數說明。SystemInformationLength,[輸入]:存放指定的信息結構體的內存長度,單位位元組。ReturnLength,[輸出]:存放寫入了多少位元組的數據到指定的信息結構體。如果指定的信息結構體的長度不夠放下實際的數據,則不會寫入任何數據到指定的信息結構體,但本參數還是會返回需要寫入多少位元組的數據。返回值大於等於0:成功,返回值就是成功碼。小於0:失敗,返回值就是錯誤碼。錯誤碼STATUS_SUCCESS宏(0x0):成功。STATUS_INFO_LENGTH_MISMATCH宏(0xC0000004):指定的信息結構體的長度不夠放下實際的數據。……線程安全是原子操作是其他說明2.10.2 CPU處理器系統在使用CPU處理器時,分為幾個模式使用,當沒有任何進程要使用時,系統就讓CPU處理器執行空閑線程,此時CPU處理器就處於空閑狀態,當有進程在用戶模式下執行時,CPU處理器就處於用戶狀態下,當有進程在內核模式下運行時,CPU處理器就處於內核狀態下。空閑狀態、用戶狀態、內核狀態所佔用的時間,就叫空閑時間、用戶時間、內核時間。2.10.2.1 GetSystemTimes(未完成)函數名稱GetSystemTimes頭文件#include <Windows.h>函數功能獲取CPU處理器的當前累計的空閑時間、內核時間、用戶時間。函數聲明BOOL GetSystemTimes (LPFILETIME lpIdleTime,LPFILETIME lpKernelTime,LPFILETIME lpUserTime);函數參數lpIdleTime,[輸出]:存放當前累計的空閑時間。lpKernelTime,[輸出]:存放當前累計的空閑時間與內核時間之和。lpUserTime,[輸出]:存放當前累計的用戶時間。返回值非0:成功。0:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明本函數獲取到的時間都是FILETIME結構體,如果需要浮點型的數值,需要進行轉換。如果要計算CPU處理器的使用率,就是100 - 空閑時間 / (用戶時間 + 空閑時間 + 內核時間) * 100.0。2.10.3 MEM內存2.10.3.1 內存概念2.10.3.1.1 進程的內存圖一對於系統中的每一個進程而言,都有 4GB 的 "內存空間"。也就是每個進程都認為自己有 4GB 的內存可以使用。系統將每個進程的 4GB 地址空間,從邏輯上劃分為兩大部分:1) 藍色的用戶空間,此空間是被用戶程序所使用的。比如我在代碼中寫「分配100MB內存」,其實佔用的就是這一部分。2) 紅色的內核空間,此空間是被用作操作系統執行必要的線程切換以及從用戶態函數進入內核態執行功能所保留的內存地址. 應用程序無法操作此區域。2.10.3.1.2 Intel x86 體系內存管理Intel 規定, 一個在計算機內部, 可以使用 "分頁機制" 對硬體內存進行 "虛擬化". 其核心技術如下圖:圖二首先, 在程序中的一個地址 0x1234, 5678 被計算機的頁部件(硬體)經過 1,2,3 步, 從線性地址(程序中的地址) 轉變為真正機器上的物理地址(即實際內存的硬體地址). 每個線性地址都被分成 "頁目錄索引(PDE, 10-bit)", "頁表索引(PTE, 10-bit)", "頁內偏移(offset, 12-bit)" 三部分.1) 在頁目錄中根據 PDE 找到頁表的位置, 即通過 0x48 找到 0xa000, 0000.2) 根據頁表中的 PTE 找到頁地址, 即通過 0x345 找到 0x4000, 0000.3) 根據偏移, 在頁中找到我們要的具體地址, 即已知頁位於 0x4000, 0000, 我們需要存取其 0x678 偏移處的數據, 則我們所需要操作的真是物理地址就是 0x4000, 0678.2.10.3.1.3 基於 x86 的 Windows 內存管理圖 3首先澄清兩個概念:1.一個進程中的內存有三種分類,空閑, 保留, 提交. 具體的含義可以在圖 3中找到說明. 這三種類型的內存在某一時刻可能位於內存中, 也可能位於交換文件中.2.工作集定義:The working set of a process is the set of pages in the virtual address space of the process thatare currently resident in physical memory. 即: 實際在物理內存中的大小.結合實際系統, 以我家安裝的win8.1 為例, 打開任務管理器, 可見如下:圖 4工作集(內存): 可以這麼理解, 此值就是該進程所佔用的總物理內存. 但是這個值是由兩部分組成, 即"專用工作集"+"共享工作集".內存(專用工作集): 這對於一個進程是最重要的, 它代表了一個進程獨佔用了多少內存.內存(共享工作集): 這是該進程和別的進程共享的內存量. 通常, 這是載入一個 dll 所佔用的內存.提交大小: 屬於 Committed 那一類. 但是不一定在物理內存中, 有些可能位於交換文件中. 如果有一個程序, 原本占 500MB 內存, 但是絕大多數內存都不使用, 則可以通過 `EmptyWorkingSet` 向操作系統發送請求, 將此進程的不常用的內容從物理內存中換出到換頁文件中保存, 如下圖:圖 52.10.3.1.4 寫在最後0. 工作集, 即在物理內存中的數據的集合.1. 工作集 = 專用 + 共享2. 將所有的 "工作集" 相加後的值會大於任務管理器中內存佔用的百分比, 因為百分比對共享內存進行排重了.3. "提交大小" 和 "工作集" 是兩個層面的概念, 大部分活躍進程的 "工作集" 會大於 "提交大小", 而大部分非活躍的進程 "工作集" 會小於 "提交大小", 但是兩者沒有絕對關係.4. 虛擬內存: 就是換頁文件.2.10.3.2 GlobalMemoryStatus(未完成)函數名稱GlobalMemoryStatus頭文件#include <Windows.h>函數功能獲取系統當前物理內存和虛擬內存的相關信息。函數聲明void GlobalMemoryStatus (LPMEMORYSTATUS lpBuffer);函數參數lpBuffer,[輸出]:存放物理內存和虛擬內存的相關信息的結構體的內存指針。返回值無錯誤碼無線程安全是原子操作是其他說明本函數只能獲取內存大小不超過4GB的相關信息,如果要獲取內存大小超過4GB的相關信息,可以調用GlobalMemoryStatusEx()函數。2.10.4 網路介面和網路適配器GetIfEntry() 獲取本機一個指定網路介面或網路設備的索引序號的信息。類型為PPP協議的寬頻連接的網路適配器,在沒有連接時,操作狀態為已禁用。2.10.4.1 GetIfTAble(未完成)函數名稱GetIfTAble頭文件#include <Iphlpapi.h>#pragma comment(lib, "Iphlpapi.lib")函數功能獲取本機所有網路介面和網路適配器的狀態信息。函數聲明DWORD GetIfTable (PMIB_IFTABLE pIfTable,PULONG pdwSize,BOOL bOrder);函數參數pIfTable,[輸出]:存放MIB_IFTABLE結構體數組的內存指針。本參數用於存放本機所有網路介面和網路適配器的狀態信息,本參數應該是先由程序調用malloc()等函數分配的內存。pdwSize,[輸入&輸出]:輸入時,存放pIfTable參數指定的MIB_IFTABLE結構體數組的內存長度的變數的內存指針,單位位元組。輸出時,存放輸出了多少長度的數據到pIfTable參數指定的MIB_IFTABLE結構體數組裡,如果MIB_IFTABLE結構體數組的內存長度不夠,則不會輸出任何數據到MIB_IFTABLE結構體數組裡,但本參數任然會在輸出時存放MIB_IFTABLE結構體數組的內存最小長度。bOrder,[輸入]:存放是否需要根據網路設備的索引序號將MIB_IFTABLE結構體數組裡的狀態信息排序。非0表示排序,0表示不排序。返回值ERROR_SUCCESS宏(0):成功。ERROR_INSUFFICIENT_BUFFER宏(122):失敗,MIB_IFTABLE結構體的內存長度不夠,查看pdwSize參數獲取最小長度。ERROR_INVALID_PARAMETER宏(87):失敗,錯誤的參數,pdwSize參數為NULL,或本函數的調用進程無法讀寫pIfTable參數或pdwSize參數指定的內存。ERROR_NOT_SUPPORTED宏(50):失敗,操作系統不受支持。錯誤碼無線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明本函數一般需要調用兩次,第一次pIfTable參數填NULL,pdwSize參數填的存放內存長度的變數為0。然後本函數返回後,再根據pdwSize參數存放的內存最小長度分配pIfTable參數指定的內存,最後再調用本函數就能成功。也有可能第二次調用的時候情況發生了變化,導致分配的內存長度還是不夠,就需要不停的重新分配內存,直到本函數調用成功為止。如果是其他錯誤,則應該報錯跳出循環。2.10.4.2 GetAdaptersInfo(未完成)函數名稱GetAdaptersInfo頭文件#include <Iphlpapi.h>#pragma comment(lib, "Iphlpapi.lib")函數功能獲取本機所有網路適配器的配置信息。只獲取已啟用的網路適配器,不獲取已禁用的網路適配器。不獲取網路介面、迴環網路適配器。函數聲明DWORD GetAdaptersInfo (PIP_ADAPTER_INFO pIfTable,PULONG dwOutBufLen);函數參數pIfTable,[輸出]:存放IP_ADAPTER_INFO結構體鏈表的內存指針。本參數用於存放本機所有網路適配器的配置信息,本參數應該是先由程序調用malloc()等函數分配的內存。dwOutBufLen,[輸入&輸出]:輸入時,存放pIfTable參數指定的IP_ADAPTER_INFO結構體鏈表的內存長度的變數的內存指針,單位位元組。輸出時,存放輸出了多少長度的數據到pIfTable參數指定的IP_ADAPTER_INFO結構體鏈表裡,如果IP_ADAPTER_INFO結構體鏈表的內存長度不夠,則不會輸出任何數據到IP_ADAPTER_INFO結構體鏈表裡,但本參數任然會在輸出時存放IP_ADAPTER_INFO結構體鏈表的內存最小長度。返回值ERROR_SUCCESS宏(0):成功。ERROR_BUFFER_OVERFLOW宏(111):失敗,MIB_IFTABLE結構體的內存長度不夠,查看dwOutBufLen參數獲取最小長度。ERROR_INVALID_DATA宏(13):失敗,本函數獲取到的網路適配器信息是無效的。ERROR_INVALID_PARAMETER宏(87):失敗,錯誤的參數,dwOutBufLen參數為NULL,或本函數的調用進程無法讀寫pIfTable參數或dwOutBufLen參數指向的內存。ERROR_NO_DATA宏(232):失敗,本機沒有任何已啟用的網路適配器。ERROR_NOT_SUPPORTED宏(50):失敗,操作系統不受支持。其他:通過調用FormatMessage()函數查看錯誤提示信息。錯誤碼見返回值線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明本函數一般需要調用兩次,第一次pIfTable參數填NULL,pdwSize參數填的存放內存長度的變數為0。然後本函數返回後,再根據pdwSize參數存放的內存最小長度分配pIfTable參數指定的內存,最後再調用本函數就能成功。也有可能第二次調用的時候情況發生了變化,導致分配的內存長度還是不夠,就需要不停的重新分配內存,直到本函數調用成功為止。如果是其他錯誤,則應該報錯跳出循環。2.10.4.3 GetInterfaceInfo(未完成)函數名稱GetInterfaceInfo頭文件#include <Iphlpapi.h>#pragma comment(lib, "Iphlpapi.lib")函數功能獲取本機所有啟用了IPv4協議的物理和虛擬的網路適配器的名稱和索引序號,不獲取任何其他信息。只獲取已啟用的網路適配器,不獲取已禁用的網路適配器。不獲取迴環網路適配器。只獲取安裝並啟用了IPv4協議的網路適配器,不獲取安裝了但未啟用IPv4協議的網路適配器。函數聲明DWORD GetInterfaceInfo (PIP_INTERFACE_INFO pIfTable,PULONG dwOutBufLen);函數參數pIfTable,[輸入]:存放IP_INTERFACE_INFO動態結構體的內存指針。本參數用於存放本機所有啟用了IPv4協議的物理和虛擬的網路適配器的名稱和索引序號,本參數應該是先由程序調用malloc()等函數分配的內存。dwOutBufLen,[輸入&輸出]:輸入時,存放pIfTable參數指定的IP_INTERFACE_INFO動態結構體的內存長度的變數的內存指針,單位位元組。輸出時,存放輸出了多少長度的數據到pIfTable參數指定的IP_INTERFACE_INFO動態結構體里,如果IP_INTERFACE_INFO動態結構體的內存長度不夠,則不會輸出任何數據到IP_INTERFACE_INFO動態結構體里,但本參數任然會在輸出時存放IP_INTERFACE_INFO動態結構體的內存最小長度。返回值ERROR_SUCCESS宏(0):成功。ERROR_INSUFFICIENT_BUFFER宏(122):失敗,IP_INTERFACE_INFO結構體的內存長度不夠,查看dwOutBufLen參數獲取最小長度。ERROR_INVALID_PARAMETER宏(87):失敗,錯誤的參數,dwOutBufLen參數為NULL,或本函數的調用進程無法讀寫pIfTable參數或dwOutBufLen參數指定的內存。ERROR_NO_DATA宏(232):失敗,本機沒有任何已啟用的網路適配器。ERROR_NOT_SUPPORTED宏(50):失敗,操作系統不受支持。其他:通過調用FormatMessage()函數查看錯誤提示信息。錯誤碼見返回值線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明本函數一般需要調用兩次,第一次pIfTable參數填NULL,pdwSize參數填的存放內存長度的變數為0。然後本函數返回後,再根據pdwSize參數存放的內存最小長度分配pIfTable參數指定的內存,最後再調用本函數就能成功。也有可能第二次調用的時候情況發生了變化,導致分配的內存長度還是不夠,就需要不停的重新分配內存,直到本函數調用成功為止。如果是其他錯誤,則應該報錯跳出循環。2.10.5 性能計數器Performance Counters性能計數器可以統計硬體設備的各項性能指標。在Windows 2000及以上系統中,可以在「控制面板-〉管理-〉性能」中看到該程序,在繪圖界面上點擊滑鼠右擊,選擇「添加計數器」就有可能看到所有可統計的項目。性能計數器可以實時統計硬體設備的各項性能指標,常常在論壇里看到一些新朋友問如何自己實現任務管理器,及如何實時獲得每個進程的CPU使用率,內存使用...等等,那麼使用系統性能計數器應該是最佳選擇。MSDN:http://msdn.microsoft.com/en-us/library/windows/desktop/aa373078(v=vs.85).aspx使用性能計數器的基本步驟:1.創建計數器PdhOpenQuery()。3.把感興趣的計數器添加進來PdhAddCounter()。4.收集數據PdhCollectQueryData()。5.得到計數器的數值PdhGetFormattedCounterValue()。6.關閉計數器PdhCloseQuery()。CPU性能計數器:Processor(_Total)\% Processor TimeProcessor(_Total)\% User TimeProcessor(_Total)\% Privileged TimeProcessor(_Total)Interrupts/secProcessor(_Total)\% DPC TimeProcessor(_Total)\% Interrupt TimeProcessor(_Total)DPCs Queued/secProcessor(_Total)DPC RateProcessor(_Total)\% Idle Time內存性能計數器:MemoryPage Faults/secMemoryAvailable BytesMemoryPages/secMemoryPages Input/secMemoryPage Reads/secMemoryPages Output/secMemoryPage Writes/secMemoryCache BytesMemorySystem Code Total BytesMemoryAvailable MBytes網路性能計數器:Network Interface(Realtek RTL8139 Family PCI Fast Ethernet NIC)Bytes Received/secNetwork Interface(Realtek RTL8139 Family PCI Fast Ethernet NIC)Bytes Sent/secNetwork Interface(Realtek RTL8139 Family PCI Fast Ethernet NIC)Bytes Total/sec邏輯分區性能計數器:LogicalDisk(_Total)Disk Reads/sec 分區每秒讀取次數LogicalDisk(_Total)Disk Read Bytes/sec 分區每秒讀取位元組數LogicalDisk(_Total)Disk Writes/sec 分區每秒寫入次數LogicalDisk(_Total)Disk Write Bytes/sec 分區每秒寫入位元組數物理硬碟性能計數器:PhysicalDisk(_Total)\% Disk Time 硬碟使用率PhysicalDisk(_Total)Disk Reads/sec 硬碟每秒讀取次數PhysicalDisk(_Total)Disk Read Bytes/sec 硬碟每秒讀取位元組數PhysicalDisk(_Total)Disk Writes/sec 硬碟每秒寫入次數PhysicalDisk(_Total)Disk Write Bytes/sec 硬碟每秒寫入位元組數2.10.5.1 PdhOpenQuery(未完成)函數名稱PdhOpenQuery頭文件#include <Pdh.h>#pragma comment(lib, "Pdh.lib")函數功能創建一個性能計數器的查詢句柄,查詢句柄用於統一管理各項性能指標的數值。函數聲明PDH_STATUS PdhOpenQuery (LPCTSTR szDataSource,DWORD_PTR dwUserData,PDH_HQUERY * phQuery);函數參數szDataSource,[輸入]:存放性能計數器的日誌文件路徑,該日誌里存放著各項性能指標的數值。如果為NULL,表示直接從實時數據源獲取各項性能指標的數值。dwUserData,[輸入]:User-defined value to associate with this query. To retrieve the user data later, call PdhGetCounterInfo and access the dwQueryUserData member of PDH_COUNTER_INFO.可以為NULL。phQuery,[輸出]:存放性能計數器的查詢句柄,後續用於管理各項性能指標的數值。返回值ERROR_SUCCESS宏:成功。其他:失敗,返回值就是錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.10.5.2 PdhAddCounter(未完成)函數名稱PdhAddCounter頭文件#include <Pdh.h>#pragma comment(lib, "Pdh.lib")函數功能創建一個計數器,並添加到查詢句柄。計數器用於表示要查詢哪項性能指標,添加到查詢句柄後,由查詢句柄統一收集該查詢句柄下的所有計數器的數值。函數聲明PDH_STATUS PdhAddCounter (PDH_HQUERY hQuery,LPCTSTR szFullCounterPath,DWORD_PTR dwUserData,PDH_HCOUNTER * phCounter);函數參數hQuery,[輸入]:存放查詢句柄的值。szFullCounterPath,[輸入]:存放計數器路徑字元串的內存指針。格式:"\ComputerPerfObject(ParentInstance/ObjectInstance#InstanceIndex)Counter"。dwUserData,[輸入]:User-defined value. This value becomes part of the counter information. To retrieve this value later, call the PdhGetCounterInfo function and access the dwUserData member of the PDH_COUNTER_INFO structure.可以為NULL。phCounter,[輸出]:存放計數器句柄的內存指針。返回值ERROR_SUCCESS宏:成功。其他:失敗,返回值就是錯誤碼。錯誤碼PDH_CSTATUS_BAD_COUNTERNAME宏:計數器路徑字元串無法解析或解釋.PDH_CSTATUS_NO_COUNTER宏:在指定的計算機或性能計數器的日誌文件里,未被找到指定的計數器。PDH_CSTATUS_NO_COUNTERNAME宏:計數器路徑字元串是空的。PDH_CSTATUS_NO_MACHINE宏:The path did not contain a computer name, and the function was unable to retrieve the local computer name.PDH_CSTATUS_NO_OBJECT:Unable to find the specified object on the computer or in the log file.PDH_FUNCTION_NOT_FOUND:Unable to determine the calculation function to use for this counter.PDH_INVALID_ARGUMENT宏:一個或多個參數是無效的。PDH_INVALID_HANDLE宏:查詢句柄是無效的。PDH_MEMORY_ALLOCATION_FAILURE宏:無法分配足夠的內存來完成本函數的操作。線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明同一個查詢句柄可以添加多個計數器。2.10.5.3 PdhRemoveCounter(未完成)函數名稱PdhRemoveCounter頭文件#include <Pdh.h>#pragma comment(lib, "Pdh.lib")函數功能從查詢句柄里移除一個計數器,並關閉該計數器。移除後該計數器句柄會變成無效句柄,且不能再被使用。函數聲明PDH_STATUS PdhRemoveCounter (PDH_HCOUNTER hCounter);函數參數hCounter,[輸入]:存放計數器句柄的值。返回值ERROR_SUCCESS宏:成功。其他:失敗,返回值就是錯誤碼。錯誤碼PDH_INVALID_HANDLE宏:計數器句柄是無效的。線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.10.5.4 PdhCollectQueryData(未完成)函數名稱PdhCollectQueryData頭文件#include <Pdh.h>#pragma comment(lib, "Pdh.lib")函數功能收集一個查詢句柄里所有計數器的數值。收集完後,需要調用PdhGetFormattedCounterValue()函數來獲取指定計數器的數值。函數聲明PDH_STATUS PdhCollectQueryData (PDH_HQUERY hQuery);函數參數hQuery,[輸入]:存放查詢句柄的值。返回值ERROR_SUCCESS宏:成功。其他:失敗,返回值就是錯誤碼。錯誤碼PDH_INVALID_HANDLE宏:無效的查詢句柄。PDH_NO_DATA宏:查詢句柄沒有添加任何計數器,或者沒有收集到任何計數器的數值,可能因為許可權不足。線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明有些計數器的數值是對比上一次的數值統計出來的,這類計數器只收集一次數值是無效的,需要再次調用本函數才能收集到有效的數值,因為這類計數器是統計一段時間內的性能指標變化,每一次收集到的計數器的數值都是對比上一次收集的數值統計出來的,例如每秒的CPU使用率,那麼第一次調用本函數後,需要等待一秒,然後再次調用本函數,才能收集到這一秒的CPU使用率。2.10.5.5 PdhGetFormattedCounterValue(未完成)函數名稱PdhGetFormattedCounterValue頭文件#include <Pdh.h>#pragma comment(lib, "Pdh.lib")函數功能從一個已經收集過數值的計數器里獲取數值。函數聲明PDH_STATUS PdhGetFormattedCounterValue (PDH_HCOUNTER hCounter,DWORD dwFormat,LPDWORD lpdwType,PPDH_FMT_COUNTERVALUE pValue);函數參數hCounter,[輸入]:存放計數器句柄的值。dwFormat,[輸入]:存放獲取計數器的數值的格式標記,可以為(選一至一個):PDH_FMT_DOUBLE:以DOUBLE雙精度型獲取計數器的數值。PDH_FMT_LARGE:以LONGLONG型獲取計數器的數值。PDH_FMT_LONG:以LONG型獲取計數器的數值。還可以為(用"|"選零至多個):PDH_FMT_NOSCALE:不使用計數器的默認縮放因子。PDH_FMT_NOCAP100:如果設置本標記,則計數器的百分比數值的上限可以大於100,例如:多個處理器的使用率。如果不設置本標記,則計數器的百分比數值的上限為100。PDH_FMT_1000:如果設置本標記,則計數器的數值乘以1000。如果不設置本標記,則計數器的數值不會乘以1000。lpdwType,[輸出]:Receives the counter type. For a list of counter types, see the Counter Types section of the OnlineWindows Server 2003 Deployment Kit.可以為NULL。pValue,[輸出]:存放用於存放計數器數值的計數器數值結構體的內存指針。返回值ERROR_SUCCESS宏:成功。其他:失敗,返回值就是錯誤碼。錯誤碼PDH_INVALID_ARGUMENT宏:有一個參數是無效的,或格式不正確。PDH_INVALID_DATA宏:計數器句柄里沒有收集到有效數值,或一個成功的狀態碼。PDH_INVALID_HANDLE宏:計數器句柄是無效的。線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.10.5.6 PdhCloseQuery(未完成)函數名稱PdhCloseQuery頭文件#include <Pdh.h>#pragma comment(lib, "Pdh.lib")函數功能關閉性能計數器的查詢句柄。函數聲明PDH_STATUS PdhCloseQuery (PDH_HQUERY hQuery);函數參數hQuery,[輸入]:存放查詢句柄的值。返回值ERROR_SUCCESS宏:成功。其他:失敗,返回值就是錯誤碼。錯誤碼PDH_INVALID_HANDLE宏:查詢句柄是無效的。線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.11 多進程一個可執行程序被執行前,操作系統會先為該可執行程序分配相關資源以供執行(如:CPU、內存、套接字等),這一系列的資源組合起來稱為進程,也可以稱為是一個可執行程序的實例、實體。一個進程只能對應一個可執行程序。一個進程剛開始執行時,只有一條執行流程,這個流程稱為主線程。如果一個進程需要多條執行流程,就可以在主線程里創建多個子線程。大多數處理器至少支持兩種執行模式:內核模式、用戶模式。內核模式下,可以執行很多和系統硬體相關的操作。用戶模式下,則不能直接操作硬體。當線程在執行操作系統相關的函數時,線程就處於內核模式,當線程在執行非操作系統相關的函數時,線程就處於用戶模式。這樣可以保護操作系統的內核不會被任何線程破壞。每一個進程都有一個全操作系統唯一的句柄和標識。2.11.1 進程操作2.11.1.1 CreateProcess(未完成)函數名稱CreateProcess頭文件#include <Windows.h>函數功能創建一個新進程。函數聲明BOOL CreateProcess (LPCSTR lpApplicationName,LPSTR lpCommandLine,LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTES lpThreadAttributes,BOOL bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCSTR lpCurrentDirectory,LPSTARTUPINFOA lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation);函數參數lpApplicationName,[輸入] :存放可執行文件路徑字元串的內存指針。路徑可以為相對或絕對路徑,不支持通配符,文件後綴名不能省略, 路徑後面不能加命令行參數,加了也自動忽略,命令行參數必須通過lpCommandLine參數傳遞。如果本參數為相對路徑,不會自動搜索任何其他目錄,例如Windows系統目錄,Path環境變數目錄等。如果本參數為NULL,則lpCommandLine參數最前面必須包含可執行文件路徑,並由空格符與後面的字元分開。如果要執行BAT批處理文件,此參數必須為"cmd.exe",且lpCommandLine參數必須為"/C BAT批處理文件路徑"。如果要執行16位可執行文件,此參數必須為NULL,且在lpCommandLine參數里包含可執行文件路徑及參數。lpCommandLine,[輸入]:存放執行可執行文件時傳遞的命令行參數字元串的內存指針,包括" "結束符最大長度為32768位元組。如果lpApplicationName參數為NULL,此參數的可執行文件路徑字元串部分的長度不能超過MAX_PATH宏。如果不需要傳遞命令行參數,此參數的參數字元串部分就為NULL。如果本參數不為NULL,則此參數不能為常量,因為Unicode版的CreateProcess()函數內部會更改參數字元串的內容,但在CreateProcess()函數返回之前,它會將該字元串恢復原樣,ANSI版的不受此限制。lpProcessAttributes,[輸入]:存放進程屬性結構體的內存指針,一般為NULL。lpThreadAttributes,[輸入]:存放線程屬性結構體的內存指針,一般為NULL。bInheritHandles:,[輸入]:指示新進程是否從調用進程處繼承了句柄。如果本參數為非0,表示調用進程中的每一個可繼承的打開句柄都將被子進程繼承,被繼承的句柄與原進程擁有完全相同的值和訪問許可權。如果本參數為0,表示不繼承。dwCreationFlags,[輸入]:存放創建進程時使用的標記。可以為(用"|"選零至多個):CREATE_DEFAULT_ERROR_MODE:新的進程不繼承調用進程的錯誤模式。CreateProcess函數賦予新進程當前的默認錯誤模式作為替代。應用程序可以調用SetErrorMode函數設置當前的默認錯誤模式。這個標誌對於那些運行在沒有硬體錯誤環境下的多線程外殼程序是十分有用的。對於CreateProcess函數,默認的行為是為新進程繼承調用者的錯誤模式。設置這個標誌以改變默認的處理方式。CREATE_NEW_CONSOLE:如果設置此標記,則新進程將使用一個新控制台,而不是繼承調用進程的控制台。如果不設置此標記,則這個新進程將與調用進程使用同一個控制台。如果新進程不是控制台程序,則此標記無意義。此標誌不能與DETACHED_PROCESS標記同時設置。CREATE_NEW_PROCESS_GROUP:新進程將是一個進程樹的根進程。進程樹中的全部進程都是根進程的子進程。新進程樹的用戶標識符與這個進程的標識符是相同的,由lpProcessInformation參數返回。進程樹經常使用GenerateConsoleCtrlEvent函數允許發送CTRL+C或CTRL+BREAK信號到一組控制台進程。CREATE_SEPARATE_WOW_VDM:如果設置此標記,新進程將會在一個私有的虛擬DOS機(VDM)中運行。另外,默認情況下所有的16位Windows應用程序都會在同一個共享的VDM中以線程的方式運行。單獨運行一個16位程序的優點是一個應用程序的崩潰只會結束這一個VDM的運行;其他那些在不同VDM中運行的程序會繼續正常的運行。同樣的,在不同VDM中運行的16位Windows應用程序擁有不同的輸入隊列,這意味著如果一個程序暫時失去響應,在獨立的VDM中的應用程序能夠繼續獲得輸入。CREATE_SHARED_WOW_VDM:如果WIN.INI中的Windows段的DefaultSeparateVDM選項被設置為真,這個標識使得CreateProcess函數越過這個選項並在共享的虛擬DOS機中運行新進程。CREATE_SUSPENDED:新進程的主線程會以暫停的狀態被創建,直到調用ResumeThread()函數被調用時才運行。CREATE_UNICODE_ENVIRONMENT:如果設置此標記,由lpEnvironment參數指定的環境變數內存塊使用Unicode字符集。如果不設置此標記,由lpEnvironment參數指定的環境變數內存塊使用ANSI字符集。DEBUG_PROCESS:如果設置此標記,調用進程將被當做一個調試程序,並且新進程會被當做被調試的進程。系統把被調試程序發生的所有調試事件通知給調試器,且只有本函數調用進程可以調用WaitForDebugEvent()函數。DEBUG_ONLY_THIS_PROCESS:如果此標誌沒有被設置且調用進程正在被調試,新進程將成為調試調用進程的調試器的另一個調試對象。如果調用進程沒有被調試,有關調試的行為就不會產生。DETACHED_PROCESS:對於控制台進程,新進程沒有訪問父進程式控制制台的許可權。新進程可以通過AllocConsole函數自己創建一個新的控制台。如果新進程不是控制台程序,則此標記無意義。此標記不能與CREATE_NEW_CONSOLE標誌同時設置。CREATE_NO_WINDOW:如果設置此標記,則新進程不顯示控制台窗口。如果不設置此標記,則新進程會顯示控制台窗口。如果新進程不是控制台程序,則此標記無意義。以下是進程優先順序標記,可以為(選零至一個):HIGH_PRIORITY_CLASS:指示這個進程將執行時間臨界的任務,所以它必須被立即運行以保證正確。這個優先順序的程序優先於正常優先順序或空閑優先順序的程序。一個例子是Windows任務列表,為了保證當用戶調用時可以立刻響應,放棄了對系統負荷的考慮。確保在使用高優先順序時應該足夠謹慎,因為一個高優先順序的CPU關聯應用程序可以佔用幾乎全部的CPU可用時間。IDLE_PRIORITY_CLASS:指示這個進程的線程只有在系統空閑時才會運行並且可以被任何高優先順序的任務打斷。例如屏幕保護程序。空閑優先順序會被子進程繼承。NORMAL_PRIORITY_CLASS:指示這個進程沒有特殊的任務調度要求。REALTIME_PRIORITY_CLASS:指示這個進程擁有可用的最高優先順序。一個擁有實時優先順序的進程的線程可以打斷所有其他進程線程的執行,包括正在執行重要任務的系統進程。例如,一個執行時間稍長一點的實時進程可能導致磁碟緩存不足或滑鼠反映遲鈍。lpEnvironment,[輸入]:存放新進程的環境變數內存塊的內存指針,如果為NULL,表示繼承本函數調用進程的環境變數。環境變數內存塊的格式為"name1=value1 name2=value2 name3=value3 ……"。lpCurrentDirectory,[輸入]:存放新進程的當前活動目錄字元串的內存指針,可以為UNC格式。如果為NULL,表示和調用進程使用一樣的當前活動目錄。lpStartupInfo,[輸入]:存放一個用於決定新進程的主窗體如何顯示的STARTUPINFO結構體的內存指針,不能為NULL。lpProcessInformation,[輸出]:存放一個用來接收新進程的識別信息的PROCESS_INFORMATION結構體的內存指針,不能為NULL。詳見返回值非0:成功。0:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明調用完本函數後,新進程需要先初始化完畢後才能開始運行,本函數是啟動新進程成功後就立即返回成功,不會等待新進程初始化完畢後才返回,未初始化完畢的新進程的進程和線程的句柄和標識是無效的,如果要操作新進程,必須等待初始化完畢後才能操作,否則會報ERROR_INVALID_THREAD_ID錯誤的線程標識等錯誤。如果新進程是窗口程序,可以通過調用WaitForInputIdle()函數等待新進程初始化完畢。如果新進程是控制台程序或沒有線程消息隊列,可以考慮通過不停的調用PostThreadMessage()函數,直到成功為止,因為對未初始化完畢的線程寄送消息是會報ERROR_INVALID_THREAD_ID錯誤的,當初始化完畢後,寄送消息就會成功。2.12 多線程每一個線程都有一個全操作系統唯一的句柄和標識。2.12.1 線程操作2.12.1.1 CreateThread(未完成)函數名稱CreateThread頭文件#include <Windows.h>函數功能為本進程創建一個新的線程,並返回線程的句柄。函數聲明HANDLE CreateThread (LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId);函數參數lpThreadAttributes,[輸入]:指向一個 SECURITY_ATTRIBUTES 結構的指針,該結構決定了線程的安全屬性,一般置為 NULL。dwStackSize,[輸入]:指定了線程的堆棧長度,一般都設置為0。lpStartAddress,[輸入]:表示新線程開始執行的主函數指針。線程主函數的聲明必須是DWORD WINAPI ThreadFunc (LPVOID lpThreadParameter),ThreadFunc是線程主函數名(名稱可以修改),lpThreadParameter為參數名(名稱可以修改),線程主函數只能有一個參數。lpParameter,[輸入]:指定傳給線程主函數的參數,不傳就為NULL。dwCreationFlags,[輸入]:線程創建後是否立即執行線程主函數。如果本參數為0,表示立即執行。如果本參數為CREATE_SUSPENDED宏,則線程創建後,掛起狀態,並不馬上執行,以後可以調用ResumeThread()函數喚醒線程。lpThreadId,[輸出]:存放新線程ID的變數的內存指針,不需要就為NULL。返回值非NULL:新線程的句柄。NULL:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明…………2.12.1.2 SuspendThreadDWORD SuspendThread(HANDLE hThread);該函數用於掛起指定的線程,如果函數執行成功,則線程的執行被終止。2.12.1.3 ResumeThreadDWORD ResumeThread(HANDLE hThread);該函數用於結束線程的掛起狀態,執行線程。 也就是恢復指定的線程2.12.1.4 ExitThreadVOID ExitThread(DWORD dwExitCode);該函數用於線程終結自身的執行,主要在線程的執行函數中被調用。其中參數dwExitCode用來設置線程的退出碼。2.12.1.5 TerminateThreadBOOL TerminateThread(HANDLE hThread,DWORD dwExitCode);一般情況下,線程運行結束之後,線程函數正常返回,但是應用程序可以調用TerminateThread強行終止某一線程的執行。各參數含義如下:hThread:將被終結的線程的句柄;dwExitCode:用於指定線程的退出碼。使用TerminateThread()終止某個線程的執行是不安全的,可能會引起系統不穩定;雖然該函數立即終止線程的執行,但並不釋放線程所佔用的資源。因此,一般不建議使用該函數。2.12.1.6 GetExitCodeThread(未完成)函數名稱GetExitCodeThread頭文件#include <Windows.h>函數功能判斷指定的線程是否終止運行,如果已經終止,就獲取該線程的退出代碼。函數聲明BOOL GetExitCodeThread(HANDLE hThread,LPDWORD lpExitCode);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.12.1.7 GetCurrentThreadIdGetCurrentThreadId()獲取當前線程ID。2.12.2 臨界區在用戶模式工作,適用於保護線程間共享資源,一個線程可以多次Lock不會出錯。不支持在多進程之間工作。#include <Windows.h>CRITICAL_SECTION Section;InitializeCriticalSection(&Section);//初始化臨界區線程中使用EnterCriticalSection(&Section);//進入臨界區{}LeaveCriticalSection(&Section);//退出臨界區2.12.3 互斥鎖在內核模式工作,除了支持臨界區的功能,還可以為互斥量命名,以便在多進程中工作。互斥量比臨界區耗資源。1、#include <Windows.h>HANDLE hMutex;hMutex = CreateMutex(NULL , false, "mutex");線程函數使用:WaitForSingleObject(hMutex,INFINITE);{}ReleaseMutex(hMutex);2、CMutex Section;線程函數中使用CsingleLock singlelock;singlelock(&Section);singlelock.lock();singlelock.Unlock();2.12.4 事件事件對象就像一個開關:它只有兩種狀態---開和關。當一個事件處於」開」狀態,我們稱其為」有信號」否則稱為」無信號」。可以在一個線程的執行函數中創建一個事件對象,然後觀察它的狀態,如果是」無信號」就讓該線程睡眠,這樣該線程佔用的CPU時間就比較少。產生事件對象的函數如下:HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, // SDBOOL bManualReset, // reset typeBOOL bInitialState, // initial stateLPCTSTR lpName // object name);該函數創建一個Event同步對象,如果CreateEvent調用成功的話,會返回新生成的對象的句柄,否則返回NULL。參數說明:lpEventAttributes 一般為NULLbManualReset 創建的Event是自動複位還是人工複位.如果true,人工複位, 一旦該Event被設置為有信號,則它一直會等到ResetEvent()API被調用時才會恢復 為無信號. 如果為false,Event被設置為有信號,則當有一個wait到它的Thread時, 該Event就會自動複位,變成無信號. 如果想 在每次調用WaitForSingleObject 後讓WINDOWS為您自動地把事件地狀態恢復為」無信號」狀態,必須把該參數設為FALSE,否則,您必須每次調用ResetEvent函數來清除事件 的信號。bInitialState 初始狀態,true,有信號,false無信號lpName 事件對象的名稱。您在OpenEvent函數中可能使用。注釋:一個Event被創建以後,可以用OpenEvent()API來獲得它的Handle,用CloseHandle()來關閉它,用SetEvent()或PulseEvent()來設置它使其有信號,用ResetEvent()來使其無信號,用WaitForSingleObject()或WaitForMultipleObjects()來等待其變為有信號。PulseEvent()是一個比較有意思的使用方法,正如這個API的名字,它使一個Event 對象的狀態發生一次脈衝變化,從無信號變成有信號再變成無信號,而整個操作是原子的。對自動複位的Event對象,它僅釋放第一個等到該事件的thread(如果有),而對於人工複位的Event對象,它釋放所有等待的thread。這裡有兩個API函數用來修改事件對象的信號狀態:SetEvent和ResetEvent。前者把事件對象設為」有信號」狀態,而後者正好相反。在事件對象生成後,必須調用WaitForSingleObject來讓線程進入等待狀態,該函數的語法如下:WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)hHandle-->指向同步對象的指針。事件對象其實是同步對象的一種。dwMilliseconds--> 等待同步對象變成」有信號」前等待的時間,以毫秒計。當等待的時間超過該值後無信號同步對象仍處於」無信號」狀態,線程不再等待, WaitForSingleObject函數會返回。如果想要線程一直等待,請把該參數設為INFINITE(該值等於0xffffffff)。2.13 服務2.13.1 OpenSCManager(未完成)函數名稱OpenSCManager頭文件#include <Winsvc.h>庫文件#pragma comment(lib, "Advapi32.lib")函數功能打開服務控制管理資料庫,並返回服務控制管理資料庫句柄。函數聲明SC_HANDLE WINAPI OpenSCManager (LPCTSTR lpMachineName,LPCTSTR lpDatabaseName,DWORD dwDesiredAccess);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.13.2 CloseServiceHandle(未完成)函數名稱CloseServiceHandle頭文件#include <Winsvc.h>庫文件#pragma comment(lib, "Advapi32.lib")函數功能關閉服務控制管理資料庫句柄。函數聲明類型 函數名 (類型 參數1,類型 參數2,……);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.13.3 CreateService(未完成)函數名稱CreateService頭文件#include <Winsvc.h>庫文件#pragma comment(lib, "Advapi32.lib")函數功能創建一個服務對象,並將其添加到指定的服務控制管理器資料庫。函數聲明SC_HANDLE WINAPI CreateService (SC_HANDLE hSCManager,LPCTSTR lpServiceName,LPCTSTR lpDisplayName,DWORD dwDesiredAccess,DWORD dwServiceType,DWORD dwStartType,DWORD dwErrorControl,LPCTSTR lpBinaryPathName,LPCTSTR lpLoadOrderGroup,LPDWORD lpdwTagId,LPCTSTR lpDependencies,LPCTSTR lpServiceStartName,LPCTSTR lpPassword);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.13.4 QueryServiceStatus(未完成)函數名稱QueryServiceStatus頭文件#include <Winsvc.h>庫文件#pragma comment(lib, "Advapi32.lib")函數功能函數主要功能說明。函數聲明類型 函數名 (類型 參數1,類型 參數2,……);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.13.5 ControlService(未完成)函數名稱ControlService頭文件#include <Winsvc.h>庫文件#pragma comment(lib, "Advapi32.lib")函數功能函數主要功能說明。函數聲明類型 函數名 (類型 參數1,類型 參數2,……);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.14 可視化窗口每個窗口都有一個三維坐標,X軸表示窗口在屏幕的橫坐標位置,最左邊為0,依次向右每一個像素遞增一,Y軸表示窗口在屏幕的縱坐標位置,最上邊為0,依次向下每一個像素遞增一,Z軸表示窗口擋在其他窗口的前面還是躲在後面,從遠往近看,Z軸坐標越大的就會擋在其他的控制項或窗口的前面。控制項MFC類描述動畫CAnimateCtrl顯示連續的AVI視頻剪輯按鈕CButton用來產生某種行為的按鈕,以及複選框、單選鈕和組框組合框CComboBox編輯框和列表框的組合編輯框CEdit用於鍵入文本標題頭CHeaderCtrl位於某一行文本之上的按鈕,可用來控制顯示文件的寬度熱鍵CHotKeyCtrl用於通過按下某一組合鍵來很快的執行某些常用的操作圖象列表CImageList一系列圖象(典型情況下是一系列圖標或點陣圖)的集合。圖象列表本身不是一種控制項,它常常是和其它控制項一起工作,為其它控制項提供所用的圖象列表列表CListCtrl顯示文本及其圖標列表的窗口列表框CListBox包括一系列字元串的列表進度CProgressCtrl用於在一較長操作中提示用戶所完成的進度多格式文本編輯CRichEditCtrl提供可設置字元和段落格式的文本編輯的窗口滾動條CScrollBar為對話框提供控制項形式的滾動條滑塊CSliderCtrl包括一個有可選標記的滑塊的窗口旋轉按鈕CSpinButtonCtrl提供一對可用於增減某個值的箭頭靜態文本CStatic常用於為其它控制項提供標籤狀態條CStatusBarCtrl用於顯示狀態信息的窗口,同MFC類CStatusBar類似選項卡CTabCtrl在選項卡對話框或屬性頁中提供具有類似筆記本中使用的分隔標籤的外觀的選項卡工具條CToolBarCtrl具有一系列命令生成按鈕的窗口,同MFC類CToolBar類似工具提示CToolTipCtrl一個小的彈出式窗口,用於提供對工具條按鈕或其它控制項功能的簡單描述樹CTreeCtrl用於顯示一系列的項的繼承結構2.14.1 窗口位置、窗口大小2.14.1.1 GetWindowRect(未完成)函數名稱GetWindowRect頭文件#include <Windows.h>函數功能獲取指定的窗口的左邊、頂邊、右邊、底邊在屏幕上的位置。函數聲明BOOL GetWindowRect (HWND hWnd,LPRECT lpRect);函數參數hWnd,[輸入]:存放要獲取哪個窗口句柄的位置,不能為NULL。lpRect,[輸出]:存放位置結構體的內存指針,用於存放指定的窗口在屏幕上的位置。返回值非0:成功0:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.14.1.2 SetWindowPos(未完成)函數名稱SetWindowPos頭文件#include <Windows.h>函數功能改變一個窗口的Z軸順序、位置、尺寸、樣式。函數聲明BOOL SetWindowPos (HWND hWnd,HWND hWndInsertAfter,int X,int Y,int cx,int cy,UINT uFlags);函數參數hWnd,[輸入]:存放要改變的窗口的句柄。hWndInsertAfter,[輸入]:存放要將hWnd參數指定的窗口定位在哪些窗口句柄的前面。如果不想定位窗口,就在uFlags參數中設置SWP_NOZORDER標記,則本參數將被忽略,否則本參數不能為NULL。此參數也可以為(選一至一個):HWND_BOTTOM(1):如果hWnd參數指定的窗口是當前激活窗口,將此窗口定位在Z軸順序的底部,也就是所有窗口的後面,且如果此窗口是置頂窗口,就變成非置頂窗口。如果hWnd參數指定的窗口不是當前激活窗口,則不做任何定位,無論此窗口是置頂窗口,還是非置頂窗口。HWND_NOTOPMOST(-2):如果hWnd參數指定的窗口是置頂窗口,且是當前激活窗口,就變成非置頂窗口,並定位在所有非置頂窗口的前面,及在所有置頂窗口的後面。如果hWnd參數指定的窗口已經是一個非置頂窗口,或不是當前激活窗口,則不做任何定位。HWND_TOP(0):如果hWnd參數指定的窗口是非置頂窗口,且是當前激活窗口,將窗口定位在所有非置頂窗口的前面,及在所有置頂窗口的後面。如果hWnd參數指定的窗口已經是一個置頂窗口,或不是當前激活窗口,則不做任何定位。HWND_TOPMOST(-1):將hWnd參數指定的窗口定位在所有非置頂窗口和置頂窗口的前面,並將窗口變成置頂窗口,無論此窗口是不是當前激活窗口。如果hWnd參數指定的窗口在置頂後,又有其他窗口被置頂,則此窗口將被定位在其他置頂窗口的後面。如果要一直保持某個窗口的置頂位置,需要每隔一段時間就設置一次置頂,才能保證不被其他窗口蓋住。X,[輸入]:存放將hWnd參數指定的窗口的左邊移動到屏幕的哪個像素。如果不想移動窗口,就在uFlags參數中設置SWP_NOMOVE標記,則本參數將被忽略。Y,[輸入]:存放將hWnd參數指定的窗口的頂邊移動到屏幕的哪個像素。如果不想移動窗口,就在uFlags參數中設置SWP_NOMOVE標記,則本參數將被忽略。cx,[輸入]:存放將hWnd參數指定的窗口的左邊至右邊的長度改為多少個像素。如果不想修改窗口尺寸,就在uFlags參數中設置SWP_NOSIZE標記,則本參數將被忽略。注意:本參數是邊框長度,不是像素位置。cy,[輸入]:存放將hWnd參數指定的窗口的頂邊至低邊的長度改為多少個像素。如果不想修改窗口尺寸,就在uFlags參數中設置SWP_NOSIZE標記,則本參數將被忽略。注意:本參數是邊框長度,不是像素位置。uFlags,[輸入]:存放操作窗口的位置和大小的標記,可以為(用"|"選零至多個):SWP_DRAWFRAME:Draws a frame (defined when the window was created) around the window.SWP_FRAMECHANGED:Sends a WM_NCCALCSIZE message to the window, even if the window"s size is not being changed. If this flag is not specified, WM_NCCALCSIZE is sent only when the window"s size is being changed.SWP_HIDEWINDOW:Hides the window.SWP_SHOWWINDOW:Displays the window.SWP_NOACTIVATE:Does not activate the window. If this flag is not set, the window is activated and moved to the top of either the topmost or the non-topmost group (depending on the setting of the pWndInsertAfter parameter).SWP_NOCOPYBITS:Discards the entire contents of the client area. If this flag is not specified, the valid contents of the client area are saved and copied back into the client area after the window is sized or repositioned.SWP_NOOWNERZORDER:Does not change the owner window"s position in the Z-order.SWP_NOREDRAW:Does not redraw changes. If this flag is set, no repainting of any kind occurs. This applies to the client area, the nonclient area (including the title and scroll bars), and any part of the parent window uncovered as a result of the moved window. When this flag is set, the application must explicitly invalidate or redraw any parts of the window and parent window that must be redrawn.SWP_NOREPOSITION:Same as SWP_NOOWNERZORDER.SWP_NOSENDCHANGING:Prevents the window from receiving the WM_WINDOWPOSCHANGING message.SWP_NOMOVE:如果設置本標記,表示不改變窗口的左邊、頂邊的位置,並忽略X參數、Y參數。如果不設置本標記,表示需要改變窗口的左邊、頂邊的位置,並使X參數、Y參數有效。SWP_NOSIZE:如果設置本標記,表示不改變窗口的左右、上下的大小,並忽略cx參數、cy參數。如果不設置本標記,表示需要改變窗口的左右、上下的大小,並使cx參數、cy參數有效。SWP_NOZORDER:如果設置本標記,表示不改變窗口的Z軸順序,並忽略hWndInsertAfter參數。如果不設置本標記,表示需要改變窗口的Z軸順序,並使hWndInsertAfter參數有效。返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.14.2 MessageBox(未完成)函數名稱MessageBox頭文件#include <Windows.h>函數功能顯示一個消息對話框,其中包含一組按鈕、一個系統圖標和一句消息,如狀態或錯誤的消息。消息對話框中返回一個整數值,該值指示用戶單擊了哪個按鈕。函數聲明int MessageBox (HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);函數參數hWnd,[輸入]:存放消息對話框的父窗口。如果為NULL,表示消息框框沒有父窗口。lpText,[輸入]:存放消息對話框的消息字元串。lpCaption,[輸入]:存放消息對話框的標題字元串。如果為NULL,默認就是「錯誤」。uType,[輸入]:存放出現在消息對話框的行為標記,用"|"選按鈕、圖標、窗體和其他標記。按鈕,默認為MB_OK標記,可以是(選零至一個):MB_OK:只有「確定」按鈕。MB_YESNO:有「是」和「否」按鈕。MB_ABORTRETRYIGNORE:有「放棄」,「重試」和「忽略」按鈕。MB_YESNOCANCEL:有「是」,「否」和「取消」按鈕。MB_RETRYCANCEL:有「重試」和「取消」按鈕。MB_OKCANCEL:有「確定」和「取消」按鈕。MB_CANCELTRYCONTINUE:有「取消」,「重試」和「繼續」按鈕。默認按鈕,默認為MB_DEFBUTTON1標記,可以是(選零至一個):MB_DEFBUTTON1:第一個按鈕是默認按鈕。MB_DEFBUTTON2:第二個按鈕是默認按鈕。MB_DEFBUTTON3:第三個按鈕是默認按鈕。MB_DEFBUTTON4:第四個按鈕是默認按鈕。圖標,默認沒有圖標,可以是(選零至一個):MB_ICONEXCLAMATION:驚嘆號警告圖標,黃色三角形中間一個感嘆號。MB_ICONWARNING:同MB_ICONEXCLAMATION標記。MB_ICONINFORMATION:提示信息圖標,圓圈中小寫字母i組成的圖標。MB_ICONASTERISK:同MB_ICONINFORMATION標記。MB_ICONQUESTION:問題標記圖標。MB_ICONSTOP:錯誤停止圖標。MB_ICONERROR:同MB_ICONSTOP標記。MB_ICONHAND:同MB_ICONSTOP標記。窗體,默認為MB_APPLMODAL標記,可以是(選零至一個):MB_APPLMODAL:消息對話框顯示在父窗口之上,用戶必須單擊消息對話框的按鈕後才能使用父窗口,不影響其他窗口使用。MB_SYSTEMMODAL:消息對話框顯示在系統所有窗口之上,用戶必須單擊消息對話框的按鈕後才能使用父窗口,不影響其他窗口使用。MB_TASKMODAL:消息對話框顯示在本進程所有窗口之上,用戶必須單擊消息對話框的按鈕後才能使用本進程其他窗口,不影響其他進程窗口使用。其他,可以是(選零至多個):MB_DEFAULT_DESKTOP_ONLY:接收輸入的當前桌面一定是一個預設桌面。否則,函數調用失敗。預設桌面是一個在用戶已經紀錄且以後應用程序在此上面運行的桌面。MB_HELP:把一個幫助按鈕增加到消息對話框。用戶單擊幫助按鈕或按F1鍵後產生一個WM_HELPINFO消息。MB_RIGHT:如果設置此標記,消息對話框的消息字元串向右對齊。如果不設置此標記,消息對話框的消息字元串向左對齊。MB_RTLREADING:用在Hebrew和Arabic系統中從右到左的順序顯示消息和大寫文本。MB_SETFOREGROUND:消息對話框設置為活動窗口,本函數會在內部調用SetForegroundWindow()函數。MB_TOPMOSI:消息對話框用WS_EX_TOPMOST窗口類型來創建,也就是顯示在系統所有窗口之上。MB_SERVICE_NOTIFICATION:MB_SERVICE_NOTIFICATION_NT3X:返回值0:失敗,調用GetlastError()函數查看錯誤碼。IDABORT宏:用戶單擊了「放棄」按鈕。IDCANCEL宏:用戶單擊了「取消」按鈕。IDCONTINUE宏:用戶單擊了「繼續」按鈕。IDIGNORE宏:用戶單擊了「忽略」按鈕。IDNO宏:用戶單擊了「否」按鈕。IDOK宏:用戶單擊了「是」按鈕。IDRETRY宏:用戶單擊了「重試」按鈕。IDYES宏:用戶單擊了「確定」按鈕。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明2.14.3 FindWindow(未完成)函數名稱FindWindow頭文件#include <xxx.h>#include <xxx.h>庫文件#pragma comment(lib, "xxx.lib")函數功能函數主要功能說明。函數聲明類型 函數名 (類型 參數1,類型 參數2,……);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.14.4 樣式2.14.4.1 ModifyStyle(未完成)函數名稱ModifyStyle頭文件#include <Windows.h>函數功能根據指定的窗口句柄,動態添加並刪除該窗口的普通樣式,並立即生效。函數聲明BOOL ModifyStyle (HWND hWnd,DWORD dwRemove,DWORD dwAdd,UINT nFlags);函數參數hWnd,[輸入]:存放要修改樣式的窗口的句柄的值,該窗口必須已經創建。dwRemove,[輸入]:存放要刪除的普通樣式的值,一般為該窗口的樣式宏。如果不需要刪除,本參數填0。例如:列表控制項的大圖標視圖樣式的宏定義為LVS_ICON。dwAdd,[輸入]:存放要添加的普通樣式的值,一般為該窗口的樣式宏。如果不需要添加,本參數填0。例如:列表控制項的大圖標視圖樣式的宏定義為LVS_ICON。nFlags,[輸入]:存放需要調用SetWindowPos()函數修改的樣式,不需要就填0,本參數可以為(用"|"選零至多個):SWP_NOSIZE:保持當前大小。SWP_NOMOVE:保持當前位置。SWP_NOZORDER:保持當前的Z次序。SWP_NOACTIVATE:不激活該窗口。返回值非0:成功。0:失敗。錯誤碼無線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明有些窗口的普通樣式是衝突的,需要同時刪除舊樣式,並添加新樣式,否則會導致失敗。有些窗口的普通樣式是不可以動態添加或刪除的,否則會導致失敗。本函數只能修改普通樣式,不能修改擴展樣式,修改擴展樣式需調用ModifyStyleEx()函數。2.14.5 CDC圖形設備環境類CDC類是在顯示數據,或者使用圖形,或者使用文本中必不可少的。Windows使用與設備無關的圖形設備環境(DC:Device Context)進行顯示。MFC基礎類庫定義了圖形設備環境類----CDC類。2.14.5.1 CDC::GetTextExtent(未完成)函數名稱GetTextExtent頭文件#include <Windows.h>函數功能根據本類對象設置的字體,計算一個字元串顯示在窗口上的像素尺寸。函數聲明CSize GetTextExtent (const CString & str);CSize GetTextExtent (LPCTSTR lpszString,int nCount);函數參數str,[輸入]:存放要計算像素尺寸的字元串的CString字元串類對象。lpszString,[輸入]:存放要計算像素尺寸的字元串的內存指針。nCount,[輸入]:存放要計算像素尺寸的字元串的內存長度的值。返回值字元串的上下和左右的像素尺寸錯誤碼無線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明設置本類對象的字體可以調用CDC::SelectObject()函數。2.14.6 CFont字體類CFont類封裝了一個Windows圖形設備介面(GDI)字體,並為操作字體提供了成員函數。Windows提供了多種與設備無關的不同尺寸的字體。有效地使用這些Windows字體,不用在編程時下很大功夫,就可以明顯地增強各種應用程序的功能。字體是Windows GDI必要的組成部分,這意味字體的使用與其他GDI對象一樣。它們可以縮放和剪切,可以像選取畫筆或者畫刷一樣選取設備環境。所有關於撤消選中和刪除的GDI規則都適用於字體。2.14.6.1 CFont::CreatePointFont(未完成)函數名稱CreatePointFont頭文件#include <Windows.h>函數功能修改本字體類對象的字體。函數聲明BOOL CreatePointFont (int nPointSize,LPCTSTR lpszFaceName,CDC* pDC);函數參數nPointSize,[輸入]:存放新字體的大小的值,該值要在實際大小上再乘以10,例如字體大小為11,則本參數就填110。lpszFaceName,[輸入]:存放字體名稱字元串的內存指針,例如字體為宋體,則本參數就填"宋體"。pDC,[輸入]:Pointer to the CDC object to be used to convert the height in nPointSize to logical units. If NULL, a screen device context is used for the conversion.返回值非0:成功。0:失敗。錯誤碼無線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明如果本類對象的字體不再使用了,應該調用DeleteObject()函數釋放本類對象的字體資源,在本類對象被釋放時,會自動釋放字體資源。2.14.7 CWnd窗口基類CWnd類是MFC窗口類的基類,提供了微軟基礎類庫中所有窗口類的基本功能。2.14.7.1 CWnd::SetFont函數名稱SetFont頭文件#include <Windows.h>函數功能設置本窗口類對象的字體。函數聲明void SetFont (CFont * pFont,BOOL bRedraw);函數參數pFont,[輸入]:存放字體類對象的內存指針。創建字體類對象可以參考CFont::CreatePointFont()函數。bRedraw,[輸入]:存放是否要在設置完字體後立即重繪窗口,非0表示需要立即重繪,0表示不需要立即重繪。返回值無錯誤碼無線程安全是原子操作是其他說明本函數實際上是對本窗口類對象發送WM_SETFONT消息,如果本窗口類對象沒有處理該消息,則本函數無效。2.14.8 CListCtrl列表控制項類列表控制項分為四種視圖:圖標視圖、小圖標視圖、列表視圖、報表視圖。圖標視圖: ,小圖標視圖:列表視圖: ,報表視圖:列表控制項中每一行為一個項目,每一個項目都有一至多個欄位,每個欄位都有圖標和標籤。圖標視圖、小圖標視圖、列表視圖直接可以插入項目,但是只能顯示每個項目的第一個欄位的圖標和標籤,即使插入了其他的欄位也不能顯示。報表視圖必須先插入欄位頭,然後才能插入項目,要不然插入的項目不會顯示。報表視圖中可以同時顯示每個項目的每個欄位的圖標和標籤。項目索引號是每個項目的唯一標識,用於操作項目時起定位作用,項目索引號始終是連續的,且第一個項目的索引號始終為0,第二個項目的索引號始終為1,以此類推。欄位索引號是某一項目的每個欄位的唯一標識,用於操作項目的欄位時起定位作用,欄位索引號始終是連續的,且每個項目的第一個欄位的索引號始終為0,每個項目的第二個欄位的索引號始終為1,以此類推。2.14.8.1 CListCtrl::InsertItem(未完成)函數名稱InsertItem頭文件#include <afxcmn.h>庫文件無函數功能向列表控制項中插入一個新項目。函數聲明int InsertItem (const LVITEM * pItem);int InsertItem (int nItem,LPCTSTR lpszItem);int InsertItem (int nItem,LPCTSTR lpszItem,int nImage);int InsertItem (UINT nMask,int nItem,LPCTSTR lpszItem,UINT nState,UINT nStateMask,int nImage,LPARAM lParam);函數參數pItem,[輸入]:存放LVITEM結構體的內存指針,新項目的各種參數都在該結構體中。nItem,[輸入]:存放新項目的索引號,本參數只能大於等於0。lpszItem,[輸入]:存放新項目的主項目的標籤字元串的內存指針。如果本參數為LPSTR_TEXTCALLBACK宏,表示項目的標籤為虛擬標籤,詳情請參考LVITEM結構體的pszText成員變數。nImage,[輸入]:Index of the item"s image, or I_IMAGECALLBACK if the item is a callback item. For information on callback items, see CListCtrl::GetCallbackMask.nMask,[輸入]:存放本函數有哪些參數有效的標記,可以為(用"|"選零至多個):nState,[輸入]:參數說明。nStateMask,[輸入]:參數說明。lParam,[輸入]:參數說明。返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明如果新項目的索引號在列表控制項中已經存在,則該索引號的項目及以後的項目全部加一,新項目插入到該索引號對應位置。如果新項目的索引號在列表控制項中不存在,則新項目就插入到列表控制項的最後一行,並把新項目的索引號修改為插入前最後一個項目的索引號加一,如果列表控制項中沒有任何項目,則新項目就在第一行,且索引號為0。2.14.8.2 CListCtrl::DeleteItem(未完成)函數名稱DeleteItem頭文件#include <afxcmn.h>庫文件無函數功能刪除列表控制項中某個項目。函數聲明類型 函數名 (類型 參數1,類型 參數2,……);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.14.8.3 CListCtrl::DeleteAllItems(未完成)函數名稱DeleteAllItems頭文件#include <afxcmn.h>庫文件無函數功能刪除列表控制項中所有的項目。函數聲明類型 函數名 (類型 參數1,類型 參數2,……);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.14.8.4 CListCtrl::InsertColumn(未完成)函數名稱InsertColumn頭文件#include <afxcmn.h>庫文件無函數功能向列表控制項中插入一個新欄位頭。函數聲明int InsertColumn (int nCol,const LVCOLUMN * pColumn);int InsertColumn (int nCol,LPCTSTR lpszColumnHeading,int nFormat = LVCFMT_LEFT,int nWidth = -1,int nSubItem = -1);函數參數nCol,[輸入]:存放新欄位頭的索引號,本參數只能大於等於0。pColumn,[輸入]:參數說明。lpszColumnHeading,[輸入]:存放新欄位頭的標籤字元串的內存指針,不能為NULL。nFormat,[輸入]:存放新欄位頭的標籤、及每個項目的在新欄位的標籤的對齊方式的值,可以為(選一至一個):LVCFMT_LEFT(0x0000):向左對齊。LVCFMT_RIGHT(0x0001):向右對齊。LVCFMT_CENTER(0x0002):居中對齊。注意:如果新欄位頭的索引號為0,則本參數將忽略。如果要設置索引號為0的欄位的對齊方式,有以下幾種方法:1、可以先插入索引號為1的欄位,然後再調用CListCtrl::DeleteColumn()函數刪除索引號為0的欄位。2、插入索引號為0的欄位後,再調用CListCtrl::SetColumn()函數修改欄位的對齊方式。nWidth,[輸入]:存放新欄位頭的初始寬度的值,單位像素。如果本參數為-1,表示使用默認寬度,一般為10。如果本參數為0或小於-1,表示寬度為0。nSubItem,[輸入]:Index of the subitem associated with the column. If this parameter is -1, no subitem is associated with the column.返回值-1:失敗。其他:新欄位的實際索引號。錯誤碼無線程安全否原子操作否其他說明只有報表視圖才能顯示欄位頭,且報表視圖必須插入欄位頭才能顯示列表控制項中的項目。如果新欄位頭的索引號在列表控制項中已經存在,則該索引號的欄位頭及以後的欄位頭全部加一,新欄位頭插入到該索引號對應位置。如果新欄位頭的索引號在列表控制項中不存在,則新欄位頭就插入到列表控制項的最後一個,並把新欄位頭的索引號修改為插入前最後一個欄位頭的索引號加一,如果列表控制項中沒有任何欄位頭,則新欄位頭就在第一個,且索引號為0。2.14.8.5 CListCtrl::DeleteColumn函數名稱DeleteColumn頭文件#include <afxcmn.h>庫文件無函數功能從列表控制項中刪除一個欄位頭。函數聲明BOOL DeleteColumn (int nCol);函數參數nCol,[輸入]:存放要刪除的欄位頭的索引號,本參數只能大於等於0。返回值非0:成功。0:失敗,要刪除的欄位頭的索引號不存在。錯誤碼無線程安全否原子操作否其他說明如果要刪除的欄位頭後面還有欄位頭,則後面的欄位頭的索引號全部將減一。2.14.8.6 CListCtrl::GetColumnWidth(未完成)函數名稱GetColumnWidth頭文件#include <afxcmn.h>庫文件無函數功能獲取列表控制項中某個欄位頭的寬度,單位像素。函數聲明類型 函數名 (類型 參數1,類型 參數2,……);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.14.8.7 CListCtrl::SetColumnWidth(未完成)函數名稱SetColumnWidth頭文件#include <afxcmn.h>庫文件無函數功能設置列表控制項中某個欄位頭的寬度,單位像素。函數聲明類型 函數名 (類型 參數1,類型 參數2,……);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.14.8.8 CListCtrl::GetExtendedStyle(未完成)函數名稱GetExtendedStyle頭文件#include <Windows.h>庫文件無函數功能獲取列表控制項對象的擴展樣式。函數聲明DWORD GetExtendedStyle ();函數參數無返回值擴展樣式的標記值,可以為(用"|"選零至多個):LVS_EX_GRIDLINES(0x00000001):在報表視圖中,如果設置本標記,表示顯示網格線,如果不設置本標記,表示隱藏網格線。LVS_EX_SUBITEMIMAGES(0x00000002):在報表視圖中,如果設置本標記,表示每個項目的每個欄位都可以顯示圖標,如果不設置本標記,表示每個項目只有第一個欄位才能顯示圖標,隱藏其他欄位的圖標。LVS_EX_CHECKBOXES(0x00000004):在任何視圖中,如果設置本標記,表示每個項目都帶複選框,如果不設置本標記,表示每個項目都不帶複選框。注意:可以調用CListCtrl::GetCheck()函數獲取複選框狀態,調用CListCtrl::SetCheck()函數設置複選框狀態。LVS_EX_TRACKSELECT(0x00000008):在任何視圖中,如果設置本標記,表示滑鼠在某項目上懸停一段時間後自動選中該項目,如果不設置本標記,表示不會自動選中項目。LVS_EX_HEADERDRAGDROP(0x00000010):在報表視圖中,如果設置本標記,表示每列報表頭可以拖動順序,但每列序號不變,如果不設置本標記,表示每列報表頭順序固定。LVS_EX_FULLROWSELECT(0x00000020):在報表視圖中,如果設置本標記,表示在每個項目的整行所有欄位都可以選中該項目,如果不設置本標記,表示只能在每個項目的第一欄位選中該項目。LVS_EX_ONECLICKACTIVATE(0x00000040):在任何視圖中,如果設置本標記,表示單擊任何項目即可選中該項目,並向父窗口發送LVN_ITEMACTIVATE項目激活消息,如果不設置本標記,表示單擊任何項目都不發送LVN_ITEMACTIVATE項目激活消息。LVS_EX_TWOCLICKACTIVATE(0x00000080):在任何視圖中,如果設置本標記,表示單擊任何已選中的項目,會向父窗口發送LVN_ITEMACTIVATE項目激活消息,如果不設置本標記,表示單擊任何已選中的項目都不發送LVN_ITEMACTIVATE項目激活消息。LVS_EX_FLATSB(0x00000100):在任何視圖中,如果設置本標記,表示使用扁平化風格顯示滾動條,如果不設置本標記,表示使用普通風格顯示滾動條。LVS_EX_REGIONAL(0x00000200):在圖標視圖中,如果設置本標記,表示只顯示每個項目的圖標和文本,隱藏列表控制項的邊框、背景、滾動條、複選框等,如果不設置本標記,表示正常顯示。LVS_EX_INFOTIP(0x00000400):在任何視圖中,如果設置本標記,表示當某個項目需要顯示Tooltip工具提示控制項時,向父窗口發送LVN_GETINFOTIP消息,如果不設置本標記,表示不顯示Tooltip工具提示控制項,也不向父窗口發送LVN_GETINFOTIP消息。LVS_EX_UNDERLINEHOT(0x00000800):在任何視圖中,如果設置本標記,表示在滑鼠懸停的項目上顯示下劃線,如果不設置本標記,表示在滑鼠懸停的項目上不顯示下劃線。LVS_EX_UNDERLINECOLD(0x00001000):在任何視圖中,如果設置本標記,表示在滑鼠未懸停的項目上顯示下劃線,如果不設置本標記,表示在滑鼠未懸停的項目上不顯示下劃線。LVS_EX_MULTIWORKAREAS(0x00002000):多工作區。LVS_EX_LABELTIP(0x00004000):LVS_EX_BORDERSELECT(0x00008000):在任何視圖中,如果設置本標記,表示通過改變邊框顏色方式來顯示已選中的項目,如果不設置本標記,表示通過高亮方式來顯示已選中的項目。以下標記需要XP及以後的系統才支持:LVS_EX_DOUBLEBUFFER(0x00010000):在任何視圖中,如果設置本標記,表示本控制項使用雙緩衝方式來進行重繪,雙緩衝方式下可以減少頻繁重繪時控制項的閃爍,如果不設置本標記,表示本控制項使用正常方式進行重繪,正常方式下頻繁重繪可能導致控制項閃爍。LVS_EX_HIDELABELS(0x00020000):LVS_EX_SINGLEROW(0x00040000):LVS_EX_SNAPTOGRID(0x00080000):LVS_EX_SIMPLESELECT(0x00100000):以下標記需要VISTA及以後的系統才支持:LVS_EX_JUSTIFYCOLUMNS(0x00200000):LVS_EX_TRANSPARENTBKGND(0x00400000):LVS_EX_TRANSPARENTSHADOWTEXT(0x00800000):LVS_EX_AUTOAUTOARRANGE(0x01000000):LVS_EX_HEADERINALLVIEWS(0x02000000):LVS_EX_AUTOCHECKSELECT(0x08000000):LVS_EX_AUTOSIZECOLUMNS(0x10000000):LVS_EX_COLUMNSNAPPOINTS(0x40000000):LVS_EX_COLUMNOVERFLOW(0x80000000):錯誤碼無線程安全是原子操作否其他說明2.14.8.9 CListCtrl::SetExtendedStyle函數名稱SetExtendedStyle頭文件#include <Windows.h>庫文件無函數功能設置列表控制項對象的擴展樣式。函數聲明DWORD SetExtendedStyle (DWORD dwNewStyle);函數參數dwNewStyle,[輸入]:存放新的擴展樣式的值,參考CListCtrl::GetExtendedStyle()函數的返回值。返回值成功設置了哪些擴展樣式到列表控制項錯誤碼無線程安全否原子操作否其他說明2.14.8.10 CListCtrl::GetItemText(未完成)函數名稱GetItemText頭文件#include <afxcmn.h>庫文件無函數功能獲取列表控制項中某個項目的某個欄位的標籤。函數聲明類型 函數名 (類型 參數1,類型 參數2,……);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.14.8.11 CListCtrl::SetItemText(未完成)函數名稱SetItemText頭文件#include <afxcmn.h>庫文件無函數功能設置列表控制項中某個項目的某個欄位的標籤。函數聲明類型 函數名 (類型 參數1,類型 參數2,……);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.14.8.12 CListCtrl::GetCheck函數名稱GetCheck頭文件#include <afxcmn.h>庫文件無函數功能獲取某個項目的複選框的狀態。函數聲明BOOL GetCheck (int nItem);函數參數nItem,[輸入]:存放項目的索引號的值,項目的索引號從0開始。返回值-1:項目沒有帶複選框,或指定的項目不存在。1:複選框處於選中狀態。0:複選框處於未選中狀態。錯誤碼無線程安全否原子操作否其他說明使用本函數前,需要列表控制項具有LVS_EX_CHECKBOXES擴展樣式。2.14.8.13 CListCtrl::SetCheck函數名稱SetCheck頭文件#include <afxcmn.h>庫文件無函數功能設置某個項目的複選框的狀態。函數聲明BOOL SetCheck (int nItem,BOOL fCheck = TRUE);函數參數nItem,[輸入]:存放項目的索引號的值,項目的索引號從0開始。fCheck,[輸入]:存放項目的複選框要設置的狀態,非0表示選中,0表示未選中。返回值1:成功,或項目沒有帶複選框。0:失敗,可能是指定的項目不存在。錯誤碼無線程安全否原子操作否其他說明2.14.8.14 CListCtrl::GetBkColor(未完成)函數名稱GetBkColor頭文件#include <afxcmn.h>庫文件無函數功能獲取列表控制項的背景色。函數聲明COLORREF GetBkColor (void);函數參數無返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明2.14.8.15 CListCtrl::SetBkColor(未完成)函數名稱SetBkColor頭文件#include <afxcmn.h>庫文件無函數功能設置列表控制項的背景色。函數聲明BOOL SetBkColor (COLORREF cr);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明2.14.8.16 CListCtrl::GetTextBkColor(未完成)函數名稱GetTextBkColor頭文件#include <afxcmn.h>庫文件無函數功能獲取列表控制項的全部項目的背景色。函數聲明COLORREF GetTextBkColor (void);函數參數無返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明2.14.8.17 CListCtrl::SetTextBkColor(未完成)函數名稱SetTextBkColor頭文件#include <afxcmn.h>庫文件無函數功能設置列表控制項的全部項目的背景色。函數聲明BOOL SetTextBkColor (COLORREF cr);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明2.14.8.18 CListCtrl::GetTextColor(未完成)函數名稱GetTextColor頭文件#include <afxcmn.h>庫文件無函數功能獲取列表控制項的全部項目的標籤的顏色。函數聲明COLORREF GetTextColor (void);函數參數無返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明2.14.8.19 CListCtrl::SetTextColor(未完成)函數名稱SetTextColor頭文件#include <afxcmn.h>庫文件無函數功能設置列表控制項的全部項目的標籤的顏色。函數聲明BOOL SetTextColor (COLORREF cr);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明2.14.8.20 CListCtrl::GetSelectedCount(未完成)函數名稱GetSelectedCount頭文件#include <afxcmn.h>庫文件無函數功能獲取列表控制項中被選中的項目總數。函數聲明類型 函數名 (類型 參數1,類型 參數2,……);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.14.8.21 LVN_GETDISPINFO(未完成)消息名稱LVN_GETDISPINFO函數名稱OnLvnGetdispinfo頭文件#include <Windows.h>產生條件當列表控制項中的某個項目的某個欄位的虛擬標籤重繪時,且列表控制項響應了本消息,就會立即產生本消息。函數聲明void CListCtrl::OnLvnGetdispinfo (NMHDR * pNMHDR,LRESULT * pResult)函數參數pNMHDR,[輸入&輸出]:輸入時,存放當前重繪的某個項目的某個欄位的信息。輸出時,存放當前重繪的某個項目的某個欄位的虛擬標籤。注意:如果要修改虛擬標籤字元串的內容,需要先調用CListCtrl::SetItemText()函數,然後再在本函數內修改。如果不先調用CListCtrl::SetItemText()函數,直接就在本函數內修改,有可能會導致列表控制項顯示出來的標籤內容錯誤。pResult,[輸入]:本參數無意義,直接填0即可。返回值無錯誤碼無線程安全是原子操作是其他說明例子:void CListCtrl:: OnLvnGetdispinfo(NMHDR *pNMHDR, LRESULT *pResult){NMLVDISPINFO * pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);pDispInfo->item.pszText = "這是虛擬標籤的內容";*pResult = 0;}本消息需要項目的標籤設置成LPSTR_TEXTCALLBACK宏才能產生。2.14.9 CIPAddressCtrl IP地址控制項類2.14.9.1 CIPAddressCtrl::GetAddress(未完成)函數名稱GetAddress頭文件#include <xxx.h>#include <xxx.h>庫文件#pragma comment(lib, "xxx.lib")函數功能函數主要功能說明。函數聲明類型 函數名 (類型 參數1,類型 參數2,……);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.15 消息機制Windows下的應用程序如果要接收消息,首先需要調用GetMessage()函數或PeekMessage()函數來創建一個線程消息隊列,用來存放該線程接收到的各種消息。消息分兩種,一種是進隊消息,一種是不進隊消息。進隊消息是指會被放入線程消息隊列的消息。例如PostMessage()函數和PostThreadMesssge()函數發送的消息,應用程序需要調用GetMessage()函數或PeekMessage()函數來獲取。不進隊消息是指操作系統直接調用窗口過程函數所處理的消息,不會被放入線程消息隊列,沒有窗口的線程是收不到這類消息的。例如,調用SendMessage()函數發送的消息,調用CreateWindow()函數創建窗口時自動發送的WM_CREATE消息,調用UpdateWindow()函數更新窗口時自動發送的WM_PAINT消息,調用DestroyWindow()函數銷毀窗口時自動發送的WM_DESTROY消息等都是不進隊消息。UIPI是指User Interface Privilege Isolation(用戶界面特權隔離),是Windows NT 6.0後(即Vista)引入的一種新的安全特性,是整個UAC機制的有機組成部分,主要用於攔截接受對自身進程MIC等級還低的進程發來的消息。根據Windows開發規範,用戶自定義消息都是大於WM_USER的。UIPI的默認規則是:一個進程如果向高於自己MIC等級的進程發送高於WM_USER的消息都會失敗,而系統自定義消息則會進行選擇性的過濾,某些容易引起危險的信息也會被過濾,比如WM_DROPFILES消息。上面提到UIPI是基於進程的MIC等級的,而在Windows NT6.0以後的系統裡面,由低到高一共分為六個等級:SECURITY_MANDATORY_UNTRUSTED_RID 不信任的MIC等級SECURITY_MANDATORY_LOW_RID 低MIC等級,如IE瀏覽器進程SECURITY_MANDATORY_MEDIUM_RID 中MIC等級,如Explorer桌面進程SECURITY_MANDATORY_HIGH_RID 高MIC等級,以管理員身份運行的都是這個等級SECURITY_MANDATORY_SYSTEM_RID 系統MIC等級,服務應用程序SECURITY_MANDATORY_PROTECTED_PROCESS_RID 受保護進程的MIC等級這裡可以看到IE是低MIC等級的,主要是為了在一定程度上解決IE的安全性問題,即使很多病毒通過IE下來,但是由於本身是通過IE系統,相應的MIC等級過低,可以防止他對其他進程造成不良影響。UIPI的引進可以比較有效的解決一些和窗口消息相關的安全性問題,比如窗口粉碎攻擊,惡意窗口信息等,但也帶來了一定的兼容性問題:1.以往通過窗口消息進行進程通信的程序很容易碰到這樣那樣的問題。2.運行在高MIC等級上的進程無法接受一些常用的系統信息,如前面提到的文件拖曳消息。2.15.1 消息發送2.15.1.1 SendMessage(未完成)函數名稱SendMessage頭文件#include <Windows.h>函數功能函數主要功能說明。函數聲明類型 函數名 (類型 參數1,類型 參數2,……);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.15.1.2 PostMessage(未完成)函數名稱PostMessage頭文件#include <Windows.h>函數功能函數主要功能說明。函數聲明類型 函數名 (類型 參數1,類型 參數2,……);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明當發送的消息被UIPI用戶界面特權隔離阻止了,本函數會返回失敗,並設置錯誤碼為5(拒絕訪問)。默認情況下消息隊列的最大長度為10000條,如果有程序收到的消息條數超過了該限制,需要考慮重新設計程序,或者修改以下註冊表項:HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsNTCurrentVersionWindowsUSERPostMessageLimit消息隊列的最大長度至少為4000。2.15.1.3 PostThreadMessage(未完成)函數名稱PostThreadMessage頭文件#include <Windows.h>函數功能發送一個消息到指定的線程標識對應的線程消息隊列,並立即返回,不會等待消息接收方處理完畢再返回。函數聲明BOOL PostThreadMessage (DWORD idThread,UINT Msg,WPARAM wParam,LPARAM lParam);函數參數idThread,[輸入]:存放消息接收方的線程標識,接收方的線程必須已經創建了線程消息隊列,否則本函數返回失敗。Msg,[輸入]:存放消息值。wParam,[輸入]:存放消息的第一個參數。lParam,[輸入]:存放消息的第二個參數。返回值非0:成功。0:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼ERROR_INVALID_THREAD_ID宏:接收方的線程標識是無效的,或者沒有創建線程消息隊列。ERROR_NOT_ENOUGH_QUOTA宏:接收方的消息隊列已達到最大值。線程安全是原子操作是其他說明2.15.2 消息獲取2.15.2.1 GetMessage(未完成)函數名稱GetMessage頭文件#include <Windows.h>函數功能本函數是從調用線程的線程消息隊列里取得一個消息並將其存放到指定的消息結構體,獲取消息成功後,將從消息隊列中刪除該消息。如果調用線程沒有消息隊列,本函數就會自動創建。此函數可以指定接收一定範圍的消息值。此函數不能接收其他線程消息隊列里的消息。此函數會一直阻塞等待直到有消息到來才返回。函數聲明BOOL GetMessage (LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax);函數參數lpMsg,[輸出]:存放用於存放消息的消息結構體的內存指針,參考MSG。hWnd,[輸入]:存放要接收哪個窗口的窗口消息的窗口句柄,只能是調用線程創建的窗口,不能是其他線程創建的。如果為NULL,表示接收窗口消息或者線程消息,不只接收窗口消息。如果為-1,表示只接收線程消息,不接收窗口消息。wMsgFilterMin,[輸入]:存放要接收的最小消息值。如果最小消息值和最大消息值都為0,就表示獲取所有消息。例如:鍵盤消息的最小消息值為WM_KEYFIRST(0x0100),滑鼠消息的最小消息值為WM_MOUSEFIRST (0x0200),如果只想獲取WM_INPUT消息,就把最小消息值和最大消息值都設置為WM_INPUT(0x00FF)。wMsgFilterMax,[輸入]:存放要接收的最大的消息值。如果最小消息值和最大消息值都為0,就表示獲取所有消息。例如:鍵盤消息的最大消息值為WM_KEYLAST(0x0109),滑鼠消息的最小消息值為WM_MOUSELAST(0x020E),如果只想獲取WM_INPUT消息,就把最小消息值和最大消息值都設置為WM_INPUT(0x00FF)。返回值非0:成功,接收到非WM_QUIT消息。0:成功,接收到WM_QUIT消息。-1:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明2.15.2.2 PeekMessage函數名稱PeekMessage頭文件#include <Windows.h>函數功能本函數是從調用線程的線程消息隊列里取得一個消息並將其存放到指定的消息結構體,獲取消息成功後,可以指定是否從消息隊列中刪除該消息。如果調用線程沒有消息隊列,本函數就會自動創建。本函數可以指定接收一定範圍的消息值。本函數不能接收其他線程消息隊列里的消息。本函數不會阻塞等待消息到來,如果線程消息隊列里沒有符合條件的消息,本函數立即返回失敗。函數聲明BOOL PeekMessage (LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg);函數參數lpMsg,[輸出]:存放用於存放消息的消息結構體的內存指針。詳見MSG結構體詳解。hWnd,[輸入]:存放要接收哪個窗口的窗口消息的窗口句柄,只能是調用線程創建的窗口,不能是其他線程創建的。如果為NULL,表示接收窗口消息或者線程消息,不只接收窗口消息。如果為-1,表示只接收線程消息,不接收窗口消息。wMsgFilterMin,[輸入]:存放要接收的最小消息值。如果最小消息值和最大消息值都為0,就表示獲取所有消息。例如:鍵盤消息的最小消息值為WM_KEYFIRST(0x0100),滑鼠消息的最小消息值為WM_MOUSEFIRST (0x0200),如果只想獲取WM_INPUT消息,就把最小消息值和最大消息值都設置為WM_INPUT(0x00FF)。wMsgFilterMax,[輸入]:存放要接收的最大的消息值。如果最小消息值和最大消息值都為0,就表示獲取所有消息。例如:鍵盤消息的最大消息值為WM_KEYLAST(0x0109),滑鼠消息的最小消息值為WM_MOUSELAST(0x020E),如果只想獲取WM_INPUT消息,就把最小消息值和最大消息值都設置為WM_INPUT(0x00FF)。wRemoveMsg,[輸入]:存放要如何接收消息的標記。可以為(用"|"選零至多個):PM_NOREMOVE(0):本函數接收到消息後,不從隊列里刪除該消息。本標記不能與PM_REMOVE標記同時使用。PM_REMOVE(1):本函數接收到消息後,要從隊列里刪除該消息。本標記不能與PM_NOREMOVE標記同時使用。PM_NOYIELD(2):本標誌使系統不釋放等待調用程序空閑的線程。可將本標記隨意組合到PM_NOREMOVE或PM_REMOVE標記。默認情況下,本函數接收所有消息,也可以指定一下類型進行接收(用"|"選零至多個):PM_QS_INPUT:接收滑鼠和鍵盤消息。PM_QS_PAINT:接收畫圖消息。PM_QS_POSTMESSAGE:接收所有Post寄送方式發送的消息,包括WM_TIMER計時器和WM_HOTKEY熱鍵。PM_QS_SENDMESSAGE:接收所有Send發送方式發送的消息。返回值非0:成功。0:失敗,沒有獲取到符合條件的消息。錯誤碼無。線程安全是原子操作是其他說明2.15.2.3 WaitMessage(未完成)函數名稱WaitMessage頭文件#include <Winuser.h>庫文件#pragma comment(lib, "User32.lib")函數功能當一個線程沒有消息在其消息隊列中的時候,線程放棄控制權給其他的線程。WaitMessage函數掛起線程,直到一個新的消息被放入線程的消息隊列中才返回。函數聲明BOOL WaitMessage (void);函數參數無返回值非0:成功。0:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明線程在調用一個函數核查線程消息隊列後,如果消息隊列中沒有可讀的消息,WaitMessage函數不會返回。這是因為PeekMessage、GetMessage、GetQueueStatus、WaitMessage、 MsgWaitForMultipleObjects和MsgWaitForMultipleObjectsEx這樣的函數核對消息隊列,改變隊列的狀態信息這樣輸入不再被認為是新的。如果連續調用WaitMessage將等到指定類型的新輸入到達後才返回。已存在的未讀過的輸入(在上次線程檢查隊列之前接收的)被忽略。2.15.3 消息處理2.15.3.1 滑鼠2.15.3.1.1 WM_MOUSEMOVE消息名稱WM_MOUSEMOVE(0x0200)函數名稱OnMouseMove頭文件#include <Windows.h>產生條件當滑鼠在窗口的客戶區上方移動時,就會立即產生本消息。當滑鼠在窗口的標題欄上方移動時,則不產生本消息。當滑鼠停留在窗口上不移動時,則不產生本消息。當滑鼠在其他窗口上移動時,則不產生本消息。函數聲明void OnMouseLeave (UINT nFlags,CPoint point);函數參數nFlags,[輸出]:存放產生本消息時各個虛擬鍵有沒有被按下,可能包含多個下列值:MK_CONTROL(0x0008):CTRL鍵被按下。MK_LBUTTON(0x0001):滑鼠左鍵被按下。MK_MBUTTON(0x0010):滑鼠中鍵被按下。MK_RBUTTON(0x0002):滑鼠右鍵被按下。MK_SHIFT(0x0004):SHIFT鍵被按下。MK_XBUTTON1(0x0020):第一個X按鈕被按下。MK_XBUTTON2(0x0040):第二個X按鈕被按下。point,[輸出]:存放產生本條消息時的滑鼠位置的結構體,不是接收本消息時的坐標,因為從消息的發送到接收是需要時間的。返回值無其他說明滑鼠是否在窗口的客戶區,是根據WM_NCHITTEST消息處理後的返回值來判斷的,如果WM_NCHITTEST消息處理不好,有可能會導致窗口接收不到本消息。2.15.3.1.2 WM_MOUSELEAVE消息名稱WM_MOUSELEAVE(0x02A3)函數名稱OnMouseLeave頭文件#include <Windows.h>產生條件首先需要調用TrackMouseEvent()函數將窗口設置為需要接收本消息,當滑鼠不在窗口上方時,就會立即產生本消息,無論滑鼠是否是從窗口上移動出去的。函數聲明void OnMouseLeave (void);函數參數無返回值無其他說明調用TrackMouseEvent()函數將窗口設置為需要處理本消息。例子:TRACKMOUSEEVENT stTME;stTME.cbSize = sizeof (stTME);//指定TRACKMOUSEEVENT結構體大小stTME.dwFlags = TME_LEAVE;//指定需要處理WM_MOUSELEAVE消息stTME.hwndTrack = m_hWnd;//指定要處理消息的窗口句柄TrackMouseEvent (&stTME);//設置WM_MOUSELEAVE消息需要被處理本消息在處理後,就不會再產生了,需要再次調用TrackMouseEvent()函數將窗口設置為需要處理本消息。建議在WM_MOUSEMOVE消息處理函數中調用TrackMouseEvent()函數,因為這個時候正好滑鼠在窗口上方,一旦滑鼠移動出去,就會產生本消息。不建議在本消息處理函數中調用TrackMouseEvent()函數,因為一旦滑鼠不在窗口上方時,就會不停的產生本消息,並且即使滑鼠再移動到窗口上方,還是會不停的產生本消息。2.15.3.1.3 WM_LBUTTONDOWN消息名稱WM_LBUTTONDOWN(0x0201)函數名稱OnLButtonDown頭文件#include <Windows.h>產生條件當滑鼠在窗口的客戶區上方按下左鍵時,就會立即產生本消息,不是左鍵彈起時。函數聲明void OnLButtonDown (UINT nFlags,CPoint point);函數參數nFlags,[輸出]:存放產生本消息時各個虛擬鍵有沒有被按下,可能包含多個下列值:MK_CONTROL(0x0008):CTRL鍵被按下。MK_LBUTTON(0x0001):滑鼠左鍵被按下。MK_MBUTTON(0x0010):滑鼠中鍵被按下。MK_RBUTTON(0x0002):滑鼠右鍵被按下。MK_SHIFT(0x0004):SHIFT鍵被按下。MK_XBUTTON1(0x0020):第一個X按鈕被按下。MK_XBUTTON2(0x0040):第二個X按鈕被按下。point,[輸出]:存放產生本條消息時的滑鼠位置的結構體,不是接收本消息時的坐標,因為從消息的發送到接收是需要時間的。返回值無其他說明左鍵彈起的時候會產生WM_LBUTTONUP消息。2.15.3.2 註銷、重啟、關機2.15.3.2.1 WM_QUERYENDSESSION消息名稱WM_QUERYENDSESSION(0x0011)函數名稱OnQueryEndSession頭文件#include <Windows.h>產生條件當系統在註銷、重啟、關機之前,就會立即產生本消息。本消息主要用於系統詢問各個進程,系統是否能繼續進行註銷、重啟、關機。函數聲明BOOL OnQueryEndSession();函數參數無返回值非0:同意系統繼續進行註銷、重啟、關機。0:不同意系統繼續進行註銷、重啟、關機。其他說明如果當前所有進程處理本消息後全部返回非0值,則系統的註銷、重起、關機將繼續下去,並且向所有進程再發送WM_ENDSESSION消息,並且消息參數bEnding為TRUE。如果當前有一個進程處理本消息後返回0值,則系統的註銷、重起、關機將被終止,並且不再繼續對剩餘的進程發送本消息,而是向已經發送過本消息的進程發送WM_ENDSESSION消息,並且消息參數bEnding為FALSE。如果要判斷系統是否真的要註銷、重起、關機,只要處理WM_ENDSESSION消息,並在根據消息參數bEnding是否為TRUE,來判斷系統是否真的要註銷、重起、關機,然後做出相應的處理。2.15.3.3 解析度2.15.3.3.1 WM_DISPLAYCHANGE消息名稱WM_DISPLAYCHANGE(0x007E)函數名稱WindowProc頭文件#include <Windows.h>產生條件當系統改變屏幕的解析度後,就會立即產生本消息。本消息只能在重載的WindowProc()函數中進行處理。函數聲明無函數參數wParam,[輸出]:存放每個像素所佔的顏色位數的值,例如:24表示24位色,32表示32位色。lParam,[輸出]:存放新解析度的水平和垂直長度的值,低位元組部分為新的水平解析度,高位元組部分為的新的垂直解析度。返回值無其他說明2.15.3.4 窗口位置、窗口大小2.15.3.4.1 WM_SIZING消息名稱WM_SIZING(0x0214)函數名稱OnSizing頭文件#include <Windows.h>產生條件當窗口的左邊、頂邊、右邊、底邊的長度將要改變但還沒有改變時,就會立即產生本消息,當整個窗口被移動時,則不產生。一般是用戶正在拖動窗口的邊框時,就會立即產生本消息。函數聲明void OnSizing (UINT fwSide,LPRECT pRect);函數參數fwSide,[輸出]:存放產生本消息時窗口的哪條邊或哪個角被拖動,可以為(選一至一個):WMSZ_BOTTOM(0x0006):底邊被拖動。WMSZ_BOTTOMLEFT(0x0007):底邊和左邊被拖動,也就是左下角。WMSZ_BOTTOMRIGHT(0x0008):底邊和右邊被拖動,也就是右下角。WMSZ_LEFT(0x0001):左邊被拖動。WMSZ_RIGHT(0x0002):右邊被拖動。WMSZ_TOP(0x0003):頂邊被拖動。WMSZ_TOPLEFT(0x0004):頂邊和左邊被拖動,也就是左上角。WMSZ_TOPRIGHT(0x0005):頂邊和右邊被拖動,也就是右上角。pRect,[輸入&輸出]:輸入時,存放產生本條消息時,窗口大小將要改變後的位置結構體的內存指針。輸出時,存放產生本條消息後,窗口大小實際改變後的位置結構體的內存指針。注意:程序可以修改本參數達到控制窗口大小的目的。返回值無其他說明產生本消息時,窗口大小實際還沒有改變,調用GetWindowRect()函數獲取到的還是沒有改變時的大小。2.15.3.5 計時器2.15.3.5.1 WM_TIMER(未完成)消息名稱WM_TIMER(0x0113)函數名稱OnTimer頭文件#include <Windows.h>產生條件當某個計時器的超時時間已過,就會立即產生本消息。函數聲明void OnTimer (UINT_PTR nIDEvent)函數參數nIDEvent,[輸出]:存放超時時間已過的計時器的標識。返回值無其他說明要觸發本消息,需要先調用SetTimer()函數。由於本消息不是操作系統產生的,而是程序在調用GetMessage()函數和PeekMessage()函數時產生的,所以如果某個計時器的超時時間已過,但是程序沒有來得及調用GetMessage()函數和PeekMessage()函數,則將不會產生本消息。GetMessage()函數和PeekMessage()函數產生本消息的原理就是,當發現某個計時器的超時時間點已過,然後就產生本消息,並把超時時間點設置成未來的一個時刻,這個時刻與啟動該計時器的時刻保持倍數於超時時間的增加。2.16 WinINet(Windows Internet)互聯網協議WinINet互聯網協議API主要支持三種協議:HTTP(Hypertext Transfer Protocol)萬維網的超文本傳輸協議、FTP(File Transfer Protocol)文件傳輸協議和GopherGopher信息查找協議。本API只能用於客戶端連接服務端,不支持搭建伺服器。WinINet函數內置有簡單卻靈活的緩衝支持。從網路接收到的任何數據都會緩存到硬碟中,然後在後續請求中被獲取。應用程序可以控制每個請求的緩存。對於來自伺服器的HTTP請求,大多數收到的頭部也被緩存。當從緩存中為HTTP請求獲取響應時,也會把緩存的頭部數據返回給調用者。這使得數據下載對於用戶是透明的,無論數據是來自緩存還是來自網路。使用永久URL緩存函數時,應用程序必須正確地分配緩衝區以得到想要的結果。2.16.1 解析2.16.1.1 InternetCrackUrl(未完成)函數名稱InternetCrackUrl頭文件#include <Windows.h>#include <Wininet.h>#pragma comment(lib, "wininet.lib")函數功能解析一個URL統一資源定位器字元串,分別獲得協議、用戶名、密碼、伺服器地址、埠號、路徑、額外信息。函數聲明BOOL InternetCrackUrl (LPCTSTR lpszUrl,DWORD dwUrlLength,DWORD dwFlags,LPURL_COMPONENTS lpUrlComponents);函數參數lpszUrl,[輸入]:存放URL統一資源定位器字元串的內存指針。dwUrlLength,[輸入]:存放URL統一資源定位器字元串的內存長度。如果lpszUrl參數以" "結束,該參數可以為0。dwFlags:[輸入|輸出|輸入&輸出],參數說明。lpUrlComponents,[輸出]:存放URL_COMPONENTS結構體的內存指針,解析後的各項信息就存放在此結構體里。返回值TRUE:成功。FLASE:失敗,調用GetlastError()函數獲取錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明2.16.2 連接2.16.2.1 InternetOpen(未完成)函數名稱InternetOpen頭文件#include <Windows.h>#include <Wininet.h>#pragma comment(lib, "wininet.lib")函數功能初始化WinINet,指定連接伺服器的方式,然後返回HINTERNET句柄。返回的HINTERNET句柄用於創建對指定伺服器的指定服務的連接。函數聲明HINTERNET InternetOpen (LPCSTR lpszAgent,DWORD dwAccessType,LPCSTR lpszProxy,LPCSTR lpszProxyBypass,DWORD dwFlags);函數參數lpszAgent,[輸入]:指向一個字元串,該字元串指定應用程序或實體調用WinInet函數的名稱。此名稱用作HTTP協議用戶代理,不需要就為NULL。dwAccessType,[輸入]:連接伺服器使用的方式,可以是(選一至一個):INTERNET_OPEN_TYPE_DIRECT:解析所有本地主機,可以理解為直連。INTERNET_OPEN_TYPE_PRECONFIG:返回註冊表中代理或直接的配置。INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY:返回註冊表中代理或直接的配置,並防止對Microsoft Jscript 或 INS文件的使用。INTERNET_OPEN_TYPE_PROXY:為代理傳遞請求,除非代理提供了旁路列表且解析的名字可以繞過代理;此時,函數使用INTERNET_OPEN_TYPE_DIRECT。lpszProxy,[輸入]:指定了當dwAccessType參數為INTERNET_OPEN_TYPE_PROXY時,此參數表示代理伺服器的名字。不要使用一個空的字元串,因為,該函數將使用它作為代理的名字。WinINet函數僅能識別OERN類型的代理和TIS網關。如果有安裝IE,這些函數也同樣支持SOCKS代理。FTP請求可由CERN類型代理或轉換為HTTP請求,或使用InternetOpenUrl函數實現。如果dwAccessType參數未被設置為INTERNET_OPEN_TYPE_PROXY,本參數無意義,直接填NULL。lpszProxyBypass,[輸入]:指向一個字元串,它指定一個可選的主機名列表或IP地址,列表可包括未知元素。如果dwAccessType參數未被設置為INTERNET_OPEN_TYPE_PROXY,本參數無意義,直接填NULL。dwFlags,[輸入]:其他功能標記,可以是(用"|"選零至多個):INTERNET_FLAG_ASYNC:僅能用於作用在該函數返回的句柄的子句柄上的非同步請求。INTERNET_FLAG_FROM_CACHE:不做網路請求。所有的實體都由緩存返回。如果請求條目不在緩存中,一個適當的錯誤將返回。INTERNET_FLAG_OFFLINE:與INTERNET_FLAG_FROM_CACHE標記一樣。返回值非NULL:HINTERNET句柄。NULL:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明使用完此函數返回的HINTERNET句柄後,需要調用InternetCloseHandle()函數釋放句柄資源。2.16.2.2 InternetConnect(未完成)函數名稱InternetConnect頭文件#include <Windows.h>#include <Wininet.h>#pragma comment(lib, "wininet.lib")函數功能使用InternetOpen()函數獲得的HINTERNET句柄來連接指定的伺服器的指定的服務,然後返回HINTERNET句柄。返回的HINTERNET句柄用於和伺服器之間的具體操作。函數聲明HINTERNET InternetConnect (HINTERNET hInternet,LPCSTR lpszServerName,INTERNET_PORT nServerPort,LPCSTR lpszUserName,LPCSTR lpszPassword,DWORD dwService,DWORD dwFlags,DWORD_PTR dwContext);函數參數hInternet,[輸入]:調用InternetOpen()函數獲得的HINTERNET句柄。lpszServerName,[輸入]:要連接的伺服器的IP地址或者域名。nServerPort,[輸入]:要連接的伺服器的埠號,可以自由指定,也可以是(選一至一個):INTERNET_DEFAULT_FTP_PORT:使用默認的FTP文件傳輸協議伺服器埠21。INTERNET_DEFAULT_GOPHER_PORT:使用默認的Gopher信息查找系統伺服器埠70。注意:僅適用於Windows XP和Windows Server 2003 R2及更早的操作系統。INTERNET_DEFAULT_HTTP_PORT:使用默認的HTTP超文本傳輸協議伺服器埠80。INTERNET_DEFAULT_HTTPS_PORT:使用默認的HTTPS安全超文本傳輸協議伺服器埠443。INTERNET_DEFAULT_SOCKS_PORT:使用默認的SOCKS防火牆安全會話轉換協議伺服器埠1080。INTERNET_INVALID_PORT_NUMBER:使用dwService參數指定的伺服器使用的默認埠。lpszUserName,[輸入]:連接伺服器使用的用戶名字元串。如果為NULL,則使用默認的匿名用戶。lpszPassword,[輸入]:連接伺服器使用的用戶名對應的密碼字元串。如果lpszUserName參數和此參數都為NULL,則使用默認的匿名用戶的密碼。如果lpszUserName參數不為NULL,但此參數為NULL,則使用空密碼。dwService,[輸入]:使用什麼協議連接伺服器,可以是(選一至一個):INTERNET_SERVICE_FTP:FTP文件傳輸協議。INTERNET_SERVICE_GOPHER:Gopher信息查找系統。注意:本標記僅適用於Windows XP和Windows Server 2003 R2及更早的操作系統。INTERNET_SERVICE_HTTP:HTTP超文本傳輸協議。dwFlags,[輸入]:其他功能標記。可以是(用"|"選零至多個):INTERNET_FLAG_PASSIVE:如果使用FTP文件傳輸協議協議,且使用此標記,表示使用被動模式連接。如果使用FTP文件傳輸協議協議,但不使用此標記,表示使用主動模式連接。如果不是使用FTP文件傳輸協議協議,此標記無意義。INTERNET_FLAG_EXISTING_CONNECT:如果使用相同的必須屬性創建連接,會嘗試使用現有的InternetConnect句柄。這僅僅是使用FTP操作時非常有用,因為FTP是,通常在同一會話中執行多個操作的唯一協議。緩存的WinINet一個連接句柄句柄InternetOpen生成的每個HINTERNET 。在InternetOpenUrl中和InternetConnect函數使用這個標記用於HTTP和FTP連接。dwContext,[輸入]:Pointer to a variable that contains an application-defined value that is used to identify the application context for the returned handle in callbacks.不需要就填NULL。返回值非NULL:HINTERNET句柄。NULL:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明使用完此函數返回的HINTERNET句柄後,需要調用InternetCloseHandle()函數斷開連接,並釋放句柄資源。如果使用HTTP協議連接,此時不會真正建立TCP套接字連接,只有在調用HttpSendRequest()函數後才會建立。2.16.3 選項2.16.3.1 InternetSetOption(未完成)函數名稱InternetSetOption頭文件#include <Windows.h>#include <Wininet.h>#pragma comment(lib, "wininet.lib")函數功能設置一個調用InternetOpen()或InternetConnect()函數獲取的HINTERNET句柄的選項的值。函數聲明BOOL InternetSetOption (HINTERNET hInternet,DWORD dwOption,LPVOID lpBuffer,DWORD dwBufferLength);函數參數hInternet,[輸入]:存放調用InternetOpen()或InternetConnect()函數獲取的HINTERNET句柄的值。dwOption,[輸入]:要設置選項,可以是(選一至一個):INTERNET_OPTION_CONNECT_TIMEOUT:連接遠端時的超時間間,單位毫秒,默認為60000毫秒,lpBuffer參數為unsigned long類型。INTERNET_OPTION_SEND_TIMEOUT:發送數據時的超時時間,單位毫秒,默認為30000毫秒,lpBuffer參數為unsigned long類型。INTERNET_OPTION_RECEIVE_TIMEOUT:接收數據時的超時間間,單位毫秒,默認為30000毫秒,lpBuffer參數為unsigned long類型。更多選項參考http://technet.microsoft.com/zh-cn/sysinternals/aa385328。lpBuffer,[輸入]:存放要設置的選項的值的內存指針,具體類型根據dwOption參數而定。dwBufferLength,[輸入]:存放選項的值的內存長度,單位位元組。返回值TRUE:成功。FALSE:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明2.16.3.2 InternetQueryOption(未完成)函數名稱InternetQueryOption頭文件#include <Windows.h>#include <Wininet.h>#pragma comment(lib, "wininet.lib")函數功能查看一個調用InternetOpen()或InternetConnect()函數獲取的HINTERNET句柄的選項的值。函數聲明BOOL InternetQueryOption (HINTERNET hInternet,DWORD dwOption,LPVOID lpBuffer,LPDWORD lpdwBufferLength);函數參數參數1:[輸入|輸出|輸入&輸出],參數說明。參數2:[輸入|輸出|輸入&輸出],參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.16.4 FTP文件傳輸協議2.16.4.1 目錄操作FtpCreateDirectory在FTP伺服器上建立目錄, 需要InternetConnect返回的會話句柄FtpRemoveDirectory在FTP伺服器上刪除目錄, 需要InternetConnect返回的會話句柄FtpGetCurrentDirectory獲取當前在FTP伺服器上的工作目錄, 需要InternetConnect返回的會話句柄FtpSetCurrentDirectory設置在FTP伺服器上的工作目錄, 需要InternetConnect返回的會話句柄2.16.4.2 文件操作2.16.4.2.1 FtpGetFile(未完成)函數名稱FtpGetFile頭文件#include <Windows.h>#include <Wininet.h>#pragma comment(lib, "wininet.lib")函數功能從FTP伺服器上下載指定文件到本地的指定文件。函數聲明BOOL FtpGetFile(HINTERNET hConnect,LPCTSTR lpszRemoteFile,LPCTSTR lpszNewFile,BOOL fFailIfExists,DWORD dwFlagsAndAttributes,DWORD dwFlags,DWORD_PTR dwContext);函數參數hConnect,[輸入]:存放調用InternetConnect()函數返回的FTP伺服器連接句柄。lpszRemoteFile,[輸入]:存放要從FTP伺服器上下載的指定文件的路徑字元串的內存指針。lpszNewFile,[輸入]:存放要下載文件到本地的指定文件的路徑字元串的內存指針。fFailIfExists,[輸入]:存放當本地的指定文件已存在時是否失敗的值。如果為非0,表示不替換已存在的文件,返回失敗。如果為0,表示替換已存在的文件。dwFlagsAndAttributes,[輸入]:存放本地的指定文件的文件屬性,可以是FILE_ATTRIBUTE_*宏。dwFlags,[輸入]:存放下載文件時的標記。以下是傳輸模式的標記,可以是(選一至一個):FTP_TRANSFER_TYPE_UNKNOWN宏(0x0000):用未知模式傳輸文件,其實就是二進位模式。FTP_TRANSFER_TYPE_ASCII宏(0x0001):用ASCII模式傳輸文件,將文件中的回車換行符轉換為本機的字元。例如:UNIX系統的回車換行符為"
",而Windows系統的回車換行符為"
",用此模式可以自動轉換這些字元。FTP_TRANSFER_TYPE_BINARY宏(0x0002):用二進位模式傳輸文件,不將文件中的任何字元進行轉換,保證文件的內容不會改變。INTERNET_FLAG_TRANSFER_ASCII宏(0x0001):用ASCII模式傳輸文件,同FTP_TRANSFER_TYPE_ASCII宏。INTERNET_FLAG_TRANSFER_BINARY宏(0x0002):用二進位模式傳輸文件,同FTP_TRANSFER_TYPE_BINARY宏。以下是傳輸方式的標記,可以是(用"|"選零至多個):INTERNET_FLAG_NEED_FILE宏(0x0010):如果文件不能被緩存,則創建一個臨時文件。INTERNET_FLAG_HYPERLINK宏(0x0400):當決定何時從網路重載時,如果伺服器沒有返回Expires time和LastModified,那麼強制重載。INTERNET_FLAG_RESYNCHRONIZE宏(0x0800):有條件地從互聯網下載請求的資源。如果緩存中的數據就是當前版本,則使用緩存中的數據;否則,重新從伺服器下載資源。INTERNET_FLAG_RELOAD宏(0x80000000):強製程序直接從互聯網獲取請求的資源,不從緩存中獲取,下載的信息又將重新被保存到緩存中。注意:如果允許從緩存中獲取的資源,可能會導致獲取到的資源和伺服器上的資源不一致。dwContext,[輸入]:存放用於接收狀態信息的回調函數的函數指針。不需要就填NULL。返回值非0:成功。0:失敗,調用GetlastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明網路不好的情況下本函數有可能出現卡住不返回的情況,設置超時時間可能可以解決。本函數存在下載成功,但實際下載的文件的長度與FTP上的文件的長度不同的情況,出現後,如果立即重新下載此文件很有可能文件長度還是不同,所以建議先刪除損壞的文件,繼續下載其他文件,等下載完後,斷開連接,再重連,再下載。2.16.4.2.2 FtpPutFile(未完成)函數名稱FtpPutFile頭文件#include <Wininet.h>庫文件#pragma comment(lib, "Wininet.lib")函數功能把本地的指定文件上傳到FTP伺服器的指定文件。函數聲明BOOL FtpPutFile (HINTERNET hConnect,LPCTSTR lpszLocalFile,LPCTSTR lpszNewRemoteFile,DWORD dwFlags,DWORD_PTR dwContext);函數參數hConnect,[輸入]:存放調用InternetConnect()函數返回的FTP伺服器連接句柄。lpszLocalFile,[輸入]:存放上傳前本地的指定文件的路徑字元串的內存指針,包括文件名。lpszNewRemoteFile,[輸入]:存放上傳後FTP伺服器的指定文件的路徑字元串的內存指針,包括文件名。dwFlags,[輸入]:存放上傳文件時的標記。以下是傳輸模式的標記,可以是(選一至一個):FTP_TRANSFER_TYPE_UNKNOWN宏(0x0000):用未知模式傳輸文件,就是二進位模式。FTP_TRANSFER_TYPE_ASCII宏(0x0001):用ASCII模式傳輸文件,將文件中的回車換行符轉換為本機的字元。例如:UNIX系統的回車換行符為"
",而Windows系統的回車換行符為"
",用此模式可以自動轉換這些字元。FTP_TRANSFER_TYPE_BINARY宏(0x0002):用二進位模式傳輸文件,不將文件中的任何字元進行轉換,保證文件的內容不會改變。INTERNET_FLAG_TRANSFER_ASCII宏(0x0001):用ASCII模式傳輸文件,同FTP_TRANSFER_TYPE_ASCII。INTERNET_FLAG_TRANSFER_BINARY宏(0x0002):用二進位模式傳輸文件,同FTP_TRANSFER_TYPE_BINARY。以下是傳輸方式的標記,可以是(用"|"選零至多個):INTERNET_FLAG_NEED_FILE宏(0x0010):如果文件不能被緩存,則創建一個臨時文件。INTERNET_FLAG_HYPERLINK宏(0x0400):當決定何時從網路重載時,如果伺服器沒有返回Expires time和LastModified,那麼強制重載。INTERNET_FLAG_RESYNCHRONIZE宏(0x0800):有條件地從互聯網下載請求的資源。如果緩存中的數據就是當前版本,則使用緩存中的數據;否則,重新從伺服器下載資源。INTERNET_FLAG_RELOAD宏(0x80000000):強製程序直接從互聯網獲取請求的資源,不從緩存中獲取,下載的信息又將重新被保存到緩存中。注意:從緩存中獲取的資源,可能會和伺服器上的資源不一致。dwContext,[輸入]:Pointer to a variable that contains the application-defined value that associates this search with any application data. This parameter is used only if the application has already called InternetSetStatusCallback to set up a status callback.不需要就填NULL。返回值非0:成功。0:失敗,調用GetlastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.16.4.2.3 FtpDeleteFile(未完成)函數名稱FtpDeleteFile頭文件#include <Windows.h>#include <Wininet.h>#pragma comment(lib, "wininet.lib")函數功能在FTP伺服器上刪除指定的文件。函數聲明BOOL FtpDeleteFile (HINTERNET hConnect,LPCTSTR lpszFileName);函數參數hConnect,[輸入]:存放調用InternetConnect()函數返回的FTP伺服器連接句柄。lpszFileName,[輸入]:存放要刪除的文件的路徑字元串的內存指針。返回值非0:成功。0:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明FtpFindFirstFile在FTP伺服器上查找符合條件的文件或目錄,需要InternetConnect返回的會話句柄InternetFindNextFile在FTP伺服器上繼續查找下一個符合條件的文件或目錄,需要FtpFindFirstFile返回的會話句柄FtpGetFileExFtpDeleteFile在FTP伺服器上刪除一個文件,需要InternetConnect返回的會話句柄FtpRenameFile在FTP伺服器上更改一個文件的名字,需要InternetConnect返回的會話句柄FtpOpenFile在FTP伺服器上打開一個文件, 需要InternetConnect返回的會話句柄InternetReadFile直接在FTP伺服器上讀取文件,需要FtpOpenFile返回的會話句柄InternetWriteFile直接在FTP伺服器上寫入文件,需要FtpOpenFile返回的會話句柄2.16.5 HTTP超文本傳輸協議2.16.5.1 HttpOpenRequest(未完成)函數名稱HttpOpenRequest頭文件#include <Windows.h>#include <Wininet.h>#pragma comment(lib, "wininet.lib")函數功能創建一個HTTP請求,返回該HTTP請求的HINTERNET句柄。函數聲明HINTERNET HttpOpenRequest (HINTERNET hConnect,LPCTSTR lpszVerb,LPCTSTR lpszObjectName,LPCTSTR lpszVersion,LPCTSTR lpszReferer,LPCTSTR * lplpszAcceptTypes,DWORD dwFlags,DWORD_PTR dwContext);函數參數hConnect,[輸入]:存放調用InternetConnect()函數連接HTTP伺服器後,返回的HINTERNET句柄。lpszVerb,[輸入]:存放請求名稱字元串的內存指針,為NULL就表示GET請求。例如:"GET","POST"等。lpszObjectName,[輸入]:存放請求的目標對象的名稱字元串的內存指針。一般是一個網頁文件路徑,一個可執行模塊名稱,一個搜索說明符等。lpszVersion,[輸入]:存放請求使用的HTTP協議版本字元串的內存指針,為NULL就表示HTTP/1.1版本。例如:"HTTP/1.0","HTTP/1.1"。lpszReferer,[輸入]:存放HTTP Referer的URL統一資源定位器字元串的內存指針。HTTP Referer是指當瀏覽器向HTTP伺服器發送請求的時候,一般會帶上Referer,告訴伺服器我是從哪個頁面鏈接過來的,伺服器藉此可以獲得一些信息用於處理。比如從我主頁上鏈接到一個朋友那裡,他的HTTP伺服器就能夠從HTTP Referer中統計出每天有多少用戶單擊我主頁上的鏈接訪問他的網站。lplpszAcceptTypes,[輸入]:存放本次請求可以接收的文件類型列表,為表示只接收文本文件。例如:"*/*"表示可以接收所有的文件類型,"text/*"表示只接收文本文件。dwFlags,[輸入]:存放請求使用的一些標記,可以是(用"|"選零至多個):INTERNET_FLAG_CACHE_IF_NET_FAIL:Returns the resource from the cache if the network request for the resource fails due to an ERROR_INTERNET_CONNECTION_RESET (the connection with the server has been reset) or ERROR_INTERNET_CANNOT_CONNECT (the attempt to connect to the server failed).INTERNET_FLAG_HYPERLINK:Forces a reload if there was no Expires time and no LastModified time returned from the server when determining whether to reload the item from the network.INTERNET_FLAG_IGNORE_CERT_CN_INVALID:Disables checking of SSL/PCT-based certificates that are returned from the server against the host name given in the request. WinINet functions use a simple check against certificates by comparing for matching host names and simple wildcarding rules.INTERNET_FLAG_IGNORE_CERT_DATE_INVALID:Disables checking of SSL/PCT-based certificates for proper validity dates.INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP:Disables detection of this special type of redirect. When this flag is used, WinINet functions transparently allow redirects from HTTPS to HTTP URLs.INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS:Disables detection of this special type of redirect. When this flag is used, WinINet functions transparently allow redirects from HTTP to HTTPS URLs.INTERNET_FLAG_KEEP_CONNECTION:Uses keep-alive semantics, if available, for the connection. This flag is required for Microsoft Network (MSN), NT LAN Manager (NTLM), and other types of authentication.INTERNET_FLAG_NEED_FILE:Causes a temporary file to be created if the file cannot be cached.INTERNET_FLAG_NO_AUTH:Does not attempt authentication automatically.INTERNET_FLAG_NO_AUTO_REDIRECT:Does not automatically handle redirection in HttpSendRequest.INTERNET_FLAG_NO_CACHE_WRITE:Does not add the returned entity to the cache.INTERNET_FLAG_NO_COOKIES:Does not automatically add cookie headers to requests, and does not automatically add returned cookies to the cookie database.INTERNET_FLAG_NO_UI:Disables the cookie dialog box.INTERNET_FLAG_PRAGMA_NOCACHE:Forces the request to be resolved by the origin server, even if a cached copy exists on the proxy.INTERNET_FLAG_RELOAD:Forces a download of the requested file, object, or directory listing from the origin server, not from the cache.INTERNET_FLAG_RESYNCHRONIZE:Reloads HTTP resources if the resource has been modified since the last time it was downloaded. All FTP resources are reloaded.Windows XP and Windows Server 2003 R2 and earlier:Gopher resources are also reloaded.INTERNET_FLAG_SECURE:Uses secure transaction semantics. This translates to using Secure Sockets Layer/Private Communications Technology (SSL/PCT) and is only meaningful in HTTP requests.dwContext,[輸入]:參數說明。返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明本函數只是創建HTTP請求,並沒有將HTTP請求發送到HTTP伺服器,需要調用HttpSendRequest()完成發送。2.16.5.2 HttpSendRequest(未完成)函數名稱HttpSendRequest頭文件#include <Windows.h>#include <Wininet.h>#pragma comment(lib, "wininet.lib")函數功能根據調用HttpOpenRequest()函數獲取的HTTP請求的HINTERNET句柄,發送該HTTP請求到HTTP伺服器。函數聲明BOOL HttpSendRequest (HINTERNET hRequest,LPCTSTR lpszHeaders,DWORD dwHeadersLength,LPVOID lpOptional,DWORD dwOptionalLength);函數參數參數1:[輸入|輸出|輸入&輸出],參數說明。參數2:[輸入|輸出|輸入&輸出],參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.16.6 斷開2.16.6.1 InternetCloseHandle(未完成)函數名稱InternetCloseHandle頭文件#include <Windows.h>#include <Wininet.h>#pragma comment(lib, "wininet.lib")函數功能斷開與伺服器的連接,並釋放調用InternetOpen()函數或InternetConnect()函數獲得的HINTERNE句柄資源。函數聲明BOOL InternetCloseHandle (HINTERNET hInternet);函數參數hInternet,[輸入]:存放調用InternetOpen()函數或InternetConnect()函數獲得的HINTERNET句柄。返回值0:失敗,調用GetLastError()函數查看錯誤碼。非0:成功。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明2.17 INI配置文件2.17.1 INI配置文件簡介為什麼要用INI文件?如果我們程序沒有任何配置文件時,這樣的程序對外是全封閉的,一旦程序需要修改一些參數必須要修改程序代碼本身並重新編譯,這樣很不好,所以要用配置文件,讓程序出廠後還能根據需要進行必要的配置;配置文件有很多如INI配置文件,XML配置文件,還有就是可以使用系統註冊表等。本文主要是為讀者在實現讀寫INI配置文件模塊之前,提供有關INI文件的格式信息。在早期的windows桌面系統中主要是用INI文件作為系統的配置文件,從win95以後開始轉向使用註冊表,但是還有很多系統配置是使用INI文件的。其實INI文件就是簡單的text文件,只不過這種txt文件要遵循一定的INI文件格式。現在的WINCE系統上也常常用INI文件作為配置文件,這次研究INI文件的目的就是為了我的GPS定位系統客戶端寫個系統配置文件。「.INI 」就是英文 「initialization」的頭三個字母的縮寫;當然INI file的後綴名也不一定是".ini"也可以是".cfg",".conf 」或者是".txt"。經典格式:INI文件的格式很簡單,最基本的三個要素是:parameters,sections和comments。什麼是parameters元素?INI所包含的最基本的「元素」就是parameter;每一個parameter都有一個name和一個value,name和value是由等號「=」隔開。name在等號的左邊。如:name = value什麼是sections章節?所有的parameters都是以sections為單位結合在一起的。所有的section名稱都是獨佔一行,並且sections名字都被方括弧包圍著([ and ])。在section聲明後的所有parameters都是屬於該section。對於一個section沒有明顯的結束標誌符,一個section的開始就是上一個section的結束,或者是end of the file。Sections一般情況下不能被nested,當然特殊情況下也可以實現sections的嵌套。section如下所示:[section]什麼是comments注釋?在INI文件中注釋語句是以分號「;」開始的。所有的所有的注釋語句不管多長都是獨佔一行直到結束的。在分號和行結束符之間的所有內容都是被忽略的。注釋實例如下:; comments text當然,上面講的都是最經典的INI文件格式,隨著使用的需求INI文件的格式也出現了很多變種;INI實例:; last modified 1 April 2001 by John Doe[owner] name=John Doeorganization=Acme Products[database]server=192.0.2.42; use IP address in case network name resolution is not workingport=143file = "acme payroll.dat"2.17.2 WritePrivateProfileString(未完成)函數名稱WritePrivateProfileString頭文件#include <Windows.h>函數功能向指定的INI配置文件的指定章節下的指定節點寫入指定的字元串值,本系列函數支持多線程同時讀寫同一個INI配置文件。函數聲明BOOL WritePrivateProfileString (LPCSTR lpAppName,LPCSTR lpKeyName,LPCSTR lpString,LPCSTR lpFileName);函數參數lpAppName,[輸入]:存放章節名稱字元串的內存指針。如果指定的章節不存在,會自動在INI配置文件末尾添加。lpKeyName,[輸入]:存放節點名稱字元串的內存指針。節點名稱中不能出現等於符號,因為每行的第一個等於符合為節點名稱和值的分隔符,且值的內容可以出現等於符號。如果指定的節點不存在,會自動在章節末尾添加。如果本參數為NULL,則會刪除指定的章節和章節下的所有節點。lpString,[輸入]:存放值的字元串的指針。如果指定的節點已存在,會自動替換以前的值。如果本參數為NULL,則會刪除指定的章節下的指定的節點。lpFileName,[輸入]:存放INI配置文件的路徑字元串的內存指針。可以是相對或絕對路徑,包括文件名。如果INI配置文件不存在,會自動創建。返回值非0:成功。0:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是,只在調用本系列函數時。其他說明2.17.3 WritePrivateProfileSection(未完成)函數名稱WritePrivateProfileSection頭文件#include <Windows.h>函數功能向指定的INI配置文件的指定章節下替換所有節點為指定的節點,本系列函數支持多線程同時讀寫同一個INI配置文件。函數聲明BOOL WritePrivateProfileSection (LPCSTR lpAppName,LPCSTR lpString,LPCSTR lpFileName);函數參數lpAppName,[輸入]:存放章節名稱字元串的內存指針,如果指定的章節不存在,會自動在INI配置文件末尾添加。lpString,[輸入]:存放多個節點名稱字元串的內存指針,節點之間用" "字元分隔,最後一個節點用" "結束。例如:"key1=value1 key2=value2 "。lpFileName,[輸入]:存放INI配置文件的路徑字元串的內存指針,可以是相對或絕對路徑,路徑字元串必須包含文件名。如果INI配置文件不存在,會自動創建。返回值非0:成功。0:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是,只在調用本系列函數時。其他說明2.17.4 WritePrivateProfileStruct(未完成)函數名稱WritePrivateProfileStruct頭文件#include <Windows.h>函數功能向指定的INI配置文件的指定章節下的指定節點寫入指定的結構體值,用本函數寫入的結構體值只能用GetPrivateProfileStruct()函數讀取出來,本系列函數支持多線程同時讀寫同一個INI配置文件。函數聲明BOOL WritePrivateProfileStruct (LPCSTR lpszSection,LPCSTR lpszKey,LPVOID lpStruct,UINT uSizeStruct,LPCSTR szFile);函數參數lpszSection,[輸入]:存放章節名稱字元串的內存指針。如果指定的章節不存在,會自動在INI配置文件末尾添加。lpszKey,[輸入]:存放節點名稱字元串的內存指針。節點名稱中不能出現等於符號,因為每行的第一個等於符合為節點名稱和值的分隔符,且值的內容可以出現等於符號。如果指定的節點不存在,會自動在章節末尾添加。如果本參數為NULL,則會刪除指定的章節和章節下的所有節點。不能為""空字元串,否則會內存讀寫錯誤。lpStruct,[輸入]:存放結構體值的內存指針。如果指定的節點已存在,會自動替換以前的值。如果本參數為NULL,則會刪除指定的章節下的指定的節點。uSizeStruct,[輸入]:存放結構體值的內存的長度。szFile,[輸入]:存放INI配置文件的路徑字元串的內存指針,可以是相對或絕對路徑,包括文件名。返回值非0:成功。0:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是,只在調用本系列函數時。其他說明2.17.5 GetPrivateProfileSectionNames(未完成)函數名稱GetPrivateProfileSectionNames頭文件#include <Windows.h>函數功能從指定的INI配置文件的讀取所有的章節名稱字元串,本系列函數支持多線程同時讀寫同一個INI配置文件。函數聲明DWORD GetPrivateProfileSectionNames (LPSTR lpszReturnBuffer,DWORD nSize,LPCSTR lpFileName);函數參數lpszReturnBuffer,[輸出]:存放所有的章節名稱字元串的內存指針,節點之間用" "字元分隔,最後一個章節用" "結束。例如:"Section1 Section2 …SectionN "。nSize,[輸入]:存放所有的章節名稱字元串的內存的長度。lpFileName,[輸入]:存放INI配置文件的路徑字元串的內存指針,可以是相對或絕對路徑,包括文件名。返回值輸出了多少位元組到存放所有的章節名稱字元串的內存,包括每個章節名稱的" "結束符,不包括最後一個" "結束符。錯誤碼無。線程安全是原子操作是,只在調用本系列函數時。其他說明2.17.6 GetPrivateProfileSection(未完成)函數名稱GetPrivateProfileSection頭文件#include <Windows.h>函數功能從指定的INI配置文件的指定章節下讀取所有的節點名稱和值字元串,本系列函數支持多線程同時讀寫同一個INI配置文件。函數聲明DWORD GetPrivateProfileSection (LPCWSTR lpAppName,LPWSTR lpReturnedString,DWORD nSize,LPCWSTR lpFileName);函數參數lpAppName,[輸入]:存放指定的章節名稱字元串的內存指針,字元串中不區分大小寫字母。lpszReturnBuffer,[輸出]:存放所有的節點名稱和值字元串的內存指針,節點之間用" "字元分隔,最後一個節點用" "結束,例如:"Key1=Value1 Key2=Value2 …KeyN=ValueN "。nSize,[輸入]:存放所有的節點名稱和值字元串的內存的長度。lpFileName,[輸入]:存放INI配置文件的路徑字元串的內存指針,可以是相對或絕對路徑,包括文件名。返回值非0:所有的節點名稱和值字元串的長度,包括所有的分隔符" ",不包括最後的" "結束符。如果存放所有的節點名稱和值字元串的內存不夠長,返回值就是內存的長度減2。0:失敗,或存放所有的節點名稱和值字元串的內存的長度小於等於2。錯誤碼無。線程安全是原子操作是,只在調用本系列函數時。其他說明2.17.7 GetPrivateProfileString(未完成)函數名稱GetPrivateProfileString頭文件#include <Windows.h>函數功能從指定的INI配置文件的指定章節下的指定節點讀取字元串值到指定的內存,本系列函數支持多線程同時讀寫同一個INI配置文件。函數聲明DWORD GetPrivateProfileString (LPCSTR lpAppName,LPCSTR lpKeyName,LPCSTR lpDefault,LPSTR lpReturnedString,DWORD nSize,LPCTSTR lpFileName);函數參數lpAppName,[輸入]:存放指定的章節名稱字元串的內存指針,字元串中不區分大小寫字母。lpKeyName,[輸入]:存放指定的節點名稱字元串的內存指針,字元串中不區分大小寫字母。節點名稱中不能出現等於符號,因為每行的第一個等於符合為節點名稱和值的分隔符,且值的內容可以出現等於符號。lpDefault,[輸入]:存放預設值的內存指針。如果指定的INI配置文件或章節或節點未找到,那麼就強制用預設值代替。如果本參數為NULL,就表示""空字元串。lpReturnedString,[輸出]:存放指定節點的字元串值的內存指針。nSize,[輸入]:存放指定節點的字元串值的內存長度。lpFileName,[輸入]:存放INI配置文件的路徑字元串的內存指針,可以是相對或絕對路徑,包括文件名。返回值字元串值的長度,不包括" "結束符。如果讀取失敗,返回值為0,且存放字元串值的內存的第一個位元組會設置成" "。錯誤碼無。線程安全是原子操作是,只在調用本系列函數時。其他說明章節名稱、節點名稱、節點值前後的無意義空格在查找和獲取時都將自動去掉,例如:[Section]、[ Section]、[Section ]都表示是Section章節,key=value、key =value 、 key = value 都表示key節點的值為value。2.17.8 GetPrivateProfileInt(未完成)函數名稱GetPrivateProfileInt頭文件#include <Windows.h>函數功能從指定的INI配置文件的指定章節下的指定節點讀取非負整數值到指定的內存,本系列函數支持多線程同時讀寫同一個INI配置文件。函數聲明UINT GetPrivateProfileInt (LPCSTR lpAppName,LPCSTR lpKeyName,INT nDefault,LPCSTR lpFileName);函數參數lpAppName,[輸入]:存放指定的章節名稱字元串的內存指針,字元串中不區分大小寫字母。lpKeyName,[輸入]:存放指定的節點名稱字元串的內存指針,字元串中不區分大小寫字母。節點名稱中不能出現等於符號,因為每行的第一個等於符合為節點名稱和值的分隔符,且值的內容可以出現等於符號。nDefault,[輸入]:存放預設值的內存指針。如果指定的INI配置文件或指定的章節或指定的節點未找到,那麼就強制用預設值代替。lpFileName,[輸入]:存放INI配置文件的路徑字元串的內存指針,可以是相對或絕對路徑,包括文件名。返回值讀取到的非負整數值錯誤碼無線程安全是原子操作是,只在調用本系列函數時。其他說明章節名稱、節點名稱、節點值前後的無意義空格在查找和獲取時都將自動去掉,例如:[Section]、[ Section]、[Section ]都表示是Section章節,key=value、key =value 、 key = value 都表示key節點的值為value。2.17.9 GetPrivateProfileStruct(未完成)函數名稱GetPrivateProfileStruct頭文件#include <Windows.h>函數功能從指定的INI配置文件的指定章節下的指定節點讀取結構體值到指定的內存,結構體值必須是調用WritePrivateProfileStruct()函數寫入的,本系列函數支持多線程同時讀寫同一個INI配置文件。函數聲明BOOL GetPrivateProfileStruct (LPCSTR lpszSection,LPCSTR lpszKey,LPVOID lpStruct,UINT uSizeStruct,LPCSTR szFile);函數參數lpszSection,[輸入]:存放指定的章節名稱字元串的內存指針,字元串中不區分大小寫字母。lpszKey,[輸入]:存放指定的節點名稱字元串的內存指針,字元串中不區分大小寫字母。節點名稱中不能出現等於符號,因為每行的第一個等於符合為節點名稱和值的分隔符,且值的內容可以出現等於符號。lpStruct,[輸出]:存放結構體值的內存指針。uSizeStruct,[輸入]:存放結構體值的內存的長度。szFile,[輸入]:存放INI配置文件的路徑字元串的內存指針,可以是相對或絕對路徑,路徑字元串必須包含文件名。返回值非0:成功。0:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是,只在調用本系列函數時。其他說明2.18 音頻用CWaveFile類操作WAVE格式的文件。waveInGetDevCapswaveInGetErrorTextwaveInGetIDwaveInGetPositionwaveInMessagewaveOutBreakLoopwaveOutClosewaveOutGetDevCapswaveOutGetErrorTextwaveOutGetIDwaveOutGetPitchwaveOutGetPlaybackRatewaveOutGetPositionwaveOutGetVolumewaveOutMessagewaveOutPausewaveOutPrepareHeaderwaveOutResetwaveOutRestartwaveOutSetPitchwaveOutSetPlaybackRatewaveOutSetVolumewaveOutUnprepareHeader2.18.1 輸入2.18.1.1 waveInGetNumDevs函數名稱waveInGetNumDevs頭文件#include <Mmsystem.h>庫文件#pragma comment(lib, "Winmm.lib")函數功能獲取可用的音頻輸入設備的數量,不包括已禁用、已斷開的音頻輸入設備。函數聲明UINT waveInGetNumDevs (void);函數參數無返回值0:沒有音頻輸入設備,或發生錯誤。其他:音頻輸入設備的數量。錯誤碼無線程安全是原子操作是其他說明2.18.1.2 waveInOpen(未完成)函數名稱waveInOpen頭文件#include <Mmsystem.h>庫文件#pragma comment(lib, "Winmm.lib")函數功能打開指定的音頻輸入設備,並獲取音頻輸入設備句柄。打開後,將產生WIM_OPEN消息。函數聲明MMRESULT waveInOpen (LPHWAVEIN phwi,UINT uDeviceID,LPCWAVEFORMATEX pwfx,DWORD_PTR dwCallback,DWORD_PTR dwCallbackInstance,DWORD fdwOpen);函數參數phwi,[輸出]:存放音頻輸入設備句柄的變數的內存指針。如果fdwOpen參數為WAVE_FORMAT_QUERY宏,本參數無意義。uDeviceID,[輸入]:存放設備ID,可以是一個設備標識符或一個已打開的音頻輸入設備句柄,設備標識符應該為從0到音頻輸入設備的數量,也可以為(選一至一個):WAVE_MAPPER宏(0xFFFF):系統自動根據指定的音頻格式結構體選擇的音頻輸入設備。pwfx,[輸入]:存放音頻輸入時所用的音頻格式結構體的內存指針,參考WAVEFORMATEX。dwCallback,[輸入]:存放指向回調函數的指針或窗口句柄,用於處理音頻輸入過程中產生的消息。回調函數參考waveInProc。dwCallbackInstance,[輸入]:存放傳遞給回調函數的數據,以回調函數的參數方式傳遞。如果回調方式為窗口方式,本參數無意義。fdwOpen,[輸入]:存放打開音頻輸入設備時的標記,可以為(選一至一個):CALLBACK_EVENT宏:dwCallback參數為事件句柄。CALLBACK_FUNCTION宏:如果設置本標記,表示回調函數回調方式,dwCallback參數為回調函數的內存指針,回調函數聲明參考waveInProc。該回調函數會一直在另外一個獨立的新線程中被調用執行。CALLBACK_THREAD宏:如果設置本標記,表示採用線程消息回調方式,dwCallback參數為線程ID,參數類型為DWORD。當音頻輸入設備句柄已經被調用waveInClose()函數關閉了,窗口將收到MM_WIM_OPEN消息。當音頻輸入設備已經完成一個音頻數據塊的採集,窗口將收到MM_WIM_DATA消息。當音頻輸入設備句柄已經被調用waveInOpen()函數打開了,窗口將收到MM_WOM_CLOSE消息。CALLBACK_WINDOW宏:如果設置本標記,表示採用窗口消息回調方式,dwCallback參數為窗口句柄,參數類型為HWND。當音頻輸入設備句柄已經被調用waveInClose()函數關閉了,窗口將收到MM_WIM_OPEN消息。當音頻輸入設備已經完成一個音頻數據塊的採集,窗口將收到MM_WIM_DATA消息。當音頻輸入設備句柄已經被調用waveInOpen()函數打開了,窗口將收到MM_WOM_CLOSE消息。CALLBACK_NULL宏:不使用任何回調機制。本標記是默認標記。WAVE_MAPPED_DEFAULT_COMMUNICATION_DEVICE宏:If this flag is specified and the uDeviceID parameter is WAVE_MAPPER, the function opens the default communication device.This flag applies only when uDeviceID equals WAVE_MAPPER.Note Requires Windows 7WAVE_FORMAT_DIRECT宏:如果設置本標記,表示通過指定的音頻輸入設備採集到的音頻數據塊結構體,不會被Abstract Control Model(ACM)驅動轉換。如果不設置本標記,表示通過指定的音頻輸入設備採集到的音頻數據塊結構體,可能會被Abstract Control Model(ACM)驅動轉換。WAVE_FORMAT_QUERY宏:如果設置本標記,表示查詢音頻輸入設備是否支持指定的音頻格式結構體,不會打開音頻輸入設備,phwi參數將無意義,支持就會返回MMSYSERR_NOERROR宏,不支持就會返回WAVERR_BADFORMAT宏。如果不設置本標記,表示查詢音頻輸入設備是否支持指定的音頻格式結構體,並打開音頻輸入設備,phwi參數將有意義,支持並打開成功就會返回MMSYSERR_NOERROR宏,不支持就會返回WAVERR_BADFORMAT宏,或其他錯誤。WAVE_MAPPED宏(0x0004):The uDeviceID parameter specifies a waveform-audio device to be mapped to by the wave mapper.返回值MMSYSERR_NOERROR宏(0x0000):成功。MMSYSERR_ALLOCATED宏(0x0004):Specified resource is already allocated.MMSYSERR_BADDEVICEID宏(0x0002):Specified device identifier is out of range.MMSYSERR_NODRIVER宏(0x0006):沒有音頻輸入設備。MMSYSERR_NOMEM宏(0x0007):不能分配或鎖定內存。WAVERR_BADFORMAT宏(0x0020):嘗試打開的音頻格式不被音頻輸入設備支持。錯誤碼無線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明同一進程中,如果多次打開同一音頻輸入設備,獲得的音頻輸入設備句柄都是一樣的。2.18.1.3 waveInProc函數名稱waveInProc頭文件#include <Mmsystem.h>庫文件無函數功能本函數為音頻輸入設備回調函數的聲明,當音頻輸入設備被打開、關閉、完成一個音頻數據塊的採集時,系統將自動回調本函數。函數聲明void waveInProc (HWAVEIN hwi,UINT uMsg,DWORD_PTR dwInstance,DWORD_PTR dwParam1,DWORD_PTR dwParam2);函數參數hwi,[輸入]:存放音頻輸入設備句柄。uMsg,[輸入]:存放音頻輸入設備的消息類型,可以為:WIM_CLOSE宏(0x03BF):當音頻輸入設備句柄已經被調用waveInClose()函數關閉了,將收到本消息。WIM_DATA宏(0x03C0):當音頻輸入設備已經完成一個音頻數據塊的採集,將收到本消息。WIM_OPEN宏(0x03BE):當音頻輸入設備句柄已經被調用waveInOpen()函數打開了,將收到本消息。dwInstance,[輸入]:存放音頻輸入設備句柄被調用waveInOpen()函數打開時的dwCallbackInstance參數。程序可以自由通過設置不同的本參數,來區分是哪一個音頻輸入設備。dwParam1,[輸入]:存放第一個消息參數。如果uMsg參數為WIM_DATA宏時,本參數為已經完成採集的音頻數據塊結構體的內存指針,類型為WAVEHDR *。如果uMsg參數為WIM_CLOSE宏、WIM_OPEN宏時,本參數無意義。dwParam2,[輸入]:存放第二個消息參數,本參數無意義。返回值無錯誤碼無線程安全是原子操作是其他說明2.18.1.4 waveInPrepareHeader函數名稱waveInPrepareHeader頭文件#include <Mmsystem.h>庫文件#pragma comment(lib, "Winmm.lib")函數功能初始化音頻數據塊結構體。函數聲明MMRESULT waveInPrepareHeader (HWAVEIN hwi,LPWAVEHDR pwh,UINT cbwh);函數參數hwi,[輸入]:存放音頻輸入設備句柄。pwh,[輸入]:存放一個音頻數據塊結構體的內存指針,參考WAVEHDR。cbwh,[輸入]:存放音頻數據塊結構體的內存長度,單位指針。返回值MMSYSERR_NOERROR宏(0x0000):成功。MMSYSERR_INVALHANDLE宏(0x0005):設備句柄無效。MMSYSERR_NOMEM宏(0x0007):不能分配或鎖定內存。MMSYSERR_HANDLEBUSY宏(0x000C):其他線程正在使用該設備。錯誤碼無線程安全是原子操作是其他說明當不再需要使用音頻數據塊結構體時,必須調用waveInUnprepareHeader()函數釋放,否則會內存泄漏。2.18.1.5 waveInUnprepareHeader(未完成)函數名稱waveInUnprepareHeader頭文件#include <Mmsystem.h>庫文件#pragma comment(lib, "Winmm.lib")函數功能釋放已經初始化的音頻數據塊結構體。函數聲明MMRESULT waveInUnprepareHeader (HWAVEIN hwi,LPWAVEHDR pwh,UINT cbwh);函數參數hwi,[輸入]:存放音頻輸入設備句柄。pwh,[輸入]:存放一個音頻數據塊結構體的內存指針,參考WAVEHDR。cbwh,[輸入]:存放音頻數據塊結構體的內存長度,單位指針。返回值MMSYSERR_NOERROR宏(0x0000):成功。MMSYSERR_INVALHANDLE宏(0x0005):設備句柄無效。MMSYSERR_NOMEM宏(0x0007):不能分配或鎖定內存。MMSYSERR_HANDLEBUSY宏(0x000C):其他線程正在使用該設備。WAVERR_STILLPLAYING宏(0x0021):音頻數據塊結構體還添加在音頻輸入設備上。錯誤碼無線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明要釋放的音頻數據塊結構體必須已經從音頻輸入設備上移除,否則無法釋放。2.18.1.6 waveInAddBuffer(未完成)函數名稱waveInAddBuffer頭文件#include <Mmsystem.h>庫文件#pragma comment(lib, "Winmm.lib")函數功能將已經初始化的音頻數據塊結構體添加到音頻輸入設備上。同一個音頻輸入設備上可以添加多個音頻數據塊結構體,這樣可以保證音頻輸入的連續性。當一個音頻數據塊結構體已經完成採集後,該結構體會自動從音頻輸入設備上移除。如果要實現連續音頻輸入,就在音頻輸入設備上添加多個音頻數據塊結構體,當某個採集好後被自動移除後,再立即添加進去,這樣音頻輸入就不會中斷,具體幾個需要自己試,一般兩個就夠。函數聲明MMRESULT waveInAddBuffer (HWAVEIN hwi,LPWAVEHDR pwh,UINT cbwh);函數參數hwi,[輸入]:存放音頻輸入設備句柄。pwh,[輸入]:存放一個已經調用waveInPrepareHeader()函數初始化的音頻數據塊結構體的內存指針。cbwh,[輸入]:存放音頻數據塊結構體的內存長度,單位指針。返回值MMSYSERR_NOERROR宏(0x0000):成功。MMSYSERR_INVALHANDLE宏(0x0005):設備句柄無效。MMSYSERR_NOMEM宏(0x0007):不能分配或鎖定內存。MMSYSERR_HANDLEBUSY宏(0x000C):其他線程正在使用該設備。WAVERR_UNPREPARED宏(0x0022):音頻數據塊結構體未初始化。錯誤碼無線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明如果不再需要音頻輸入,需先調用waveInClose()函數停止音頻輸入,再調用waveInReset()函數移除音頻輸入設備上所有的音頻數據塊結構體。2.18.1.7 waveInStart(未完成)函數名稱waveInStart頭文件#include <Mmsystem.h>庫文件#pragma comment(lib, "Winmm.lib")函數功能讓一個已經打開的音頻輸入設備句柄開始音頻輸入。當完成一個音頻數據塊的採集後,將產生WIM_DATA消息。函數聲明MMRESULT waveInStart (HWAVEIN hwi);函數參數hwi,[輸入]:存放音頻輸入設備句柄。返回值MMSYSERR_NOERROR宏(0x0000):成功。MMSYSERR_INVALHANDLE宏(0x0005):設備句柄無效。MMSYSERR_NODRIVER宏(0x0006):沒有音頻輸入設備。MMSYSERR_NOMEM宏(0x0007):不能分配或鎖定內存。錯誤碼無線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明2.18.1.8 waveInStop(未完成)函數名稱waveInStop頭文件#include <Mmsystem.h>庫文件#pragma comment(lib, "Winmm.lib")函數功能讓一個已經開始音頻輸入的音頻輸入設備句柄停止音頻輸入。停止音頻輸入後,將不再產生WIM_DATA消息。函數聲明MMRESULT waveInStop (HWAVEIN hwi);函數參數hwi,[輸入]:存放音頻輸入設備句柄。返回值MMSYSERR_NOERROR宏(0x0000):成功。MMSYSERR_INVALHANDLE宏(0x0005):設備句柄無效。MMSYSERR_NODRIVER宏(0x0006):沒有音頻輸入設備。MMSYSERR_NOMEM宏(0x0007):不能分配或鎖定內存。錯誤碼無線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明如果音頻輸入設備正在音頻輸入,但還沒有完成一個音頻數據塊的採集,則會立即中斷採集,併產生WIM_DATA消息,音頻數據塊結構體中的dwBytesRecorded成員變數將存放實際數據的內存長度。本函數不會移除還沒有使用的音頻數據塊。2.18.1.9 waveInReset(未完成)函數名稱waveInReset頭文件#include <Mmsystem.h>庫文件#pragma comment(lib, "Winmm.lib")函數功能讓一個已經開始音頻輸入的音頻輸入設備句柄停止音頻輸入,並將已經添加到音頻輸入設備上的所有音頻數據塊結構體全部移除。函數聲明MMRESULT waveInReset (HWAVEIN hwi);函數參數hwi,[輸入]:存放音頻輸入設備句柄。返回值MMSYSERR_NOERROR宏(0x0000):成功。MMSYSERR_INVALHANDLE宏(0x0005):設備句柄無效。MMSYSERR_NODRIVER宏(0x0006):沒有音頻輸入設備。MMSYSERR_NOMEM宏(0x0007):不能分配或鎖定內存。錯誤碼無線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明如果音頻輸入設備正在音頻輸入,但還沒有完成一個音頻數據塊的採集,則會立即中斷採集,併產生WIM_DATA消息,音頻數據塊結構體中的dwBytesRecorded成員變數將存放實際數據的內存長度。2.18.1.10 waveInClose(未完成)函數名稱waveInClose頭文件#include <Mmsystem.h>庫文件#pragma comment(lib, "Winmm.lib")函數功能讓一個已經打開的播放設備句柄關閉。如果播放設備上還有音頻數據塊結構體,必須先移除,否則會導致關閉失敗。函數聲明MMRESULT waveInClose (HWAVEIN hwi);函數參數hwi,[輸入]:存放音頻輸入設備句柄。返回值MMSYSERR_NOERROR宏(0x0000):成功。MMSYSERR_INVALHANDLE宏(0x0005):設備句柄無效。MMSYSERR_NODRIVER宏(0x0006):沒有音頻輸入設備。MMSYSERR_NOMEM宏(0x0007):不能分配或鎖定內存。WAVERR_STILLPLAYING宏(0x0021):音頻輸入設備上還有音頻數據塊結構體。錯誤碼無線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明2.18.2 輸出2.18.2.1 waveOutGetNumDevs函數名稱waveOutGetNumDevs頭文件#include <Mmsystem.h>庫文件#pragma comment(lib, "Winmm.lib")函數功能獲取可用的播放設備的數量,不獲取已禁用、已斷開的播放設備。函數聲明UINT waveOutGetNumDevs (void);函數參數無。返回值0:沒有播放設備,或發生錯誤。其他:播放設備的數量。錯誤碼無線程安全是原子操作是其他說明2.18.2.2 waveOutOpen(未完成)函數名稱waveOutOpen頭文件#include <Mmsystem.h>庫文件#pragma comment(lib, "Winmm.lib")函數功能打開指定的播放設備,並獲取播放設備句柄。打開後,將產生WOM_OPEN消息。函數聲明MMRESULT waveOutOpen (LPHWAVEOUT phwo,UINT_PTR uDeviceID,LPWAVEFORMATEX pwfx,DWORD_PTR dwCallback,DWORD_PTR dwCallbackInstance,DWORD fdwOpen);函數參數phwo,[輸出]:存放播放設備句柄的變數的內存指針。如果fdwOpen參數為WAVE_FORMAT_QUERY宏,本參數無意義。uDeviceID,[輸入]:存放設備ID,可以是一個設備標識符或一個已打開的播放設備句柄,設備標識符應該從0到播放設備的數量,也可以為(選一至一個):WAVE_MAPPER宏(0xFFFF):系統自動根據指定的音頻格式結構體選擇的播放設備。pwfx,[輸入]:存放播放時所用的音頻格式結構體的內存指針,參考WAVEFORMATEX。dwCallback,[輸入]:存放指向回調函數的指針或窗口句柄,用於處理播放過程中產生的消息。dwCallbackInstance,[輸入]:存放傳遞給回調函數的數據,以回調函數的參數方式傳遞。如果回調方式為窗口方式,本參數無意義。fdwOpen,[輸入]:存放打開播放設備時的標記,可以為(選一至一個):CALLBACK_EVENT宏:dwCallback參數為事件句柄。CALLBACK_FUNCTION宏:dwCallback參數為回調函數的內存指針,回調函數聲明參考waveOutProc。該回調函數會一直在另外一個獨立的新線程中執行。CALLBACK_THREAD宏:dwCallback參數為線程ID。CALLBACK_WINDOW宏:dwCallback參數為窗口句柄,dwCallback參數類型為HWND。CALLBACK_NULL宏:不使用任何回調機制。本標記是默認標記。WAVE_ALLOWSYNC宏:If this flag is specified, a synchronous waveform-audio device can be opened. If this flag is not specified while opening a synchronous driver, the device will fail to open.WAVE_MAPPED_DEFAULT_COMMUNICATION_DEVICE宏:If this flag is specified and the uDeviceID parameter is WAVE_MAPPER, the function opens the default communication device.This flag applies only when uDeviceID equals WAVE_MAPPER.Note Requires Windows 7WAVE_FORMAT_DIRECT宏:If this flag is specified, the ACM driver does not perform conversions on the audio data.WAVE_FORMAT_QUERY宏:The function queries the device to determine whether it supports the given format, but it does not open the device.WAVE_MAPPED宏:The uDeviceID parameter specifies a waveform-audio device to be mapped to by the wave mapper.返回值MMSYSERR_NOERROR宏(0x0000):成功。MMSYSERR_ALLOCATED宏(0x0004):Specified resource is already allocated.MMSYSERR_BADDEVICEID宏(0x0002):Specified device identifier is out of range.MMSYSERR_NODRIVER宏(0x0006):沒有音頻輸入設備。MMSYSERR_NOMEM宏(0x0007):不能分配或鎖定內存。WAVERR_BADFORMAT宏(0x0020):Attempted to open with an unsupported waveform-audio format.WAVERR_SYNC宏(0x0023):The device is synchronous but waveOutOpen was called without using the WAVE_ALLOWSYNC flag.錯誤碼無線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.18.2.3 waveOutProc(未完成)函數名稱waveOutProc頭文件#include <Mmsystem.h>庫文件#pragma comment(lib, "Winmm.lib")函數功能本函數為播放設備回調函數的聲明,當播放設備被打開、關閉、完成一個音頻數據塊的播放時,系統將自動回調本函數。函數聲明void waveOutProc (HWAVEOUT hwo,UINT uMsg,DWORD_PTR dwInstance,DWORD_PTR dwParam1,DWORD_PTR dwParam2);函數參數hwo,[輸入]:存放播放設備句柄。uMsg,[輸入]:存放播放設備的消息類型,可以為:WOM_CLOSE宏(0x03BF):當播放設備句柄已經被調用waveInClose()函數關閉了,將收到本消息。WOM_DATA宏(0x03C0):當播放設備已經完成一個音頻數據塊的播放,將收到本消息。WOM_OPEN宏(0x03BE):當播放設備句柄已經被調用waveInOpen()函數打開了,將收到本消息。dwInstance,[輸入]:存放播放設備句柄被調用waveOutOpen()函數打開時的dwCallbackInstance參數。程序可以自由通過設置不同的本參數,來區分是哪一個播放設備。dwParam1,[輸入]:存放第一個消息參數。如果uMsg參數為WOM_DATA宏時,本參數為已經完成播放的音頻數據塊結構體的內存指針,類型為WAVEHDR *。如果uMsg參數為WOM_CLOSE宏、WOM_OPEN宏時,本參數無意義。dwParam2,[輸入]:存放第二個消息參數,本參數無意義。返回值無錯誤碼無線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.18.2.4 waveOutWrite(未完成)函數名稱waveOutWrite頭文件#include <Mmsystem.h>庫文件#pragma comment(lib, "Winmm.lib")函數功能將已經完成採集的音頻數據塊結構體添加到播放設備上,並開始播放,播放完畢後將自動移除音頻數據塊結構體。如果要實現連續播放,必須音頻數據塊結構體播放完畢並移除後,才能再次添加音頻數據塊結構體播放設備上。函數聲明類型 函數名 (類型 參數1,類型 參數2,……);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.18.2.5 waveOutClose(未完成)函數名稱waveOutClose頭文件#include <Mmsystem.h>庫文件#pragma comment(lib, "Winmm.lib")函數功能函數主要功能說明。函數聲明類型 函數名 (類型 參數1,類型 參數2,……);函數參數參數1,[輸入|輸出|輸入&輸出]:參數說明。參數2,[輸入|輸出|輸入&輸出]:參數說明。……返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.18.2.6 PlaySound函數名稱PlaySound頭文件#include <windows.h>#pragma comment(lib, "winmm.lib")函數功能播放音頻,音頻可以是WAVE音頻文件、內存中的WAVE音頻數據、程序自身的WAVE資源,本函數不能讓進程同時播放兩段音頻,不同的進程可以同時播放。函數聲明BOOL PlaySound (LPCSTR pszSound,HMODULE hmod,DWORD fdwSound);函數參數pszSound,[輸入]:存放音頻數據的內存指針,具體作用根據fdwSound參數的標記而定。hmod,[輸入]:存放當前程序實例的句柄的值,只有當fdwSound參數的設置了SND_RESOURCE標記才有意義,其他情況,此參數必須為NULL。fdwSound,[輸入]:播放標記,可以是(用"|"選一至多個):SND_ALIAS:設置此標記表示pszSound參數為指定的註冊表或WIN.INI中的系統事件的別名,有些操作系統可能沒有某些事件。如果指定的系統事件不存在,就會導致播放音頻失敗。pszSound參數可以是(選一至一個):"SystemAsterisk":「SystemAsterisk系統星號聲」事件。"SystemDefault":「SystemDefault系統默認聲」事件。"SystemExclamation":「SystemExclamation系統感嘆聲」 事件。"SystemExit":「SystemExit系統退出聲」 事件。"SystemHand":「SystemHand系統指針聲」 事件。"SystemQuestion":「SystemQuestion系統詢問聲」 事件。"SystemStart":「SystemStart系統啟動聲」 事件。"SystemWelcome":「SystemWelcome系統歡迎聲」 事件。SND_ALIAS_ID:設置此標記表示pszSound參數為指定的註冊表或WIN.INI中的系統事件的別名ID,有些操作系統可能沒有某些事件。如果指定的系統事件不存在,就會導致播放音頻失敗。pszSound參數可以是(選一至一個):SND_ALIAS_SYSTEMASTERISK:「SystemAsterisk系統星號音」事件。SND_ALIAS_SYSTEMDEFAULT:「SystemDefault系統默認音」 事件。SND_ALIAS_SYSTEMEXCLAMATION:「SystemExclamation系統感嘆聲」 事件。SND_ALIAS_SYSTEMEXIT:「SystemExit系統退出聲」 事件。SND_ALIAS_SYSTEMHAND:「SystemHand系統指針聲」 事件。SND_ALIAS_SYSTEMQUESTION:「SystemQuestion系統詢問聲」 事件。SND_ALIAS_SYSTEMSTART:「SystemStart系統啟動聲」 事件。SND_ALIAS_SYSTEMWELCOME:「SystemWelcome系統歡迎聲」 事件。SND_RESOURCE:pszSound參數為WAVE資源的標識符,hmod參數就為WAVE資源的標識符所屬的程序實例的句柄,當前程序實例就可調用AfxGetResourceHandle()函數獲得。SND_FILENAME:pszSound參數為指定的WAVE文件名相對或絕對路徑字元串的內存指針。SND_MEMORY:pszSound參數為存放音頻數據的內存指針,播放已經載入到內存中的音頻。如果同時還設置了SND_ASYNC標記,必須保證存放音頻數據的內存在播放結束前是正確的。以上標記必選一至一個。SND_ASYNC:非同步方式播放音頻,PlaySound()函數在開始播放後立即返回,不等待播放結束。SND_SYNC:同步方式播放音頻,在播放結束後PlaySound()函數才返回。SND_LOOP:如果設置此標記,表示不停的重複播放音頻,包括播放音頻失敗時的預設音頻,必須與SND_ASYNC標誌同時設置;如果不設置此標記,音頻在播放一次後就結束了。SND_APPLICATION:用應用程序指定的關聯來播放音頻,如果沒有關聯的播放程序,就會導致播放音頻失敗。SND_NODEFAULT:如果設置此標記,當播放音頻失敗時,本函數就返回失敗;如果不設置此標記,當播放音頻失敗時,則本函數就播放預設音頻,並且返回成功。SND_NOSTOP:如果設置此標記,且當前進程的任意線程正在調用本函數同步或非同步播放音頻,就表示不結束當前正在播放的音頻,並立即返回失敗;如果不設置此標記,且當前進程的任意線程正在調用本函數非同步播放音頻,就表示立即結束當前正在播放的音頻,開始播放本函數指定的音頻,但是如果當前進程的其他線程正在調用本函數同步播放音頻,就表示等待其他線程同步播放結束,再開始播放本函數指定的音頻。SND_NOWAIT:如果驅動程序正忙則函數就不播放音頻,並立即返回失敗。SND_PURGE:停止所有與調用任務有關的音頻。如果pszSound參數為NULL,就停止所有的音頻,否則,停止pszSound指定的音頻。返回值非0:成功。0:失敗,無法查看錯誤碼。錯誤碼無線程安全是原子操作是其他說明此函數對多線程的調用的行為不是很明確,所以要多線程播放音頻不推薦使用此函數。2.19 視頻2.20 API HOOK捕獲系統APIDetours是微軟開發的一個函數庫,可用於捕獲系統API。2.21 異常處理2.21.1 簡介在C++發展的後期,有的C++編譯系統根據實際工作的需要,增加了一些功能,作為工具來使用,其中主要有模板(包括函數模板和類模板)、異常處理、命名空間和運行時類型,以幫助程序設計人員更方便地進行程序的設計和調試工作。1997年ANSI C++委員會將它們納入了ANSII C++標準,建議所有的C++編譯系統都能實現這些功能。這些工具是非有用的,C++的使用者應當盡量使用這些工具,因此本書對此作簡要的介紹,以便為日後的進一步學習和使用打下初步基礎。在本章中主要介紹異常處理和命名空間,應當注意,期的C++是不具備這些功能的,只有近期的C++系統根據ANSIC++的要求,實現了這些功能。請讀者注意使用的C++版本。2.21.2 異常處理的目的程序員總是希望自己所編寫的程序都是正確無誤的,而且運行結果也是完全正確的。但是這幾乎是不可能的,智者千慮,必有一失,不怕一萬,就怕萬一。因此,程序編製者不僅要考慮程序沒有錯誤的理想情況,更要考慮程序存在錯誤時的情況,應該能夠儘快地發現錯誤,消除錯誤。語法錯誤:在編譯時,編譯系統能發現程序中的語法錯誤(如關鍵字拼寫錯誤,變數名未定義,語句末尾缺分號,括弧不配對等),編譯系統會告知用戶在第幾行出錯,是什麼樣的錯誤。由於是在編譯階段發現的錯誤,因此這類錯誤又稱編譯錯誤。有的初學者寫的並不長的程序,在編譯時會出現十幾個甚至幾十個語法錯誤,有人往往感到手足無措。但是,總的來說,這種錯誤是比較容易發現和糾正的,因為它們一般都是有規律的,在有了一定的編譯經驗以後,可以很快地發現出錯的位置和原因並加以改正。運行錯誤:有的程序雖然能通過編譯,也能投入運行。但是在運行過程中會出現異常,得不到正確的運行結果,甚至導致程序不正常終止,或出現死機現象。例如:.在一系列計算過程中,出現除數為0的情況。.內存空間不夠,無法實現指定的操作。.無法打開輸入文件,因而無法讀取數據。.輸入數據時數據類型有錯。由於程序中沒有對此的防範措施,因此系統只好終止程序的運行。這類錯誤比較隱蔽,易被發現,往往耗費許多時間和精力,這成為程序調試中的一個難點。在設計程序時,應當事先分析程序運行時可能出現的各種意外的情況,並且分別制訂出相應的處理方法,這就是程序的異常處理的目的。需要說明:在一般情況下,異常指的是出錯(差錯),但是異常處理並不完全等同於對出錯的處理。只要出現與人們期望的情況不同,都可以認為是異常,並對它進行異常處理。例如,在輸入學生學號時輸入了負數,此時程序並不出錯,也不終止運行,但是人們認為這是不應有的學號,應予以處理。因此,所謂異常處理指的是對運行時出現的差錯以及其他例外情況的處理。2.21.3 異常處理的方法C++處理異常的機制引入在一個小的程序中,可以用比較簡單的方法處理異常,例如用if語句判別除數是否為0,如果是。則輸出一個出錯信息。但是在一個大的系統中,包含許多模塊,每個模塊義包含許多函數,函數之間又五相調用,比較複雜。如果在每一個函數中都設置處理異常的程序段,會使程序過於複雜和龐大。因此,C++採取的辦法是:如果在執行一個函數過程中出現異常,可以不在本函數中立即處理,而是發出一個信息,傳給它的上一級(即調用它的函數),它的上級捕捉到這個信啟後進行處理。如果上一級的函數也不能處理,就再傳給其上一級,由其上一級處理。如此逐級上送,如果到最高一級還無法處理,最後只好異常終止程序的執行。這樣做使異常的發現與處理不由同一函數來完成。好處是使底層的函數專門用於解決實際任務,而不必再承擔處理異常的任務,以減輕底層函數的負擔,而把處理異常的任務上移到某一層去處理。例如在主函數中調用十幾個函數,只需在主函數中設置處理異常即可,而不必在每個函數中都設置處理異常,這樣可以提高效率。C++處理異常的機制組成C++處理異常的機制是由3個部分組成的,即檢查(try)、拋出(throw)和捕捉(catch)。把需要檢查的語句放在try塊中,throw用來當出現異常時發出(形象地稱為拋出,throw的意思是拋出)一個異常信息,而catch則用來捕捉異常信息,如果捕捉到廠異常信息,就處理它:例1給出三角形的三邊a,b,c,求三角形的面積。只有a+b>c,b+c>a,c+a>b時才能構成三角形。設置異常處理,對不符合三角形條件的輸出警告信息,不予計算。#include <iostream>#include <cmath>using namespace std;int main(){double triangle(double,double,double);double a,b,c;cin>>a>>b>>c;while(a>0 && b>0 && c>0){cout<<triangle(a,b,c)<<endl;cin>>a>>b>>c;}return 0;}double triangle (double a, double b, double c){double area;double s = (a+b+c)/2;area = sqrt ( s * (s - a) * (s - b) * (s - c));return area;}運行情況如下:6 5 4/(輸入a,b,c的值)9.92157(輸出三角形的面積)1 1.5 2/(輸入a,b,c的值)0.726184(輸出三角形的面積}1 2 1 /(輸人a,b,c的值)0(輸出三角形的面積,此結果顯然不對,因為不是三角形)1 0 6/ (輸入a,b,c的值)(結束)程序沒有對三角形條件(任意兩邊之和應大於第三邊)進行檢查,因此,當輸入a=l,b=2,c=1時,則計算出三角形的面積為0,顯然是不合適的。現在修改程序,在函數triangle中對三角形條件進行檢查,如果不符合三角形條件,就拋出一個異常信息,在主函數中的try-catch塊中調用triangle函數,檢測有無異常信息,並相應處理。修改後的程序如下:#include <iostream>#include <cmath>using namespace std;int main(){double triangle(double,double,double);double a,b,c;cin>>a>>b>>c;try//在try塊中包含要檢查的函數{while(a>0 && b>0 && c>0){cout<<triangle(a,b,c)<<endl;cin>>a>>b>>c;}}catch(double)//用catch捕捉異常信息並作相應處理{cout<<"a="<<a<<",b="<<b<<",c="<<c<<",that is not a traingle!"<<endl;}cout<<"end"<<endl;return 0;}double triangle (double a, double b, double c)//計算三角形的面積的函數{double sqrt;double s=(a+b+c)/2;if (a+b<=c||b+c<=a||c+a<=b) throw a;//當不符合三角形條什拋出異常信息return sqrt(s*(s-a)*(s-b)*(s-c));}程序運行結果如下:6 5 4(輸入a,b,c的值)9.92157(計算出三角形的面積)1 1.5 2(輸入a,b,c的值)0.726184(計算出三角形的面積)1 2 1(輸入a,b,c的值)a=1,b=2,c=1,that is not a triangle!(異常處理)end現在結合程序分析怎樣進行異常處理。(1)首先把可能出現異常的、需要檢查的語句或程序段放在try後面的花括弧中。由於riangle函數是可能出現異常的部分,所以把while循環連同triangle函數放在try塊中。這些語句是正常流程的一部分,雖然被放在by塊中,並不影響它們按照原來的順序執行。(2)程序開始運行後,按正常的順序執行到try塊,開始執行by塊中花括弧內的語句。如果在執行try塊內的語句過程中沒有發生異常,則catch子句不起作用,流程轉到catch子句後面的語句繼續執行。(3)如果在執行try塊內的語句(包括其所調用的函數)過程中發生異常,則throw運算符拋出一個異常信息。請看程序中的triangle函數部分,當不滿足三角形條件時,throw拋出double類型的異常信息a。throw拋出異常信息後,流程立即離開本函數,轉到其上一級的函數(main函數)。因此不會執行triangle函數中if語句之後的return語句。throw拋出什麼樣的數據由程序設計者自定,可以是任何類型的數據(包括自定義類型的據,如類對象)。(4)這個異常信息提供給try-catch結構,系統會尋找與之匹配的catch子句。現在a是double型,而catch子句的括弧內指定的類型也是double型,二者匹配,即catch捕獲了該異常信息,這時就執行catch子句中的語句,本程序輸出a=1.b=2,c=1,that is not a triangle!(5)在進行異常處理後,程序並不會自動終止,繼續執行catch子句後面的語句。本程序輸出「end」。注意並不是從出現異常點繼續執行while循環。如果在try塊的花括弧內有10個語句,在執行第3個語句時出現異常,則在處理完該異常後,其餘7個語句不再執行,而轉到catch子句後面的語句去繼續執行。由於catch子句是用來處理異常信息的,往往被稱為catch異常處理塊或catch異常處理器。異常處理的語法:throw語句一般是由throw運算符和一個數據組成的,其形式為:throw 表達式;try-catch的結構為:try{被檢查的語句;}catch(異常信息類型[變數名]){進行異常處理的語句;}說明:(1)被檢測的函數必須放在try塊中,否則不起作用。(2)try塊和catch塊作為—個整體出現,catch塊是try-catch結構中的一部分,必須緊跟在try塊之後,不能單獨使用,在二者之間也不能插入其他語句。(3)try和catch塊中必須有用花括弧括起來的複合語句,即使花括弧內只有一個語句,也不能省略花括弧。(4)一個try-catch結構中只能有一個try塊,但卻可以有多個catch塊,以便與不同的異常信息匹配。(5)catch後面的圓括弧中,一般只寫異常信息的類型名,如:catch(double)。catch只檢查所捕獲異常信息的類型:異常信息可以是C++系統預定義的標準類型,也可以是用戶自定義的類型(如結構體或類)。如果由throw拋出的信息屬於該類型或其子類型,則catch與throw二者匹配,catch捕獲該異常信息。catch還可以有另外一種寫法,即除了指定類型名外,還指定變數名,如:catch(double d)。此時如果throw拋出的異常信息是double型的變數a,則catch在捕獲異常信息a的同時,還使d獲得a的值,或者說d得到a的一個拷貝。什麼時候需要這樣做呢?有時希望在捕獲異常信息時,還能利用throw拋出的值。(6)如果在catch子句中沒有指定異常信息的類型,而用了刪節號「…」,則表示它可以捕捉任何類型的異常信息,如:catch(…) {cout<<"OK"<<endl;},它能捕捉所有類型的異常信息,並輸出「OK」。(7)try-catch結構可以與throw出現在同一個函數中,也可以不在同一函數中。當throw拋出異常信息後,首先在本函數中尋找與之匹配的catch,如果在本函數中無try-catch結構或找不到與之匹配的catch,就轉到其上一層去處理,如果其上一層也無try-catch結構或找不到與之匹配的catch,則再轉到更上一層的try-catch結構去處理,也就是說轉到離開出現異常最近的try-catch結構去處理。(8)在某些情況下,在throw語句中可以不包括表達式。(9)如果throw拋出的異常信息找不到與之匹配的catch塊,那麼系統就會調用一個系統函數terminate,使程序終止運行。例2 在函數嵌套的情況下檢測異常處理。這是一個簡單的例子,用來說明在try塊中有函數嵌套調用的情況下拋出異常和捕捉異常的情況。#include <iostream>using namespace std;int main (){void f1 ();try{f1 ( ); //調用fl ()}catch (double){cout <<"OK0!"<<endl;}cout <<"end0"<<endl;return 0;}void f1 (){void f2 ();try{f2 (); //調用f2 ()}catch (char){cout <<"OK1!";}cout <<"end1"<<endl;}void f2 (){void f3 ();try{f3 (); //調用f3 ()}catch (int){cout <<"Ok2!"<<endl;}cout <<"end2"<<endl;}void f3 (){double a = 0;try{throw a; //拋出double類型異常信息}catch (float){cout<<"OK3!"<<endl;}cout<<"end3"<<endl;}分析運行情況:(1)如果將f3函數中的catch子句改為catch(double),而程序中其他部分不變,則f3函數中的throw拋出的異常信息立即被門函數中的catch子句捕獲(因為拋出的是double型異常,catch要捕捉的也是double型異常,二者匹配)。於是執行catch子句中的複合語句,輸出"OK3",再執行catch子句後面的語句,輸出"end3"。f3函數執行結束後,流程返回f2函數中調用f3函數處繼續往下執行。程序運行結果如下:OK31 (在f3函數中捕獲異常)end3 (執行f3函數中最後一個語句時的輸出)end2 (執行f2函數中最後一個語句時的輸出)endl (執行u函數中最後一個浯句時的輸出)endO (執行主函數中最後—個語句時的輸出)(2)如果在此基礎上再將f3函數中的catch塊改為catch(double){cout<<"OK3!"<<endl;throw;}f3函數中的catch子句捕獲throw拋出的異常信息a,輸出"OK3!"表示收到此異常信息,但它立即用"throw;」將a再拋出。由於a是double型,與f2和門函數中的catch都不匹配,因此最後被main函數中的catch子句捕獲。程序運行結果如下:OK3!(在f3函數中捕獲異常)OK0! (在主函數中捕獲異常)end0 (執行主函數中最後一個語句時的輸出)三、 在函數聲明中進行異常情況指定為了便於閱瀆程序,使用戶在看程序時能夠知道所用的函數是否會拋出異常信息以及異常信息可能的類型,C++允許在聲明函數時列出可能拋出的異常類型,如可以將例1中第二個程序的第3行改寫為:double triangle(double,double,double)throw(double);表示triangle函數只能拋出double類型的異常信息。如果寫成double triangle(double,double,double)throw(int,double,float,char);則表示triangle函數可以拋出int,double,float或char類型的異常信息。異常指定是函數聲明的一部分,必須同時出現在函數聲明和函數定義的首行中,否則在進行函數的另一次聲明時,編澤系統會報告「類型不匹配」。如果在聲明函數時未列出可能拋出的異常類型,則該函數可以拋出任何類型的異常信息。如例1中第2個程序中所表示的那樣。如果想聲明一個不能拋出異常的函數,可以寫成以下形式:double triangle(double,double,double) throw();//throw無參數這時即使在函數執行過程中出現了throw語句,實際上也並不執行throw語句,並不拋出任何異常信息,程序將非正常終止。四、 在異常處理中處理析構函數如果在try塊(或try塊中調用的函數)中定義了類對象,在建立該對象時要調用構造函數。在執行try塊(包括在try塊中調用其他函數)的過程中如果發生了異常,此時流程立即離開try塊(如果是在try塊調用的函數中發生異常,則流程首先離開該函數,回到調用它的try塊處,然後流程再從try塊中跳出轉到catch處理塊)。這樣流程就有可能離開該對象的作用域而轉到其他函數,因而應當事先做好結束對象前的請理工作,C++的異常處理機制會在throw拋出異常信息被catch捕獲時,對有關的局部對象進行析構(調用類對象的析構函數),析構對象的順序與構造的順序相反,然後執行與異常信息匹配的catch塊中的語句。例 在異常處理中處理析構函數。這是一個為說明在異常處理中調用析構函數的示例,為了請晰地表示流程,程序中加入了一些cout語句,輸出有關的信息,以便讀者對照結果分析程序。#include< iostream>#include <string>using namespace std;class Student{public:Student(int n,string nam)//定義構造函數{ cout<<"construtor-"<<n<<endl;num=n;name=nam;}~Student(){cout<<"destructor-"<<num<<endl;}//定義析構函數void get_data();//成員函數聲明private:int num;string name; };void Student::get_data()//定義成員函數{if(num==0) throw num;//如num=O,拋出int型變數numelse cout<<num<<" "<<name<<endl;//若num不等O,輸出num,namecout<<"in get_data()"<<endl;//輸出信息,表示目前在fet_data函數中}void fun()//過程函數(注意可見性){Student stud1(1101,"tan");//建立對象studlstud1.get_data();//調用studl的getdata函數Student stud2(0,"Li");//建立對象stud2stud2.get_data();}//調用smd2的get data函數int main(){cout<<"main begin"<<endl;//表示主函數開始了cout<<"call fun()"<<endl;//表示調用fun函數try{fun();}//調用fun函數catch(int n){cout<<"num="<<n<<",error!"<<endl;}//表示num=0出錯cout<<"main end"<<endl;//表示主函數結束return 0; }分析程序執行過程,程序運行結果如下:main begiincall fun()constructor-110l//對立Student類對象stud1,num=1101110l tan//對象stud1調用Student類的成員函數get_data,num不等Oin get_data()//執行get_dataconstructor-0//建立Student類對象stud2,num=0,拋出num.destructor-O//調用Student類對象stud1的析構函數destructor-1101//調用Student類對象stud2的析構函數num=O,error!//表示num=0出錯。main end//表示主函數結束2.21.4 VC編譯器異常選項#include <stdio.h>void main (){char *a;try{a = 0;(*a) = 0;}catch(...){printf("oops,exception!!
");}}這段代碼的運行結果是什麼?你一定會說:"屏幕上打出oops,exception!!
"。沒錯,理論上的確是這樣。我們來驗證一下,用vc6產生一個空的win32 console工程,加入上面的cpp文件,debug方式編譯後,得到如期的結果,但是!release方式編譯後,仍然出現了"訪問衝突"!這如何解釋?本怪獸經調查發現,VC里缺身編譯選項里關於異常的選項是/GX,文檔里說,這等價與/EHs--同步異常捕捉。何解?答:只有編譯器認為有可能出異常的情況下,即有throw出現的情況下,編譯器才會生成異常捕捉代碼。據說是VC6的一項新優化功能,真是自作聰明!誰會希望這樣的"異常捕捉"?解決方法,去掉/GX,加上/EHa--非同步異常捕捉。這樣可以保證異常捕捉代碼不被"高明"的編譯器優化掉。那為何開頭的例子里,debug版本運行正常呢?答:debug版本不做優化。故正常也。這是VC6 IDE里非常莫名其妙的地方,用try catch的人請一定小心。---------------------------------------------------------------------------------------------------在【屬性】-》【C/C++】-》【代碼生成】-》【啟用C++異常】有如下4個選項,點擊組合框,顯示:否是(/EHsc)是,但有 SEH 異常(/EHa)<從父級或項目默認設置繼承>1、如果不選擇【是,但有 SEH 異常(/EHa)】選項,try { } catch(...) { } 不起作用。新建項目預設值是【是(/EHsc)】。就是說在預設情況下微軟不支持標準C++。2、微軟自己又弄出:__try { } __except(EXCEPTION_EXECUTE_HANDLER) { }。【啟用C++異常】選項對此不起作用,選什麼都起作用。建議不要使用。還是使用標準的吧。3、微軟還弄出:TRY{}CATCH_ALL(e) {}END_CATCH_ALL不知為什麼還弄。可能微軟的開發人員那天還得弄。總結:掌握第1種方法就足夠了,其實也不應該出現其他方法。如果你的是在從API封裝類,建議還是用第2種方法,可能你的類要應用到很多項目,那個項目是否選擇了【是,但有 SEH 異常(/EHa)】就很難說了,可能那個程序員根本就沒有注意到【是,但有 SEH 異常(/EHa)】選項,使用第1種方法會使你的異常失效。但我又覺得__try { }實在不是個東西,看著彆扭。2.21.5 捕獲所有未捕獲的異常從名字上就可以看出SetUnhandledExceptionFilter()函數的作用就是設置未捕獲異常的捕獲函數,程序崩潰就是因為有些異常我們沒有捕獲,而當這些異常我們沒捕獲時,系統就會調用SetUnhandledExceptionFilter設置的函數,在此函數中可以進行一些操作,比如彈出對話框、列印語句等。如果沒有設置未捕獲異常的捕獲函數,那麼系統就會調用默認的未捕獲異常的捕獲函數,比如彈出調試對話框、顯示內存讀寫錯誤對話框、等等。未捕獲異常的捕獲函數的返回值:EXCEPTION_EXECUTE_HANDLER equ 1 表示我已經處理了異常, 進程可以結束了EXCEPTION_CONTINUE_SEARCH equ 0 表示我不處理,其他人來吧,於是windows調用默認的未捕獲異常的捕獲函數,然後顯示一個錯誤框,並結束EXCEPTION_CONTINUE_EXECUTION equ -1 表示錯誤已經被修復,請從異常發生處繼續執行具體使用方法如下://未捕獲異常的捕獲函數LONG WINAPI MyUnhandledExceptionFilter (struct _EXCEPTION_POINTERS * pExp){cout <<"UnhandledException!!!"<<endl;return EXCEPTION_EXECUTE_HANDLER;//返回異常已經處理,並可以結束進程的標記}int main (){cout <<"begin!"<<endl;SetUnhandledExceptionFilter (MyUnhandledExceptionFilter);int i = 0;i = i / i;cout <<"end!"<<endl;getch ();return 0;}2.21.6 SetErrorMode(未完成)函數名稱SetErrorMode頭文件#include <Windows.h>庫文件#pragma comment(lib, "Kernel32.lib")函數功能設置錯誤處理方式,選擇是否讓操作系統處理指定類型的嚴重錯誤,還是讓調用進程來處理它們。函數聲明UINT WINAPI SetErrorMode (UINT uMode);函數參數uMode,[輸入]:存放要讓操作系統處理哪些類型的嚴重錯誤,可以為(用"|"選零至多個):0:使用系統默認的,既讓操作系統處理所有錯誤。SEM_FAILCRITICALERRORS(0x0001):如果設置本標記,表示不讓系統處理關鍵錯誤,讓調用進程來處理。如果不設置本標記,表示要讓系統處理關鍵錯誤,不讓調用進程來處理。系統會自動彈出一個對話框來讓用戶選擇如何處理。SEM_NOALIGNMENTFAULTEXCEPT(0x0004):如果設置本標記,表示The system automatically fixes memory alignment faults and makes them invisible to the application. It does this for the calling process and any descendant processes. This feature is only supported by certain processor architectures. For more information, see the Remarks section.After this value is set for a process, subsequent attempts to clear the value are ignored.不建議設置本標記。SEM_NOGPFAULTERRORBOX(0x0002):如果設置本標記,表示不讓系統顯示Windows錯誤報告對話框。如果不設置本標記,表示要讓系統顯示Windows錯誤報告對話框。系統會自動彈出一個錯誤報告對話框來讓用戶選擇如何處理,對話框截圖:SEM_NOOPENFILEERRORBOX(0x8000)如果設置本標記,表示不讓系統處理無法找到文件時的錯誤,讓調用進程來處理。如果不設置本標記,表示要讓系統處理無法找到文件時的錯誤。系統會自動彈出一個對話框來讓用戶選擇如何處理。例如試圖從一個沒有軟盤的軟碟機中讀數據。返回值返回值1:返回值說明。返回值2:返回值說明。……錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是 或 否 或 未知,表示此函數多線程調用是否會產生影響原子操作是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合其他說明…………2.22 錯誤碼2.22.1 GetLastError函數名稱GetLastError頭文件#include <windows.h>函數功能獲取本線程最近一次調用系統函數的錯誤碼,多線程互不影響。因為使用的線程局部變數來存放錯誤碼。函數聲明DWORD GetLastError (void);函數參數無返回值本線程最近一次的錯誤碼。錯誤碼無線程安全是原子操作是其他說明可以使用FormatMessage()函數獲取錯誤碼對應的信息字元串。2.22.2 FormatMessage(未完成)函數名稱FormatMessage頭文件#include <Windows.h>函數功能根據GetLastError()函數返回的錯誤碼,獲取此錯誤碼對應的錯誤信息字元串存放在指定內存。函數聲明DWORD FormatMessage (DWORD dwFlags,LPCVOID lpSource,DWORD dwMessageId,DWORD dwLanguageId,LPSTR lpBuffer,DWORD nSize,va_list * Arguments);函數參數dwFlags,[輸入]:可以是(用"|"選一至多個):FORMAT_MESSAGE_FROM_SYSTEM:在系統id映射表中查找錯誤信息字元串。FORMAT_MESSAGE_FROM_HMODULE:在其他資源模塊中查找錯誤信息字元串。此標記不能和FORMAT_MESSAGE_FROM_STRING標記同時使用。FORMAT_MESSAGE_FROM_STRING:lpSource參數是一個指向以NULL結尾的字元串,字元串包含一個消息定義,這個消息定義可以包含插入序列。此標誌最好不要和FORMAT_MESSAGE_FROM_HMODULE或者FORMAT_MESSAGE_FROM_SYSTEM使用。此標記不能和FORMAT_MESSAGE_FROM_HMODULE標記同時使用。FORMAT_MESSAGE_ALLOCATE_BUFFER:要此函數會自動分配內存來存放錯誤信息字元串,而不是自己指定。FORMAT_MESSAGE_IGNORE_INSERTS:在消息定義中的插入序列將會被忽略,也就是忽略Arguments參數。FORMAT_MESSAGE_ARGUMENT_ARRAY:Arguments參數不是一個va_list結構,它表示一個數組指針。這個標識符不能在64位整數值時使用,你如果要使用64位整數值,那麼你必須使用va_list結構體。lpSource,[輸入]:如果dwFlags參數指定了FORMAT_MESSAGE_FROM_HMODULE標記,本參數表示模塊句柄。如果dwFlags參數指定了FORMAT_MESSAGE_FROM_STRING標記,本參數表示id字元串。其他情況本參數無意義,必須為NULL。dwMessageId,[輸入]:存放GetLastError()函數返回的錯誤碼。如果dwFlags參數指定FORMAT_MESSAGE_FROM_STRING標記,則本參數無意義,必須為NULL。dwLanguageId,[輸入]:錯誤信息字元串所用的語言,為0表示系統自動選擇。lpBuffer,[輸入]:存放錯誤信息字元串的內存指針,但是如果dwFlags指定了FORMAT_MESSAGE_ALLOCATE_BUFFER,系統會調用LocalAlloc()函數自動分配內存,本參數就為存放該內存指針的指針變數的內存指針,用戶需要記住調用LocalFree()函數釋放該內存。nSize,[輸入]:存放錯誤信息字元串的內存長度,但是如果dwFlags指定了FORMAT_MESSAGE_ALLOCATE_BUFFER,本參數就為系統自動分配的內存的最小長度。Arguments,[輸入]:未知,必須為NULL。返回值非0:存放在內存的錯誤信息字元串的長度。0:失敗,調用GetLastError()函數查看錯誤碼。錯誤碼EXXXX:錯誤碼說明。EXXXX:錯誤碼說明。……線程安全是原子操作是其他說明lpSource參數如果是模塊句柄,可以調用LoadLibraryEx ("DLL文件名", NULL, LOAD_LIBRARY_AS_DATAFILE)函數獲取。lmerr.h、netmsg.dll模塊包含NERR_BASE(2100)至MAX_NERR(2999)的錯誤碼對應的信息字元串。wininet.h、wininet.dll模塊包含INTERNET_ERROR_BASE(12000)至INTERNET_ERROR_LAST(12175)的錯誤碼對應的信息字元串。pdhmsg.h、pdh.dll模塊包含PDH_CSTATUS_VALID_DATA(0)至PDH_CSTATUS_NEW_DATA(1)、PDH_CSTATUS_NO_MACHINE(2147485648)至PDH_QUERY_PERF_DATA_TIMEOUT(3221228542)的錯誤碼對應的信息字元串。系統id映射表包含WSA錯誤碼10000至11999、IPSec錯誤碼13000至13999、Side By Side錯誤碼14000至14999、WinEvt錯誤碼15000至15079、Wecsvc錯誤碼15080至15099、MUI錯誤碼15100至15199、Monitor Configuration API錯誤碼15200至15249、Syspart錯誤碼15250至15299、Vortex錯誤碼15300至15320、及其他的錯誤碼對應的信息字元串。3 類庫3.1 類模板3.2 list3.2.1 list類簡介list類是一種可在常數時間內在任何位置執行插入元素和刪除元素操作的順序容器。list類是雙向鏈表,其迭代器是雙向的。list類變數可以在任意位置高效執行插入、提取、和移動元素的操作,但它不能通過在list類變數中的位置直接操作元素。頭文件:#include <list>assign() 給list賦值front() 返回第一個元素back() 返回最後一個元素begin() 返回指向第一個元素的迭代器end() 返回最後一個元素的下一個元素的迭代器,其實就是NULL,用於表示鏈表結束。clear() 刪除所有元素empty() 判斷本類變數有沒有元素,如果有,則返回true,如果沒有,則返回false。erase() 刪除一個元素get_allocator() 返回list的配置器insert() 插入一個元素max_size() 返回list能容納的最大元素數量merge() 合併兩個listpop_back() 刪除最後一個元素pop_front() 刪除第一個元素push_back() 在list的末尾添加一個元素push_front() 在list的頭部添加一個元素rbegin() 返回指向第一個元素的逆向迭代器remove() 從list刪除元素remove_if() 按指定條件刪除元素rend() 指向list末尾的逆向迭代器resize() 改變list的大小reverse() 把list的元素倒轉size() 返回list中的元素個數sort() 給list排序splice() 合併兩個listswap() 交換兩個listunique() 刪除list中重複的元素3.3 map關聯容器與順序容器關聯容器通過鍵(key)存儲和讀取元素,而順序容器則通過元素在容器中的位置順序存儲和訪問元素。關聯容器(Associative containers)支持通過鍵來高效地查找和讀取元素。兩個基本的關聯容器類型是 map 和 set。 其中map 的元素以鍵-值(key-value)對的形式組織:鍵用作元素在 map 中的索引,而值則表示所存儲和讀取的數據。set 僅包含一個鍵,並有效地支持關於某個鍵是否存在的查詢。關聯容器類型一般來說,如果希望有效地存儲不同值的集合,那麼使用set容器比較合適,而map容器則更適用於需要存儲(乃至修改)每個鍵所關聯的值的情況。在做某種文本處理時,可使用set保存要忽略的單詞。而字典則是map的一種很好的應用:單詞本身是鍵,而它的解釋說明則是值。set和map類型的對象所包含的元素都具有不同的鍵,不允許為同一個鍵添加第二個元素。如果一個鍵必須對應多個實例,則需使用multimap或multi set,這兩種類型允許多個元素擁有相同的鍵。C++ Primer Plus 第6版 中文版 清晰有書籤PDF+源代碼http://www.linuxidc.com/Linux/2014-05/101227.htm讀C++ Primer 之構造函數陷阱http://www.linuxidc.com/Linux/2011-08/40176.htm讀C++ Primer 之智能指針http://www.linuxidc.com/Linux/2011-08/40177.htm讀C++ Primer 之句柄類http://www.linuxidc.com/Linux/2011-08/40175.htm將C語言梳理一下,分布在以下10個章節中:Linux-C成長之路(一):Linux下C編程概要http://www.linuxidc.com/Linux/2014-05/101242.htmLinux-C成長之路(二):基本數據類型http://www.linuxidc.com/Linux/2014-05/101242p2.htmLinux-C成長之路(三):基本IO函數操作http://www.linuxidc.com/Linux/2014-05/101242p3.htmLinux-C成長之路(四):運算符http://www.linuxidc.com/Linux/2014-05/101242p4.htmLinux-C成長之路(五):控制流http://www.linuxidc.com/Linux/2014-05/101242p5.htmLinux-C成長之路(六):函數要義http://www.linuxidc.com/Linux/2014-05/101242p6.htmLinux-C成長之路(七):數組與指針http://www.linuxidc.com/Linux/2014-05/101242p7.htmLinux-C成長之路(八):存儲類,動態內存http://www.linuxidc.com/Linux/2014-05/101242p8.htmLinux-C成長之路(九):複合數據類型http://www.linuxidc.com/Linux/2014-05/101242p9.htmLinux-C成長之路(十):其他高級議題注意:關聯容器根據鍵排列元素!所以,在迭代遍歷訪問容器時,是按照鍵的順序訪問元素,而與元素在容器中的存放位置無關!3.3.1 基礎pair類型在utility頭文件定義。3.3.2 map類型3.3.2.1 map類型的定義map 是鍵-值對的集合。map 類型通常可理解為關聯數組(associative array):可使用鍵作為下標來獲取一個值,正如內置數組類型一樣。而關聯的本質在於元素的值與某個特定的鍵相關聯,而並非通過元素在數組中的位置來獲取。map對象的構造函數即定義方法:在實際應用中,鍵類型必須定義 < 操作符,比如list<> 容器的類型則不能作為鍵。在使用關聯容器時,它的鍵不但有一個類型,而且還有一個相關的比較函數。 所用的比較函數必須在鍵類型上定義嚴格弱排序(strict weak ordering)。所謂的嚴格弱排序可理解為鍵類型數據上的「小於」關係。當用於一個鍵與自身的比較時,肯定會導致 false 結果。如果它們相互之間都不存在「小於」關係,則容器將之視為相同的鍵。用做 map 對象的鍵時,可使用任意一個鍵值來訪問相應的元素。這與下面的添加元素時行為有一定的對應3.3.2.2 map定義的類型其中:其value_type是存儲元素的鍵以及值的pair類型,而且鍵為const。// count number of times each word occurs in the inputmap<string, int> word_count; // empty map from string to int// get an iterator to an element in word_countmap<string, int>::iterator map_it = word_count.begin(); // *map_it is a reference to a pair<const string, int> objectcout << map_it->first; // prints the key for this elementcout << " " << map_it->second; // prints the value of the elementmap_it->first = "new key"; <span style="color: rgb(255, 0, 0);"><strong>// error: key is const</strong></span>++map_it->second; // ok: we can change value through an iterator對迭代器進行解引用將獲得一個pair對象,其first成員具有constmap<K, V>::key_type 類型即存放鍵,而 second成員則為map<K,V>::mapped_type 類型,即存放值。3.3.2.3 map元素添加3.3.2.3.1 一、下標添加當編寫以下代碼時:map <string, int> word_count; // empty map// insert default initialzed element with key Anna; then assign 1 to its valueword_count["Anna"] = 1;將發生:1.在 word_count 中查找鍵為 Anna 的元素,沒有找到。2.將一個新的鍵-值對插入到 word_count 中。它的鍵是 const string 類型的對象,保存 Anna。而它的值則採用值初始化,這就意味著在本例中值為 0。3.將這個新的鍵-值對插入到 word_count 中。4.讀取新插入的元素,並將它的值賦為 1。使用下標訪問 map 與使用下標訪問數組或 vector 的行為截然不同:用下標訪問不存在的元素將導致在 map 容器中添加一個新元素,它的鍵即為該下標值。PS:下標操作符返回值的使用通常來說,下標操作符返回左值。它返回的左值是特定鍵所關聯的值。可如下讀或寫元素:// count number of times each word occurs in the inputmap<string, int> word_count; // empty map from string to intstring word;while (cin >> word)++word_count[word];3.3.2.3.2 二、insert添加map上的insert操作1.添加元素// if Anna not already in word_count,inserts new element with value 1word_count.insert(map<string, int>::value_type("Anna", 1));上面語句的實參可以簡化如下兩種方法:(1)word_count.insert(make_pair("Anna", 1));(2)使用 typedeftypedef map<string,int>::value_type valType;word_count.insert(valType("Anna", 1));2、insert的返回值There can be only one element with a given key in a map. If we attempt to insert an element with a key that is already in the map, then insert does nothing. The versions of insert that take an iterator or iterator pair do not indicate whether or how many elements were inserted.但是,帶有一個鍵-值 pair 形參的 insert 版本將返回一個值:包含一個迭代器和一個 bool 值的 pair 對象,其中迭代器指向 map 中具有相應鍵的元素,而 bool 值則表示是否插入了該元素。如果該鍵已在容器中,則其關聯的值保持不變,返回的 bool 值為 false。在這兩種情況下,迭代器都將指向具有給定鍵的元素。3.3.2.4 查找以及讀取map中的元素3.3.2.4.1 一、下標讀取map<string,int> word_count;int occurs = word_count["foobar"];但是:使用下標存在一個很危險的副作用:如果該鍵不在 map 容器中,那麼下標操作會插入一個具有該鍵的新元素。3.3.2.5 二、不修改map對象的查詢操作(1) m.count(k);返回 m 中 k 的出現次數(2) m.find(k); 如果 m 容器中存在按 k 索引的元素,則返回指向該元素的迭代器。如果不存在,則返回超出末端迭代器-----使用count檢查對象總某鍵是否存在對於 map 對象,count 成員的返回值只能是 0 或 1。map 容器只允許一個鍵對應一個實例,所以 count 可有效地表明一個鍵是否存在。如果返回值非 0,則可以使用下標操作符來獲取該鍵所關聯的值,而不必擔心這樣做會在map中插入新元素:int occurs = 0;if (word_count.count("foobar"))occurs = word_count["foobar"];當然,在執行 count 後再使用下標操作符,實際上是對元素作了兩次查找。如果希望當元素存在時就使用它,則應該用 find 操作。-----讀取元素而不插入該元素find操作返回指向元素的迭代器,如果元素不存在,則返回 end 迭代器:如果希望當具有指定鍵的元素存在時,就獲取該元素的引用,否則就不在容器中創建新元素,那麼應該使用 find。3.3.3 刪除map元素3.3.4 遍歷map對象map同樣提供begin和end運算。以生成遍歷整個元素的迭代器ok,that`s all .3.3.5 實際程序演練一、單詞統計代碼一:// 建立一個map對象,保存所讀入的單詞及其出現的次數(以單詞為鍵,對應的值為單詞出現的次數)// 利用下標添加元素#include <iostream>#include <map>#include <string>using namespace std;// 2013.11.18 Written by C_SuooL_Huint main(){// freopen("in.txt","r",stdin);// freopen("out.txt","w",stdout);map<string, int> wordCount;typedef map<string, int> ::iterator valType;string word;// 讀入單詞並統計次數cout << "Enter some words (Ctrl + Z to end):" << endl;while (cin >> word){// 如果讀入的word存在在容器中,則使鍵值為word的值++,否則添加以此元素為索引的鍵,然後鍵值初始化為0,後++,即為1.++wordCount[word];}// 輸出結果,用迭代器cout << "word " << "times" << endl;for (valType iter = wordCount.begin(); iter != wordCount.end(); ++iter){cout << (*iter).first << " " << (*iter).second << endl;}return 0;}代碼二:#include <iostream>#include <map>#include <string>using namespace std;< /span><pre style="line-height: 24.5px;" class="cpp" name="code">// 2013.11.18 Written by C_SuooL_Hu</pre>// mapint main() { freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); // count number of times each word occurs in the input map<string, int> word_count;// empty map from string to int typedef map<string, int> ::iterator valType; string word; while (cin >> word) { // inserts element with key equal to word and value 1; // if word already in word_count, insert does nothing pair<map<string, int>::iterator, bool>ret =word_count.insert(make_pair(word, 1)); if (!ret.second) // word already in word_count ++ret.first->second; // increment counter }// outputcout << "word " << "times" << endl;for (valType iter = word_count.begin(); iter != word_count.end(); ++iter){cout<< (*iter).first << " " << (*iter).second<< endl;}return 0;}運行結果:有圖可知,用迭代器輸出的時候,按照字典序輸出。3.3.6 二、單詞轉換器(轉換解碼)代碼有點丑,輸入輸出IO庫還很需要加強。。。對文件的操作基本是文盲。。#include <map>#include <vector>#include <iostream>#include <fstream>#include <string>#include <sstream>// 2013.11.18 Written by C_SuooL_Huusing namespace std;ifstream& open_file(ifstream&, const string&);int main(){freopen("out.txt", "w", stdout);// map to hold the word transformation pairs:// key is the word to look for in the input; value is word to use in the outputmap<string, string> trans_map;string key, value;// ′′?¨á÷ifstream myfile ("trans_map.txt");ifstream myfilein ("in.txt");ofstream outfile("out.txt");// ?D?????tê?·?′ò?aif(!myfile){cout << "Unable to open myfile";exit(1); // terminate with error}if(!outfile){cout << "Unable to open outfile";exit(1); // terminate with error}// read the transformation map and build the mapwhile (myfile >> key >> value){trans_map.insert(make_pair(key, value));}// this block just produces the vector so that we can print it// for the bookcout << "Here is our transform string input:
";// read some text to transformstring word;// ok, now we"re ready to do the transformations// open the input file and check that the open succeededstring WORD;bool firstword = true; // controls whether a space is printedwhile (myfilein >> WORD){// ok: the actual mapwork, this part is the heart of the programmap<string, string>::const_iterator map_it =trans_map.find(WORD);// if this word is in the transformation mapif (map_it != trans_map.end()){// replace it by the transformation value in the mapWORD = map_it->second;}if (firstword)firstword = false;elsecout << " "; // print space between wordscout << WORD;}cout << endl; // done with this line of inputreturn 0;}測試結果:4 結構體庫4.1 結構體模板(未完成)結構體名稱xxx頭文件#include <xxx.h>#include <xxx.h>結構體稱呼結構體的中文稱呼。結構體說明結構體主要用途說明。相關函數Func1()、Func2()、Func3()…結構體聲明struct xxx{類型 成員變數1;類型 成員變數2;……};成員變數成員變數1:成員變數說明。成員變數2:成員變數說明。……其他說明…………4.2 套接字4.2.1 sockaddr頭文件 :#include< linux/socket.h>結構體名稱:sockaddr結構體說明:結構體主要使用說明。結構體聲明:struct sockaddr{sa_family_t sa_family; /* address family, AF_xxx */char sa_data[14]; /* 14 bytes of protocol address */};成員變數 :sa_family:IP地址的地址族,用AF_xxx定義的sa_data:協議的地址數據,佔14個位元組的注意事項 :……4.2.2 sockaddr_in頭文件 :#include< netinet/in.h>結構體名稱:sockaddr_in結構體說明:一般用於對IPv4的地址信息的說明。結構體聲明:struct sockaddr_in{__SOCKADDR_COMMON (sin_);in_port_t sin_port; /* Port number. */struct in_addr sin_addr; /* Internet address. *//* Pad to size of `struct sockaddr". */unsigned char sin_zero[sizeof (struct sockaddr) -__SOCKADDR_COMMON_SIZE -sizeof (in_port_t) -sizeof (struct in_addr)];};成員變數 :sin_port:存放埠號。sin_addr:存放IP地址。sin_zero:填充數據,為了佔滿14個位元組,無實際意義。注意事項 :…………4.2.3 sockaddr_in6頭文件 :#include< netinet/in.h>結構體名稱:sockaddr_in6結構體說明:一般用於對IPv6的地址信息的說明。結構體聲明:struct sockaddr_in6{__SOCKADDR_COMMON (sin6_);in_port_t sin6_port; /* Transport layer port # */uint32_t sin6_flowinfo; /* IPv6 flow information */struct in6_addr sin6_addr; /* IPv6 address */uint32_t sin6_scope_id; /* IPv6 scope-id */};成員變數 :sin6_port:成員變數說明。sin6_flowinfo:成員變數說明。sin6_addr:sin6_scope_id:注意事項 :…………4.3 軟硬體設備4.3.1 通用4.3.1.1 SYSTEM_PROCESS_INFORMATION(未完成)結構體名稱SYSTEM_PROCESS_INFORMATION頭文件#include <Winternl.h>結構體說明存放系統中各個進程的相關信息。相關函數NtQuerySystemInformation()、Func2()、Func3()…結構體聲明struct SYSTEM_PROCESS_INFORMATION{ULONG NextEntryOffset;BYTE Reserved1[52];PVOID Reserved2[3];HANDLE UniqueProcessId;PVOID Reserved3;ULONG HandleCount;BYTE Reserved4[4];PVOID Reserved5[11];SIZE_T PeakPagefileUsage;SIZE_T PrivatePageCount;LARGE_INTEGER Reserved6[6];}成員變數NextEntryOffset:存放下一個進程信息結構體的起始位置指針相對本結構體的起始位置指針的偏移長度,單位位元組。如果本參數為0,表示本結構體就為最後一個,沒有下一個了。Reserved1:保留參數,其實並不是沒有用到,只是微軟隱藏了而已。Reserved2:保留參數,其實並不是沒有用到,只是微軟隱藏了而已。UniqueProcessId:存放進程的全局唯一ID。Reserved3:保留參數,其實並不是沒有用到,只是微軟隱藏了而已。HandleCount:存放進程的句柄數。Reserved4:保留參數,其實並不是沒有用到,只是微軟隱藏了而已。Reserved5:保留參數,其實並不是沒有用到,只是微軟隱藏了而已。PeakPagefileUsage:存放進程的虛擬內存使用大小峰值,單位位元組,有待考證。PrivatePageCount:存放進程的提交大小,單位位元組,也就是進程動態申請的內存的理論長度。Reserved6:保留參數,其實並不是沒有用到,只是微軟隱藏了而已。其他說明4.3.1.2 _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION結構體名稱_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION頭文件#include <Winternl.h>結構體說明存放每個CPU處理器核心的相關信息。相關函數NtQuerySystemInformation()、Func2()、Func3()…結構體聲明typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION{LARGE_INTEGER IdleTime;LARGE_INTEGER KernelTime;LARGE_INTEGER UserTime;LARGE_INTEGER Reserved1[2];ULONG Reserved2;} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;成員變數IdleTime:存放CPU處理器核心的空閑時間。KernelTime:存放CPU處理器核心的內核時間。UserTime:存放CPU處理器核心的用戶時間。Reserved1:保留參數,其實並不是沒有用到,只是微軟隱藏了而已。Reserved2:保留參數,其實並不是沒有用到,只是微軟隱藏了而已。其他說明4.3.2 CPU處理器4.3.3 內存4.3.3.1 MEMORYSTATUS(未完成)結構體名稱MEMORYSTATUS頭文件#include <WinBase.h>結構體說明存放物理內存和虛擬內存的相關信息。相關函數GlobalMemoryStatus()結構體聲明struct MEMORYSTATUS{DWORD dwLength;DWORD dwMemoryLoad;SIZE_T dwTotalPhys;SIZE_T dwAvailPhys;SIZE_T dwTotalPageFile;SIZE_T dwAvailPageFile;SIZE_T dwTotalVirtual;SIZE_T dwAvailVirtual;};成員變數dwLength:存放本結構體佔用位元組大小。本參數由GlobalMemoryStatus()函數自動設置,無需事先設置。dwMemoryLoad:存放物理內存的使用率,單位百分比,數值大於等於0,小於等於100。0表示沒有使用任何內存,100表示使用了全部內存。dwTotalPhys:存放物理內存總大小,單位位元組。如果物理內存總大小超過4GB,本參數將一直為4GB。dwAvailPhys:存放物理內存剩餘可用大小,單位位元組。如果物理內存剩餘可用大小超過4GB,本參數將一直為4GB。dwTotalPageFile:存放虛擬內存的頁面文件總大小,單位位元組。本參數並不表示頁面文件在磁碟上的實際文件大小。如果物理內存剩餘可用大小超過4GB,本參數將一直為4GB。dwAvailPageFile:存放當前調用進程對頁面文件的最大可用大小,單位位元組。本參數應該小於頁面文件剩餘可用大小。如果當前調用進程對頁面文件的最大可用大小超過4GB,本參數將一直為4GB。dwTotalVirtual:存放當前調用進程的虛擬地址空間的用戶空間的總大小,以位元組為單位。本參數與CPU硬體性能參數及操作系統有關,例如,該值約為2 GB的在x86處理器上大多數32位進程和大約3 GB的32位進程是大地址識別運行的系統上4 GT RAM微調功能。如果當前調用進程的虛擬地址空間的用戶空間的總大小超過4GB,本參數將一直為4GB。dwAvailVirtual:存放當前調用進程的虛擬地址空間的用戶空間的剩餘可用大小,以位元組為單位。如果當前調用進程的虛擬地址空間的用戶空間的剩餘可用大小超過4GB,本參數將一直為4GB。其他說明本結構體只能獲取內存大小不超過4GB的相關信息,如果要獲取內存大小超過4GB的相關信息,可以調用GlobalMemoryStatusEx()函數。4.4 網路設備4.4.1 MIB_IFROW結構體名稱MIB_IFROW頭文件#include <Iphlpapi.h>結構體說明存放網路設備的狀態信息,包括名稱、索引序號、類型、最大傳輸單元、傳輸速度、物理地址、管理狀態、操作狀態、輸入輸出流量記錄、描述。相關函數GetIfTAble()結構體聲明struct MIB_IFROW{WCHAR wszName[MAX_INTERFACE_NAME_LEN];IF_INDEX dwIndex;IFTYPE dwType;DWORD dwMtu;DWORD dwSpeed;DWORD dwPhysAddrLen;UCHAR bPhysAddr[MAXLEN_PHYSADDR];DWORD dwAdminStatus;INTERNAL_IF_OPER_STATUS dwOperStatus;DWORD dwLastChange;DWORD dwInOctets;DWORD dwInUcastPkts;DWORD dwInNUcastPkts;DWORD dwInDiscards;DWORD dwInErrors;DWORD dwInUnknownProtos;DWORD dwOutOctets;DWORD dwOutUcastPkts;DWORD dwOutNUcastPkts;DWORD dwOutDiscards;DWORD dwOutErrors;DWORD dwOutQLen;DWORD dwDescrLen;UCHAR bDescr[MAXLEN_IFDESCR];};成員變數wszName:存放網路設備的唯一GUID名稱字元串。dwIndex:存放網路設備的唯一索引序號,可以使用route print命令的介面列表查看。dwType:存放網路設備的類型,可以為:IF_TYPE_OTHER(1):其他的網路設備。IF_TYPE_ETHERNET_CSMACD(6):乙太網網路設備。IF_TYPE_ISO88025_TOKENRING(9):令牌環網網路設備。IF_TYPE_FDDI(15):FDDI光纖分散式數據介面(Fiber Distributed-Data Interface)網路設備。IF_TYPE_PPP(23):PPP點對點協議(Point to Point Protocol)網路設備。IF_TYPE_SOFTWARE_LOOPBACK(24):軟體迴環網路介面。IF_TYPE_SLIP(28):串列適配器(Serial Line Interface Protocol)。IF_TYPE_ATM(37):非同步傳輸模式(Asynchronous Transfer Mode)網路設備。IF_TYPE_IEEE80211(71):基於IEEE 802.11標準的無線網路設備。IF_TYPE_TUNNEL(131):隧道式封裝(Tunnel-encapsulated)網路設備。IF_TYPE_IEEE1394(144):基於IEEE 1394(火線)高性能串列匯流排的網路設備。IF_TYPE_IEEE80216_WMAN(237):基於WiMax全球微波互聯接入 (Worldwide Interoperability for Microwave Access)的移動網路設備。注意:只有Windows7和Windows Server2008R2及以後的系統支持此類型設備。IF_TYPE_WWANPP(243):基於GSM全球移動通信系統(Global System for Mobile communication)標準的移動網路設備。注意:只有Windows7和Windows Server2008R2及以後的系統支持此類型設備。IF_TYPE_WWANPP2(244):基於CDMA碼分多址技術的移動網路設備。注意:只有Windows7和Windows Server2008R2及以後的系統支持此類型設備。dwMtu:存放網路設備的最大傳輸單元的長度,單位位元組。dwSpeed:存放網路設備的最大傳輸速率,單位比特位每秒。有些設備是以1000為進位單位的,有些是以1024為進位單位的,表示不一樣,但實際意思都是一樣的,例如:1000Mbps的速率,本參數可能為1000*1000*1000=1000000000 bps,也可能為1024*1024*1024=1073741824 bps。dwPhysAddrLen:存放bPhysAddr參數的使用長度,單位位元組。bPhysAddr:存放網路設備的MAC物理地址。dwAdminStatus:存放網路設備的管理狀態,1表示啟用,2表示禁用。管理狀態是指通過控制面板的網路和共享中心等方式對該網路設備進行管理。dwOperStatus:存放網路設備的操作狀態。可以為:IF_OPER_STATUS_NON_OPERATIONAL(0):LAN區域網適配器已被禁用,例如:地址衝突。IF_OPER_STATUS_UNREACHABLE(1):WAN廣域網適配器未連接。IF_OPER_STATUS_DISCONNECTED(2):對於LAN區域網適配器,表示網路電纜斷開。對於WAN廣域網適配器,表示無信號。IF_OPER_STATUS_CONNECTING(3):WAN廣域網適配器正在進行連接。IF_OPER_STATUS_CONNECTED(4):WAN廣域網適配器已經連接到遠端對等網路。IF_OPER_STATUS_OPERATIONAL(5):LAN區域網適配器的默認狀態,例如:已經連接。dwLastChange:存放網路設備的已進入當前操作狀態了多久,單位百分之一秒。操作狀態就是dwOperStatus成員變數所指示的操作狀態。當系統重新啟動,或本參數達到2^32後,本參數清0。dwInOctets:存放網路設備的累計輸入流量,單位位元組。dwInUcastPkts:存放網路設備的輸入包的累計個數。dwInNUcastPkts:存放網路設備的輸入包的累計非單播個數。非單播是指廣播和多播。dwInDiscards:存放網路設備的輸入包的累計丟棄個數。丟棄原因可能是錯誤的,或者重複的,或者協議未知,等等。dwInErrors:存放網路設備的輸入包的累計因錯誤丟棄個數。dwInUnknownProtos:存放網路設備的輸入包的累計因協議未知丟棄個數。dwOutOctets:存放網路設備的累計輸出流量,單位位元組。dwOutUcastPkts:存放網路設備的輸出包的累計個數。dwOutNUcastPkts:存放網路設備的輸入包的累計非單播個數。非單播是指廣播和多播。dwOutDiscards:存放網路設備的輸出包的累計丟棄個數。丟棄原因可能是錯誤的,或者重複的,或者協議未知,等等。dwOutErrors:存放網路設備的輸出包的累計因錯誤丟棄個數。dwOutQLen:存放網路設備的輸出緩存長度。本參數已不再使用。dwDescrLen:存放網路設備的bDescr參數描述字元串的長度,包括" "結束符。bDescr:存放網路設備的描述字元串,通常為硬體型號、軟體虛擬名稱。其他說明4.4.2 IP_ADAPTER_INFO結構體名稱IP_ADAPTER_INFO頭文件#include <IPTypes.h>結構體說明存放網路適配器的狀態信息。相關函數GetAdaptersInfo()結構體聲明struct xxx{類型 成員變數1;類型 成員變數2;……};成員變數成員變數1:成員變數說明。成員變數2:成員變數說明。……其他說明…………4.4.3 IP_INTERFACE_INFO(未完成)結構體名稱IP_INTERFACE_INFO頭文件#include <IPExport.h>結構體說明存放本機所有啟用了IPv4協議的物理和虛擬的網路適配器的名稱和索引序號。相關函數GetInterfaceInfo()結構體聲明struct IP_INTERFACE_INFO{LONG NumAdapters;IP_ADAPTER_INDEX_MAP Adapter[1];};成員變數NumAdapters:存放本結構體存放了多少個網路適配器。IP_ADAPTER_INDEX_MAP:存放網路適配器的名稱和索引序號的動態數組,如果NumAdapters參數為0,本參數無意義。其他說明本結構體只存放本機所有啟用了IPv4協議的物理和虛擬的網路適配器,4.5 性能計數器4.5.1 PPDH_FMT_COUNTERVALUE(未完成)結構體名稱PPDH_FMT_COUNTERVALUE頭文件#include <Pdh.h>結構體說明用於存儲性能計數器的數值。相關函數PdhGetFormattedCounterValue()、PdhCalculateCounterFromRawValue()結構體聲明struct PDH_FMT_COUNTERVALUE{DWORD CStatus;union{LONG longValue;double doubleValue;LONGLONG largeValue;LPCSTR AnsiStringValue;LPCWSTR WideStringValue;};};成員變數CStatus:存放計數器數值的狀態碼,狀態碼錶示該數值是否是有效,0表示有效,非0表示無效,狀態碼可以為:PDH_CSTATUS_NO_MACHINE宏:PDH was unable to connect to the computer specified in the counter path. If this status is returned when the counter is being added, the counter is not completely initialized. Each time the query is updated, PDH retries the connection. When the connection is established, normal data collection resumes.PDH_CSTATUS_NO_OBJECT宏:The specified computer was found, but the specified performance object was found on the computer. If this status is returned when the counter is being added, the specified counter is not included in the query. If this status is returned by an active counter, the data for that counter is invalid. Each time the data is requested, PDH tries to obtain this counter data.PDH_CSTATUS_NO_INSTANCE宏:The specified instance was not found in the object. If this status is returned while the counter is being added to the query, the counter is successfully added to the query, but no data is available until the specific instance appears and a successful status is returned.PDH_CSTATUS_NO_COUNTER宏:The specified counter was not found in the specified object. If this status is returned when the counter is being added, then the counter is not added to the query. If this status is returned after data collection, the data for that counter is invalid. Each time the data is requested, PDH tries to obtain this counter data.PDH_CSTATUS_INVALID_DATA宏:The counter was successfully found, but the data returned is not valid. This error can occur if the counter value is less than the previous value. (Because counter values always increment, the counter value rolls over to zero when it reaches its maximum value.) Another possible cause is a system timer that is not correct.PDH_CSTATUS_VALID_DATA宏:The data for the counter was returned successfully, but is unchanged from the last time the counter was read.PDH_CSTATUS_NEW_DATA宏:The data for the counter was returned successfully and is different from the last time the counter was read. PDH_CSTATUS_NEW_DATA can be returned on a rate counter even if the resulting rate is the same as the last sample. This is because the raw data value that is used in the determination of this status value has changed, not the computed rate.PDH_MORE_DATA宏:The supplied buffer was not large enough to store all of the counter data. Allocate a larger buffer and execute the function again.PDH_CSTATUS_ITEM_NOT_VALIDATED宏:The counter has been added to the query, but has not been validated nor accessed. No additional status information on this counter is available.PDH_CSTATUS_NO_COUNTERNAME宏:查詢句柄中沒有指定計數器的名字。PDH_CSTATUS_NO_COUNTER宏:指定的計數器的名字沒有找到。PDH_CSTATUS_NO_OBJECT宏:指定的計數器的對象沒有找到。PDH_CALC_NEGATIVE_DENOMINATOR宏:計數器具有分母值為負數的值。PDH_CALC_NEGATIVE_TIMEBASE宏:計數器具有時間基數為負數的值。PDH_CALC_NEGATIVE_VALUE宏:計數器具有負數的值。PDH_CSTATUS_NO_COUNTERNAME宏:沒有指定計數器路徑字元串。PDH_CSTATUS_BAD_COUNTERNAME宏:計數器路徑字元串的格式是不正確的。longValue:存放計數器數值為LONG型的值。doubleValue:存放計數器數值為DOUBLE型的值。largeValue:存放計數器數值為LONGLONG型的值。AnsiStringValue:存放計數器數值為ANSI字元串型的值。暫時未用。WideStringValue:存放計數器數值為WIDE字元串型的值。暫時未用。其他說明調用完收集函數並獲取計數器的數值成功後,還要判斷狀態碼是否為有效,如果是狀態碼無效的,則表示獲取到的數值是不正確的,如果狀態碼是有效的,則表示獲取到的數值是正確的。根據調用獲取計數器的數值函數時指定的是什麼類型,來使用本結構體的哪個成員變數,例如如果指定的是LONG型,那麼就使用longValue成員變數。4.6 進程4.6.1 PROCESS_INFORMATION結構體名稱PROCESS_INFORMATION頭文件#include <Windows.h>結構體說明進程信息結構體用於存放進程和主線程的標識和句柄。相關函數CreateProcess()、CreateProcessAsUser()、CreateProcessWithLogonW()、 CreateProcessWithTokenW()結構體聲明struct PROCESS_INFORMATION{HANDLE hProcess;HANDLE hThread;DWORD dwProcessId;DWORD dwThreadId;};成員變數hProcess:存放進程的句柄。hThread:存放主線程的句柄。dwProcessId:存放進程的標識。如果原進程退出後,本標識可能會分配給新進程。dwThreadId:存放主線程的標識。如果原線程退出後,本標識可能會分配給新線程。其他說明4.7 文件4.7.1 SHFILEOPSTRUCT(未完成)結構體名稱SHFILEOPSTRUCT頭文件#include <Shellapi.h>結構體說明Shell命令文件操作結構體用於針對SHFileOperation()函數的使用。結構體聲明struct SHFILEOPSTRUCT{HWND hwnd;UINT wFunc;PCZZTSTR pFrom;PCZZTSTR pTo;FILEOP_FLAGS fFlags;BOOL fAnyOperationsAborted;LPVOID hNameMappings;PCTSTR lpszProgressTitle;};成員變數hwnd:存放執行文件操作時,顯示的操作過程窗口的父窗口句柄,為0表示沒有父窗口,也就是桌面窗口。wFunc:存放具體執行哪種文件操作的標記,可以為(選一至一個):FO_COPY:把pFrom成員變數指定的文件或目錄複製到pTo成員變數指定的本地文件或目錄。FO_DELETE:刪除pFrom成員變數指定的單個文件或單個目錄。FO_MOVE:把pFrom成員變數指定的文件或目錄移動到pTo成員變數指定的本地文件或目錄。FO_RENAME:重命名pFrom成員變數指定的單個文件或單個目錄。如果要重命名多個文件或多個目錄,可用FO_MOVE標記代替。pFrom:成員變數說明。成員變數1:成員變數說明。成員變數1:成員變數說明。成員變數1:成員變數說明。成員變數1:成員變數說明。成員變數1:成員變數說明。其他說明…………4.8 窗口4.8.1 RECT(未完成)結構體名稱RECT頭文件#include <Windows.h>結構體說明用於存放窗口的左邊、頂邊、右邊、底邊在屏幕上的位置。相關函數GetWindowRect()、Func2()、Func3()…結構體聲明struct RECT{LONG left;LONG top;LONG right;LONG bottom;};成員變數left:存放窗口的左邊在屏幕上的哪個像素。top:存放窗口的頂邊在屏幕上的哪個像素。right:存放窗口的右邊在屏幕上的哪個像素。bottom:存放窗口的底邊在屏幕上的哪個像素。其他說明4.8.2 LVITEM(未完成)結構體名稱LVITEM頭文件#include <Commctrl.h>結構體說明存放列表控制項中某個項目的某個欄位的信息。相關函數CListCtrl::InsertItem()、CListCtrl::GetItem()、CListCtrl::SetItem()結構體聲明struct LVITEM{UINT mask;int iItem;int iSubItem;UINT state;UINT stateMask;LPSTR pszText;int cchTextMax;int iImage;LPARAM lParam;int iIndent;#if (NTDDI_VERSION >= NTDDI_WINXP)int iGroupId;UINT cColumns; // tile view columnsPUINT puColumns;#endif#if (NTDDI_VERSION >= NTDDI_VISTA) // Will be unused downlevel, but sizeof(LVITEMA) must be equal to sizeof(LVITEMW)int* piColFmt;int iGroup; // readonly. only valid for owner data.#endif};成員變數mask:存放本函數有哪些參數有效的標記,可以為(用"|"選零至多個):LVIF_TEXT(0x00000001):如果設置本標記,表示pszText參數有效,也就是標籤字元串有效。如果不設置本標記,表示項目沒有標籤。LVIF_IMAGE(0x00000002):LVIF_PARAM(0x00000004):LVIF_STATE(0x00000008):LVIF_INDENT(0x00000010):LVIF_NORECOMPUTE(0x00000800):以下標記需要XP及以後的系統才支持:LVIF_GROUPID(0x00000100):LVIF_COLUMNS(0x00000200):以下標記需要VISTA及以後的系統才支持:LVIF_COLFMT(0x00010000): // The piColFmt member is valid in addition to puColumnsiItem:存放項目的項目索引號,本參數只能大於等於0。iSubItem:存放項目的欄位索引號,本參數只能大於等於0。state:成員變數說明。stateMask:成員變數說明。pszText:存放項目的標籤字元串的內存指針。在調用設置相關函數(例如:CListCtrl::InsertItem)時:如果本成員變數為NULL,就表示項目沒有標籤,列表控制項上標籤位置顯示為一片空白。如果本成員變數為LPSTR_TEXTCALLBACK宏,表示項目的標籤為虛擬標籤。虛擬標籤是指列表控制項不為標籤字元串分配內存,當需要顯示標籤時,通過調用列表控制項的LVN_GETDISPINFO消息響應函數來顯示。使用虛擬標籤可以節約內存,並可以快速插入並顯示大量項目,列表控制項不會出現卡頓現象。詳情請參考LVN_GETDISPINFO消息。cchTextMax:存放項目的標籤字元串的內存的最大長度。本參數只適用於調用獲取相關函數(例如:CListCtrl::GetItem)時,pszText參數指向的用於存放標籤字元串的內存的最大長度,不適用於調用設置相關函數(例如:CListCtrl::InsertItem)。iImage:成員變數說明。lParam:成員變數說明。iIndent:成員變數說明。iGroupId:成員變數說明。cColumns:成員變數說明。puColumns:成員變數說明。piColFmt:成員變數說明。iGroup:成員變數說明。其他說明4.9 時鐘4.9.1 timeval結構體名稱timeval頭文件#include <time.h>結構體說明用於記錄時間的結構體。結構體聲明struct timeval{time_t tv_sec;suseconds_t tv_usec;};成員變數tv_sec:表示多少秒。tv_usec:表示多少微秒,1秒等於1000000微秒。其他說明4.9.2 timezone結構體名稱timezone頭文件#include <time.h>結構體說明用於記錄時區的結構體。結構體聲明struct timezone{int tz_minuteswest;int tz_dsttime;};成員變數tz_minuteswest:[輸入&輸出],和格林威治時間往西方的時差,差了多少分鐘。tz_dsttime:[輸入&輸出],夏時制或夏令時或日光節約時(Daylight Saving Time)的類型。類型如下:DST_NONE //不使用DST_USA //美國DST_AUST //澳洲DST_WET //西歐DST_MET //中歐DST_EET //東歐DST_CAN //加拿大DST_GB //大不列顛DST_RUM //羅馬尼亞DST_TUR //土耳其DST_AUSTALT //澳洲(1986年以後)其他說明4.9.3 tm結構體名稱tm頭文件#include <time.h>結構體說明存放日曆的結構體。結構體聲明struct tm{int tm_sec;int tm_min;int tm_hour;int tm_mday;int tm_mon;int tm_year;int tm_wday;int tm_yday;int tm_isdst;};成員變數tm_sec:表示秒鐘,在[0,60]之間,多出來的一秒是用來處理閏秒問題。tm_min:表示分鐘,在[0,59]之間。tm_hour:表示時鐘,在[0,23]之間。tm_mday:表示日份,在[1,31]之間。tm_mon:表示月份,在[0,11]之間。tm_year:表示1900年到今年一共差多少年。tm_wday:表示星期幾,在[0,6]之間,星期天為0,星期一為1,以此類推。tm_yday:表示當天是本年第幾日,在[0,365]之間,非閏年有365日,閏年有366日。tm_isdst:表示是否為日光節約時間。其他說明4.9.4 SYSTEMTIME結構體名稱SYSTEMTIME頭文件#include <Windows.h>結構體說明存放日期時間信息。結構體聲明typedef struct _SYSTEMTIME{WORD wYear;WORD wMonth;WORD wDayOfWeek;WORD wDay;WORD wHour;WORD wMinute;WORD wSecond;WORD wMilliseconds;}SYSTEMTIME;成員變數wYear:表示年份,在[1601-30827]之間。例如:此值為2013,就表示2013年。wMonth:表示月份,在[1-12]之間。例如:此值為1,就表示1月;此值為12,就表示12月。wDayOfWeek:表示星期幾,在[1-7]之間。例如:此值為1,就表示星期日;此值為7,就表示星期六。wDay:表示日份,在[1-31]之間。wHour:表示時鐘,在[0-23]之間。wMinute:表示分鐘,在[0-59]之間。wSecond:表示秒鐘,在[0-59]之間。wMilliseconds:表示毫秒,在[0-999]之間。其他說明4.9.5 TIME_ZONE_INFORMATION(未完成)結構體名稱TIME_ZONE_INFORMATION頭文件#include <timezoneapi.h>結構體說明存放時區信息的結構體。相關函數GetTimeZoneInformation()、SetTimeZoneInformation()結構體聲明struct TIME_ZONE_INFORMATION{LONG Bias;WCHAR StandardName[32];SYSTEMTIME StandardDate;LONG StandardBias;WCHAR DaylightName[32];SYSTEMTIME DaylightDate;LONG DaylightBias;};成員變數Bias:存放本地時轉換為協調時需要加減多少分鐘。例如:如果本地時區為東八區,則本參數為-480。StandardName:存放本地時區的標準名稱的字元串。例如:「中國標準時間」。本參數配置在以下註冊表中:HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionTime Zones以中國北京時間為例即 China Standard Time子項,Display:在控制面板中調整時區時顯示的名稱Std:標準時間名稱Dlt:如果有夏令時時區則為其名稱。Tzi:一個數據結構,包含本地時區和0時區相差的分鐘數等信息。二進位形式存儲的用一結構體定義之typedef struct _REG_TZI_FORMAT{LONG Bias;LONG StandardBias;LONG DaylightBias;SYSTEMTIME StandardDate;SYSTEMTIME DaylightDate;}REG_TZI_FORMAT;StandardDate:成員變數說明。StandardBias:成員變數說明。DaylightName:成員變數說明。DaylightDate:成員變數說明。DaylightBias:成員變數說明。其他說明4.10 消息機制4.10.1 MSG結構體名稱MSG頭文件#include <Windows.h>結構體說明用於存放每一個線程的消息隊列里的消息的各項信息。結構體聲明struct MSG{HWND hwnd;UINT message;WPARAM wParam;LPARAM lParam;DWORD time;POINT pt;};成員變數hwnd:存放此條窗口消息是哪一個窗口句柄的。如果不是窗口消息,此參數為NULL。message:存放消息值,就是表示此條消息是什麼消息。例如:窗口消息可能是WM_USER、WM_CHAR等,線程消息可能是自定義的了。wParam:存放此條消息的第一個參數,具體作用根據不同的消息而定。lParam:存放此條消息的第二個參數,具體作用根據不同的消息而定。time:存放此條消息的發送時間。pt:存放此條消息在發送的時候,滑鼠所在坐標。注意:這不是接收此條消息時的坐標,因為從消息的發送到接收是需要時間的。其他說明4.11 音頻4.11.1 WAVEFORMATEX(未完成)結構體名稱WAVEFORMATEX頭文件#include <mmeapi.h>結構體稱呼音頻格式結構體。結構體說明用於存放音頻數據格式的相關參數。相關函數waveInOpen()、Func2()、Func3()…結構體聲明struct WAVEFORMATEX{WORD wFormatTag; /* format type */WORD nChannels; /* number of channels (i.e. mono, stereo...) */DWORD nSamplesPerSec; /* sample rate */DWORD nAvgBytesPerSec; /* for buffer estimation */WORD nBlockAlign; /* block size of data */WORD wBitsPerSample; /* number of bits per sample of mono data */WORD cbSize; /* the count in bytes of the size of *//* extra information (after cbSize) */};成員變數wFormatTag:存放音頻的格式,一般選WAVE_FORMAT_PCM宏表示原始格式,可以為(選一至一個):WAVE_FORMAT_UNKNOWN 0x0000 /* Microsoft Corporation */WAVE_FORMAT_PCM 0x0001 /* raw format */WAVE_FORMAT_ADPCM 0x0002 /* Microsoft Corporation */WAVE_FORMAT_IEEE_FLOAT 0x0003 /* Microsoft Corporation */WAVE_FORMAT_VSELP 0x0004 /* Compaq Computer Corp. */WAVE_FORMAT_IBM_CVSD 0x0005 /* IBM Corporation */WAVE_FORMAT_ALAW 0x0006 /* Microsoft Corporation */WAVE_FORMAT_MULAW 0x0007 /* Microsoft Corporation */WAVE_FORMAT_DTS 0x0008 /* Microsoft Corporation */WAVE_FORMAT_DRM 0x0009 /* Microsoft Corporation */WAVE_FORMAT_WMAVOICE9 0x000A /* Microsoft Corporation */WAVE_FORMAT_WMAVOICE10 0x000B /* Microsoft Corporation */WAVE_FORMAT_OKI_ADPCM 0x0010 /* OKI */WAVE_FORMAT_DVI_ADPCM 0x0011 /* Intel Corporation */WAVE_FORMAT_IMA_ADPCM (WAVE_FORMAT_DVI_ADPCM) /* Intel Corporation */WAVE_FORMAT_MEDIASPACE_ADPCM 0x0012 /* Videologic */WAVE_FORMAT_SIERRA_ADPCM 0x0013 /* Sierra Semiconductor Corp */WAVE_FORMAT_G723_ADPCM 0x0014 /* Antex Electronics Corporation */WAVE_FORMAT_DIGISTD 0x0015 /* DSP Solutions, Inc. */WAVE_FORMAT_DIGIFIX 0x0016 /* DSP Solutions, Inc. */WAVE_FORMAT_DIALOGIC_OKI_ADPCM 0x0017 /* Dialogic Corporation */WAVE_FORMAT_MEDIAVISION_ADPCM 0x0018 /* Media Vision, Inc. */WAVE_FORMAT_CU_CODEC 0x0019 /* Hewlett-Packard Company */WAVE_FORMAT_HP_DYN_VOICE 0x001A /* Hewlett-Packard Company */WAVE_FORMAT_YAMAHA_ADPCM 0x0020 /* Yamaha Corporation of America */WAVE_FORMAT_SONARC 0x0021 /* Speech Compression */WAVE_FORMAT_DSPGROUP_TRUESPEECH 0x0022 /* DSP Group, Inc */WAVE_FORMAT_ECHOSC1 0x0023 /* Echo Speech Corporation */WAVE_FORMAT_AUDIOFILE_AF36 0x0024 /* Virtual Music, Inc. */WAVE_FORMAT_APTX 0x0025 /* Audio Processing Technology */WAVE_FORMAT_AUDIOFILE_AF10 0x0026 /* Virtual Music, Inc. */WAVE_FORMAT_PROSODY_1612 0x0027 /* Aculab plc */WAVE_FORMAT_LRC 0x0028 /* Merging Technologies S.A. */WAVE_FORMAT_DOLBY_AC2 0x0030 /* Dolby Laboratories */WAVE_FORMAT_GSM610 0x0031 /* Microsoft Corporation */WAVE_FORMAT_MSNAUDIO 0x0032 /* Microsoft Corporation */WAVE_FORMAT_ANTEX_ADPCME 0x0033 /* Antex Electronics Corporation */WAVE_FORMAT_CONTROL_RES_VQLPC 0x0034 /* Control Resources Limited */WAVE_FORMAT_DIGIREAL 0x0035 /* DSP Solutions, Inc. */WAVE_FORMAT_DIGIADPCM 0x0036 /* DSP Solutions, Inc. */WAVE_FORMAT_CONTROL_RES_CR10 0x0037 /* Control Resources Limited */WAVE_FORMAT_NMS_VBXADPCM 0x0038 /* Natural MicroSystems */WAVE_FORMAT_CS_IMAADPCM 0x0039 /* Crystal Semiconductor IMA ADPCM */WAVE_FORMAT_ECHOSC3 0x003A /* Echo Speech Corporation */WAVE_FORMAT_ROCKWELL_ADPCM 0x003B /* Rockwell International */WAVE_FORMAT_ROCKWELL_DIGITALK 0x003C /* Rockwell International */WAVE_FORMAT_XEBEC 0x003D /* Xebec Multimedia Solutions Limited */WAVE_FORMAT_G721_ADPCM 0x0040 /* Antex Electronics Corporation */WAVE_FORMAT_G728_CELP 0x0041 /* Antex Electronics Corporation */WAVE_FORMAT_MSG723 0x0042 /* Microsoft Corporation */WAVE_FORMAT_INTEL_G723_1 0x0043 /* Intel Corp. */WAVE_FORMAT_INTEL_G729 0x0044 /* Intel Corp. */WAVE_FORMAT_SHARP_G726 0x0045 /* Sharp */WAVE_FORMAT_MPEG 0x0050 /* Microsoft Corporation */WAVE_FORMAT_RT24 0x0052 /* InSoft, Inc. */WAVE_FORMAT_PAC 0x0053 /* InSoft, Inc. */WAVE_FORMAT_MPEGLAYER3 0x0055 /* ISO/MPEG Layer3 Format Tag */WAVE_FORMAT_LUCENT_G723 0x0059 /* Lucent Technologies */WAVE_FORMAT_CIRRUS 0x0060 /* Cirrus Logic */WAVE_FORMAT_ESPCM 0x0061 /* ESS Technology */WAVE_FORMAT_VOXWARE 0x0062 /* Voxware Inc */WAVE_FORMAT_CANOPUS_ATRAC 0x0063 /* Canopus, co., Ltd. */WAVE_FORMAT_G726_ADPCM 0x0064 /* APICOM */WAVE_FORMAT_G722_ADPCM 0x0065 /* APICOM */WAVE_FORMAT_DSAT 0x0066 /* Microsoft Corporation */WAVE_FORMAT_DSAT_DISPLAY 0x0067 /* Microsoft Corporation */WAVE_FORMAT_VOXWARE_BYTE_ALIGNED 0x0069 /* Voxware Inc */WAVE_FORMAT_VOXWARE_AC8 0x0070 /* Voxware Inc */WAVE_FORMAT_VOXWARE_AC10 0x0071 /* Voxware Inc */WAVE_FORMAT_VOXWARE_AC16 0x0072 /* Voxware Inc */WAVE_FORMAT_VOXWARE_AC20 0x0073 /* Voxware Inc */WAVE_FORMAT_VOXWARE_RT24 0x0074 /* Voxware Inc */WAVE_FORMAT_VOXWARE_RT29 0x0075 /* Voxware Inc */WAVE_FORMAT_VOXWARE_RT29HW 0x0076 /* Voxware Inc */WAVE_FORMAT_VOXWARE_VR12 0x0077 /* Voxware Inc */WAVE_FORMAT_VOXWARE_VR18 0x0078 /* Voxware Inc */WAVE_FORMAT_VOXWARE_TQ40 0x0079 /* Voxware Inc */WAVE_FORMAT_VOXWARE_SC3 0x007A /* Voxware Inc */WAVE_FORMAT_VOXWARE_SC3_1 0x007B /* Voxware Inc */WAVE_FORMAT_SOFTSOUND 0x0080 /* Softsound, Ltd. */WAVE_FORMAT_VOXWARE_TQ60 0x0081 /* Voxware Inc */WAVE_FORMAT_MSRT24 0x0082 /* Microsoft Corporation */WAVE_FORMAT_G729A 0x0083 /* AT&T Labs, Inc. */WAVE_FORMAT_MVI_MVI2 0x0084 /* Motion Pixels */WAVE_FORMAT_DF_G726 0x0085 /* DataFusion Systems (Pty) (Ltd) */WAVE_FORMAT_DF_GSM610 0x0086 /* DataFusion Systems (Pty) (Ltd) */WAVE_FORMAT_ISIAUDIO 0x0088 /* Iterated Systems, Inc. */WAVE_FORMAT_ONLIVE 0x0089 /* OnLive! Technologies, Inc. */WAVE_FORMAT_MULTITUDE_FT_SX20 0x008A /* Multitude Inc. */WAVE_FORMAT_INFOCOM_ITS_G721_ADPCM 0x008B /* Infocom */WAVE_FORMAT_CONVEDIA_G729 0x008C /* Convedia Corp. */WAVE_FORMAT_CONGRUENCY 0x008D /* Congruency Inc. */WAVE_FORMAT_SBC24 0x0091 /* Siemens Business Communications Sys */WAVE_FORMAT_DOLBY_AC3_SPDIF 0x0092 /* Sonic Foundry */WAVE_FORMAT_MEDIASONIC_G723 0x0093 /* MediaSonic */WAVE_FORMAT_PROSODY_8KBPS 0x0094 /* Aculab plc */WAVE_FORMAT_ZYXEL_ADPCM 0x0097 /* ZyXEL Communications, Inc. */WAVE_FORMAT_PHILIPS_LPCBB 0x0098 /* Philips Speech Processing */WAVE_FORMAT_PACKED 0x0099 /* Studer Professional Audio AG */WAVE_FORMAT_MALDEN_PHONYTALK 0x00A0 /* Malden Electronics Ltd. */WAVE_FORMAT_RACAL_RECORDER_GSM 0x00A1 /* Racal recorders */WAVE_FORMAT_RACAL_RECORDER_G720_A 0x00A2 /* Racal recorders */WAVE_FORMAT_RACAL_RECORDER_G723_1 0x00A3 /* Racal recorders */WAVE_FORMAT_RACAL_RECORDER_TETRA_ACELP 0x00A4 /* Racal recorders */WAVE_FORMAT_NEC_AAC 0x00B0 /* NEC Corp. */WAVE_FORMAT_RAW_AAC1 0x00FF /* For Raw AAC, with format block AudioSpecificConfig() (as defined by MPEG-4), that follows WAVEFORMATEX */WAVE_FORMAT_RHETOREX_ADPCM 0x0100 /* Rhetorex Inc. */WAVE_FORMAT_IRAT 0x0101 /* BeCubed Software Inc. */WAVE_FORMAT_VIVO_G723 0x0111 /* Vivo Software */WAVE_FORMAT_VIVO_SIREN 0x0112 /* Vivo Software */WAVE_FORMAT_PHILIPS_CELP 0x0120 /* Philips Speech Processing */WAVE_FORMAT_PHILIPS_GRUNDIG 0x0121 /* Philips Speech Processing */WAVE_FORMAT_DIGITAL_G723 0x0123 /* Digital Equipment Corporation */WAVE_FORMAT_SANYO_LD_ADPCM 0x0125 /* Sanyo Electric Co., Ltd. */WAVE_FORMAT_SIPROLAB_ACEPLNET 0x0130 /* Sipro Lab Telecom Inc. */WAVE_FORMAT_SIPROLAB_ACELP4800 0x0131 /* Sipro Lab Telecom Inc. */WAVE_FORMAT_SIPROLAB_ACELP8V3 0x0132 /* Sipro Lab Telecom Inc. */WAVE_FORMAT_SIPROLAB_G729 0x0133 /* Sipro Lab Telecom Inc. */WAVE_FORMAT_SIPROLAB_G729A 0x0134 /* Sipro Lab Telecom Inc. */WAVE_FORMAT_SIPROLAB_KELVIN 0x0135 /* Sipro Lab Telecom Inc. */WAVE_FORMAT_VOICEAGE_AMR 0x0136 /* VoiceAge Corp. */WAVE_FORMAT_G726ADPCM 0x0140 /* Dictaphone Corporation */WAVE_FORMAT_DICTAPHONE_CELP68 0x0141 /* Dictaphone Corporation */WAVE_FORMAT_DICTAPHONE_CELP54 0x0142 /* Dictaphone Corporation */WAVE_FORMAT_QUALCOMM_PUREVOICE 0x0150 /* Qualcomm, Inc. */WAVE_FORMAT_QUALCOMM_HALFRATE 0x0151 /* Qualcomm, Inc. */WAVE_FORMAT_TUBGSM 0x0155 /* Ring Zero Systems, Inc. */WAVE_FORMAT_MSAUDIO1 0x0160 /* Microsoft Corporation */WAVE_FORMAT_WMAUDIO2 0x0161 /* Microsoft Corporation */WAVE_FORMAT_WMAUDIO3 0x0162 /* Microsoft Corporation */WAVE_FORMAT_WMAUDIO_LOSSLESS 0x0163 /* Microsoft Corporation */WAVE_FORMAT_WMASPDIF 0x0164 /* Microsoft Corporation */WAVE_FORMAT_UNISYS_NAP_ADPCM 0x0170 /* Unisys Corp. */WAVE_FORMAT_UNISYS_NAP_ULAW 0x0171 /* Unisys Corp. */WAVE_FORMAT_UNISYS_NAP_ALAW 0x0172 /* Unisys Corp. */WAVE_FORMAT_UNISYS_NAP_16K 0x0173 /* Unisys Corp. */WAVE_FORMAT_SYCOM_ACM_SYC008 0x0174 /* SyCom Technologies */WAVE_FORMAT_SYCOM_ACM_SYC701_G726L 0x0175 /* SyCom Technologies */WAVE_FORMAT_SYCOM_ACM_SYC701_CELP54 0x0176 /* SyCom Technologies */WAVE_FORMAT_SYCOM_ACM_SYC701_CELP68 0x0177 /* SyCom Technologies */WAVE_FORMAT_KNOWLEDGE_ADVENTURE_ADPCM 0x0178 /* Knowledge Adventure, Inc. */WAVE_FORMAT_FRAUNHOFER_IIS_MPEG2_AAC 0x0180 /* Fraunhofer IIS */WAVE_FORMAT_DTS_DS 0x0190 /* Digital Theatre Systems, Inc. */WAVE_FORMAT_CREATIVE_ADPCM 0x0200 /* Creative Labs, Inc */WAVE_FORMAT_CREATIVE_FASTSPEECH8 0x0202 /* Creative Labs, Inc */WAVE_FORMAT_CREATIVE_FASTSPEECH10 0x0203 /* Creative Labs, Inc */WAVE_FORMAT_UHER_ADPCM 0x0210 /* UHER informatic GmbH */WAVE_FORMAT_ULEAD_DV_AUDIO 0x0215 /* Ulead Systems, Inc. */WAVE_FORMAT_ULEAD_DV_AUDIO_1 0x0216 /* Ulead Systems, Inc. */WAVE_FORMAT_QUARTERDECK 0x0220 /* Quarterdeck Corporation */WAVE_FORMAT_ILINK_VC 0x0230 /* I-link Worldwide */WAVE_FORMAT_RAW_SPORT 0x0240 /* Aureal Semiconductor */WAVE_FORMAT_ESST_AC3 0x0241 /* ESS Technology, Inc. */WAVE_FORMAT_GENERIC_PASSTHRU 0x0249WAVE_FORMAT_IPI_HSX 0x0250 /* Interactive Products, Inc. */WAVE_FORMAT_IPI_RPELP 0x0251 /* Interactive Products, Inc. */WAVE_FORMAT_CS2 0x0260 /* Consistent Software */WAVE_FORMAT_SONY_SCX 0x0270 /* Sony Corp. */WAVE_FORMAT_SONY_SCY 0x0271 /* Sony Corp. */WAVE_FORMAT_SONY_ATRAC3 0x0272 /* Sony Corp. */WAVE_FORMAT_SONY_SPC 0x0273 /* Sony Corp. */WAVE_FORMAT_TELUM_AUDIO 0x0280 /* Telum Inc. */WAVE_FORMAT_TELUM_IA_AUDIO 0x0281 /* Telum Inc. */WAVE_FORMAT_NORCOM_VOICE_SYSTEMS_ADPCM 0x0285 /* Norcom Electronics Corp. */WAVE_FORMAT_FM_TOWNS_SND 0x0300 /* Fujitsu Corp. */WAVE_FORMAT_MICRONAS 0x0350 /* Micronas Semiconductors, Inc. */WAVE_FORMAT_MICRONAS_CELP833 0x0351 /* Micronas Semiconductors, Inc. */WAVE_FORMAT_BTV_DIGITAL 0x0400 /* Brooktree Corporation */WAVE_FORMAT_INTEL_MUSIC_CODER 0x0401 /* Intel Corp. */WAVE_FORMAT_INDEO_AUDIO 0x0402 /* Ligos */WAVE_FORMAT_QDESIGN_MUSIC 0x0450 /* QDesign Corporation */WAVE_FORMAT_ON2_VP7_AUDIO 0x0500 /* On2 Technologies */WAVE_FORMAT_ON2_VP6_AUDIO 0x0501 /* On2 Technologies */WAVE_FORMAT_VME_VMPCM 0x0680 /* AT&T Labs, Inc. */WAVE_FORMAT_TPC 0x0681 /* AT&T Labs, Inc. */WAVE_FORMAT_LIGHTWAVE_LOSSLESS 0x08AE /* Clearjump */WAVE_FORMAT_OLIGSM 0x1000 /* Ing C. Olivetti & C., S.p.A. */WAVE_FORMAT_OLIADPCM 0x1001 /* Ing C. Olivetti & C., S.p.A. */WAVE_FORMAT_OLICELP 0x1002 /* Ing C. Olivetti & C., S.p.A. */WAVE_FORMAT_OLISBC 0x1003 /* Ing C. Olivetti & C., S.p.A. */WAVE_FORMAT_OLIOPR 0x1004 /* Ing C. Olivetti & C., S.p.A. */WAVE_FORMAT_LH_CODEC 0x1100 /* Lernout & Hauspie */WAVE_FORMAT_LH_CODEC_CELP 0x1101 /* Lernout & Hauspie */WAVE_FORMAT_LH_CODEC_SBC8 0x1102 /* Lernout & Hauspie */WAVE_FORMAT_LH_CODEC_SBC12 0x1103 /* Lernout & Hauspie */WAVE_FORMAT_LH_CODEC_SBC16 0x1104 /* Lernout & Hauspie */WAVE_FORMAT_NORRIS 0x1400 /* Norris Communications, Inc. */WAVE_FORMAT_ISIAUDIO_2 0x1401 /* ISIAudio */WAVE_FORMAT_SOUNDSPACE_MUSICOMPRESS 0x1500 /* AT&T Labs, Inc. */WAVE_FORMAT_MPEG_ADTS_AAC 0x1600 /* Microsoft Corporation */WAVE_FORMAT_MPEG_RAW_AAC 0x1601 /* Microsoft Corporation */WAVE_FORMAT_MPEG_LOAS 0x1602 /* Microsoft Corporation (MPEG-4 Audio Transport Streams (LOAS/LATM) */WAVE_FORMAT_NOKIA_MPEG_ADTS_AAC 0x1608 /* Microsoft Corporation */WAVE_FORMAT_NOKIA_MPEG_RAW_AAC 0x1609 /* Microsoft Corporation */WAVE_FORMAT_VODAFONE_MPEG_ADTS_AAC 0x160A /* Microsoft Corporation */WAVE_FORMAT_VODAFONE_MPEG_RAW_AAC 0x160B /* Microsoft Corporation */WAVE_FORMAT_MPEG_HEAAC 0x1610 /* Microsoft Corporation (MPEG-2 AAC or MPEG-4 HE-AAC v1/v2 streams with any payload (ADTS, ADIF, LOAS/LATM, RAW). Format block includes MP4 AudioSpecificConfig() -- see HEAACWAVEFORMAT below */WAVE_FORMAT_VOXWARE_RT24_SPEECH 0x181C /* Voxware Inc. */WAVE_FORMAT_SONICFOUNDRY_LOSSLESS 0x1971 /* Sonic Foundry */WAVE_FORMAT_INNINGS_TELECOM_ADPCM 0x1979 /* Innings Telecom Inc. */WAVE_FORMAT_LUCENT_SX8300P 0x1C07 /* Lucent Technologies */WAVE_FORMAT_LUCENT_SX5363S 0x1C0C /* Lucent Technologies */WAVE_FORMAT_CUSEEME 0x1F03 /* CUSeeMe */WAVE_FORMAT_NTCSOFT_ALF2CM_ACM 0x1FC4 /* NTCSoft */WAVE_FORMAT_DVM 0x2000 /* FAST Multimedia AG */WAVE_FORMAT_DTS2 0x2001WAVE_FORMAT_MAKEAVIS 0x3313WAVE_FORMAT_DIVIO_MPEG4_AAC 0x4143 /* Divio, Inc. */WAVE_FORMAT_NOKIA_ADAPTIVE_MULTIRATE 0x4201 /* Nokia */WAVE_FORMAT_DIVIO_G726 0x4243 /* Divio, Inc. */WAVE_FORMAT_LEAD_SPEECH 0x434C /* LEAD Technologies */WAVE_FORMAT_LEAD_VORBIS 0x564C /* LEAD Technologies */WAVE_FORMAT_WAVPACK_AUDIO 0x5756 /* xiph.org */WAVE_FORMAT_OGG_VORBIS_MODE_1 0x674F /* Ogg Vorbis */WAVE_FORMAT_OGG_VORBIS_MODE_2 0x6750 /* Ogg Vorbis */WAVE_FORMAT_OGG_VORBIS_MODE_3 0x6751 /* Ogg Vorbis */WAVE_FORMAT_OGG_VORBIS_MODE_1_PLUS 0x676F /* Ogg Vorbis */WAVE_FORMAT_OGG_VORBIS_MODE_2_PLUS 0x6770 /* Ogg Vorbis */WAVE_FORMAT_OGG_VORBIS_MODE_3_PLUS 0x6771 /* Ogg Vorbis */WAVE_FORMAT_3COM_NBX 0x7000 /* 3COM Corp. */WAVE_FORMAT_FAAD_AAC 0x706DWAVE_FORMAT_AMR_NB 0x7361 /* AMR Narrowband */WAVE_FORMAT_AMR_WB 0x7362 /* AMR Wideband */WAVE_FORMAT_AMR_WP 0x7363 /* AMR Wideband Plus */WAVE_FORMAT_GSM_AMR_CBR 0x7A21 /* GSMA/3GPP */WAVE_FORMAT_GSM_AMR_VBR_SID 0x7A22 /* GSMA/3GPP */WAVE_FORMAT_COMVERSE_INFOSYS_G723_1 0xA100 /* Comverse Infosys */WAVE_FORMAT_COMVERSE_INFOSYS_AVQSBC 0xA101 /* Comverse Infosys */WAVE_FORMAT_COMVERSE_INFOSYS_SBC 0xA102 /* Comverse Infosys */WAVE_FORMAT_SYMBOL_G729_A 0xA103 /* Symbol Technologies */WAVE_FORMAT_VOICEAGE_AMR_WB 0xA104 /* VoiceAge Corp. */WAVE_FORMAT_INGENIENT_G726 0xA105 /* Ingenient Technologies, Inc. */WAVE_FORMAT_MPEG4_AAC 0xA106 /* ISO/MPEG-4 */WAVE_FORMAT_ENCORE_G726 0xA107 /* Encore Software */WAVE_FORMAT_ZOLL_ASAO 0xA108 /* ZOLL Medical Corp. */WAVE_FORMAT_SPEEX_VOICE 0xA109 /* xiph.org */WAVE_FORMAT_VIANIX_MASC 0xA10A /* Vianix LLC */WAVE_FORMAT_WM9_SPECTRUM_ANALYZER 0xA10B /* Microsoft */WAVE_FORMAT_WMF_SPECTRUM_ANAYZER 0xA10C /* Microsoft */WAVE_FORMAT_GSM_610 0xA10DWAVE_FORMAT_GSM_620 0xA10EWAVE_FORMAT_GSM_660 0xA10FWAVE_FORMAT_GSM_690 0xA110WAVE_FORMAT_GSM_ADAPTIVE_MULTIRATE_WB 0xA111WAVE_FORMAT_POLYCOM_G722 0xA112 /* Polycom */WAVE_FORMAT_POLYCOM_G728 0xA113 /* Polycom */WAVE_FORMAT_POLYCOM_G729_A 0xA114 /* Polycom */WAVE_FORMAT_POLYCOM_SIREN 0xA115 /* Polycom */WAVE_FORMAT_GLOBAL_IP_ILBC 0xA116 /* Global IP */WAVE_FORMAT_RADIOTIME_TIME_SHIFT_RADIO 0xA117 /* RadioTime */WAVE_FORMAT_NICE_ACA 0xA118 /* Nice Systems */WAVE_FORMAT_NICE_ADPCM 0xA119 /* Nice Systems */WAVE_FORMAT_VOCORD_G721 0xA11A /* Vocord Telecom */WAVE_FORMAT_VOCORD_G726 0xA11B /* Vocord Telecom */WAVE_FORMAT_VOCORD_G722_1 0xA11C /* Vocord Telecom */WAVE_FORMAT_VOCORD_G728 0xA11D /* Vocord Telecom */WAVE_FORMAT_VOCORD_G729 0xA11E /* Vocord Telecom */WAVE_FORMAT_VOCORD_G729_A 0xA11F /* Vocord Telecom */WAVE_FORMAT_VOCORD_G723_1 0xA120 /* Vocord Telecom */WAVE_FORMAT_VOCORD_LBC 0xA121 /* Vocord Telecom */WAVE_FORMAT_NICE_G728 0xA122 /* Nice Systems */WAVE_FORMAT_FRACE_TELECOM_G729 0xA123 /* France Telecom */WAVE_FORMAT_CODIAN 0xA124 /* CODIAN */WAVE_FORMAT_FLAC 0xF1AC /* flac.sourceforge.net */WAVE_FORMAT_EXTENSIBLE 0xFFFE /* Microsoft */nChannels:存放音頻的聲道數量,1表示單聲道,2表示雙聲道立體聲。nSamplesPerSec:存放音頻的採樣頻率,單位赫茲。如果wFormatTag參數為WAVE_FORMAT_PCM宏,本參數可以為8000、11025、22050、44100。對於非PCM格式請根據廠商的說明設置本參數。nAvgBytesPerSec:存放音頻的平均數據傳輸速率,單位位元組每秒。這個值對於創建緩衝大小是很有用的。如果wFormatTag參數為WAVE_FORMAT_PCM宏,本參數應與nSamplesPerSec參數相同。對於非PCM格式請根據廠商的說明設置本參數。nBlockAlign:存放音頻的採樣單元的大小,也就是每一次採樣到的音頻數據單元的大小,單位位元組,計算方法:聲道數量×採樣位數÷8。如果wFormatTag參數為WAVE_FORMAT_PCM宏,本參數為(nChannels * wBitsPerSample) / 8。對於非PCM格式請根據廠商的說明設置本參數。wBitsPerSample:存放音頻的採樣位數,單位比特位。如果wFormatTag參數為WAVE_FORMAT_PCM宏,本參數可以為8、16。對於非PCM格式請根據廠商的說明設置本參數。cbSize:存放音頻的額外信息的大小,單位位元組,額外信息添加在WAVEFORMATEX結構的結尾。這個信息可以作為非PCM格式的wFormatTag額外屬性。如果wFormatTag參數指定的音頻格式不需要額外的信息,此值必需為0。如果wFormatTag參數為WAVE_FORMAT_PCM宏,本參數無意義。其他說明一個使用額外信息的例子,微軟自適應音頻脈衝編碼(ms-adpcm)格式,對於ms-adpcm的wformattag參數為WAVE_FORMAT_ADPCM宏。cbSize參數通常會被設置為2(16位)。存儲ms-adpcm格式的額外信息係數對編碼和波形音頻數據解碼所需。
推薦閱讀:
※Execl2010中的IFERROR函數運用
※一對多查找,用 Vlookup 函數太Out了!
※使用VLOOKUP函數對EXCEL表格隔任意列求和
※【Excel函數教程】SUM函數的取代函數SUMPRODUCT
※解決90%的函數報錯問題!常見函數報錯解析~