C、C++函數和類庫詳解(VC++版)(2016-06-26更新)


C、C++函數和類庫詳解(VC++版)(未完成)

整理者:赤勇玄心行天道

QQ:280604597

Email:280604597@qq.com

大家有什么不明白的地方,或者想要詳細了解的地方可以聯系我,我會認真回復的

1   可執行程序編譯流程

 

文件名

目錄位置

解決方案資源管理器位置

說明

Projname.rc

Projname

源文件

項目的資源腳本文件。資源腳本文件包含如下內容,具體取決於項目的類型和為項目選擇的支持(例如工具欄、對話框或 HTML):

  • 默認菜單定義。
  • 快捷鍵和字符串表。
  • 默認“關於”對話框。
  • 其他對話框。
  • 圖標文件(res\Projname.ico)。
  • 版本信息。
  • 位圖。
  • 工具欄。
  • HTML文件。

資源文件包含標准 Microsoft 基礎類資源的文件 Afxres.rc。

一個項目最多只能有一個資源腳本文件。

Resource.h

Projname

頭文件

包含項目使用的資源定義的資源頭文件。

Projname.rc2

Projname\res

源文件

包含項目使用的附加資源的腳本文件。可以在項目的.rc文件的頂部包括.rc2文件。

.rc2文件用於存放由多個不同項目使用的資源。不必為不同的項目多次創建相同的資源,而是可以將它們放在一個.rc2文件中,然后將該.rc2文件包括在主.rc文件中。

一個項目最多只能有一個附加資源的腳本文件。

Projname.def

Projname

源文件

DLL項目的模塊定義文件。對於控件,它提供控件的名稱和說明以及運行時堆的大小。

一個項目最多只能有一個模塊定義文件。

Projname.ico

Projname\res

資源文件

項目或控件的圖標文件。該圖標在應用程序最小化時出現。它還用在應用程序的“關於”框中。默認情況下,MFC提供MFC圖標,ATL提供ATL圖標。

ProjnameDoc.ico

Projname\res

資源文件

包括文檔/視圖結構支持的MFC項目的圖標文件。

Toolbar.bmp

Projname\res

資源文件

表示工具欄或調色板中的應用程序或控件的位圖文件。該位圖包含在項目的資源文件中。初始工具欄和狀態欄在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,[輸入]:

存放絕對路徑字符串的內存的最大長度。

返回值

正整數:如果絕對路徑字符串的內存的最大長度足夠大,就返回絕對路徑字符串的長度,不包括\0;如果不夠大,就返回絕對路徑字符串截斷后的長度,包括\0,並設置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_IRWXU00700 權限,表示該文件所有者具有可讀、可寫及可執行的權限。

S_IRUSR00400權限,表示該文件所有者具有可讀取的權限。

S_IWUSR00200 權限,表示該文件所有者具有可寫入的權限。

S_IXUSR00100 權限,表示該文件所有者具有可執行的權限。

S_IRWXG00070權限,表示該文件所有組具有可讀、可寫及可執行的權限。

S_IRGRP00040 權限,表示該文件所有組具有可讀的權限。

S_IWGRP00020權限,表示該文件所有組具有可寫入的權限。

S_IXGRP00010 權限,表示該文件所有組具有可執行的權限。

S_IRWXO00007權限,表示其他用戶具有可讀、可寫及可執行的權限。

S_IROTH00004 權限,表示其他用戶具有可讀的權限

S_IWOTH00002權限,表示其他用戶具有可寫入的權限。

S_IXOTH00001 權限,表示其他用戶具有可執行的權限。

返回值

-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:錯誤碼說明。

……

線程安全

是 或 否 或 未知

其他說明

"\n"會被自動轉換為"\r\n"。

 

 

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_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\PendingFileRenameOperations下,此時本函數的返回值只說明寫入注冊表的操作是否成功。

返回值

非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:\path\file"

文件名子串:"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,[輸入]:路徑字符串的內存指針。

返回值

文件擴展名前的'.'字符指針:成功。

路徑字符串的'\0'字符指針:失敗。

錯誤碼

線程安全

原子操作

其他說明

一個正確的文件擴展名不能出現空格。

 

示例:

路徑字符串:"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:\path1\path2\sample.txt

根據120像素截斷后為:  C:\pat...\sample.txt

根據25像素截斷后為:   ...\sample.txt

PathCompactPathEx   根據字符個數來生成符合長度的路徑。

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” ) 返回TRUE

PathIsContentType( “hello.txt” ,“image/gif” ) 返回FALSE

PathIsHTMLFile  判斷路徑是否是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+02

E

以“科學記數法”的形式輸出有符號十進制浮點數,如2.451E+02

f

輸出有符號十進制浮點數,不帶精度時,保留6位小數

g

選用e或f格式中較短寬度的一個輸出十進制浮點數,不輸出無效零

G

選用E或f格式中較短寬度的一個輸出十進制浮點數,不輸出無效零

o

輸出無符號八進制整數

p

輸出指針變量的無符號十六進制地址值

s

輸出char類型字符串

S

輸出wchar_t類型字符串

u

輸出無符號十進制整數

x

輸出無符號小寫十六進制整數,不能輸出有符號的,如1a2b3c4d

X

輸出無符號大寫十六進制整數,不能輸出有符號的,如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+02

E

以“科學記數法”的形式輸出十進制有符號浮點數,如2.451E+02

f

輸出十進制的有符號浮點數,不帶域寬時,保留6位小數

g

選用e或f格式中較短寬度的一個輸出十進制浮點數,不輸出無效零

G

選用E或f格式中較短寬度的一個輸出十進制浮點數,不輸出無效零

o

輸出無符號八進制整數

p

輸出指針的無符號十六進制地址值

s

輸出char類型字符串

S

輸出wchar_t類型字符串

u

輸出無符號十進制整數

x

輸出無符號小寫十六進制整數 (不輸出前綴Ox),如1a2b3c4d

X

輸出無符號大寫十六進制整數 (不輸出前綴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()函數成功后才能調用本函數。

WSAENETDOWNThe network subsystem or the associated service provider has failed.

WSAEAFNOSUPPORTThe 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.

WSAEINPROGRESSA blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.

WSAEMFILENo more socket descriptors are available.

WSAEINVALAn 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.

WSAENOBUFSNo buffer space is available. The socket cannot be created.

WSAEPROTONOSUPPORTThe specified protocol is not supported.

WSAEPROTOTYPEThe specified protocol is the wrong type for this socket.

WSAEPROVIDERFAILEDINITThe 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.

WSAESOCKTNOSUPPORTThe specified socket type is not supported in this address family.

WSAINVALIDPROVIDERThe service provider returned a version other than 2.2.

WSAINVALIDPROCTABLEThe 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 SIOCGIFFLAGS

  struct sockaddr   * ifa_addr;      //Address of interface

  struct sockaddr   * ifa_netmask;   //Netmask of interface

  union

  {

    struct sockaddr * ifu_broadaddr; // Broadcast address of interface

    struct sockaddr * ifu_dstaddr;   // Point-to-point destination address

  }ifa_ifu;

  #define             ifa_broadaddr ifa_ifu.ifu_broadaddr

  #define             ifa_dstaddr   ifa_ifu.ifu_dstaddr

  void              * 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 that are currently resident in physical memory. 即: 實際在物理內存中的大小.

結合實際系統, 以我家安裝的 win8.1 為例, 打開任務管理器, 可見如下:

 

                         圖 4

工作集(內存): 可以這么理解, 此值就是該進程所占用的總物理內存. 但是這個值是由兩部分組成, 即 '專用工作集' + '共享工作集'.

內存(專用工作集): 這對於一個進程是最重要的, 它代表了一個進程獨占用了多少內存. 

內存(共享工作集): 這是該進程和別的進程共享的內存量. 通常, 這是加載一個 dll 所占用的內存. 

提交大小: 屬於 Committed 那一類. 但是不一定在物理內存中, 有些可能位於交換文件中. 如果有一個程序, 原本占 500MB 內存, 但是絕大多數內存都不使用, 則可以通過 `EmptyWorkingSet` 向操作系統發送請求, 將此進程的不常用的內容從物理內存中換出到換頁文件中保存, 如下圖:

 

                  圖 5

2.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 Time

\Processor(_Total)\% User Time

\Processor(_Total)\% Privileged Time

\Processor(_Total)\Interrupts/sec

\Processor(_Total)\% DPC Time

\Processor(_Total)\% Interrupt Time

\Processor(_Total)\DPCs Queued/sec

\Processor(_Total)\DPC Rate

\Processor(_Total)\% Idle Time

 

內存性能計數器:

\Memory\Page Faults/sec

\Memory\Available Bytes

\Memory\Pages/sec

\Memory\Pages Input/sec

\Memory\Page Reads/sec

\Memory\Pages Output/sec

\Memory\Page Writes/sec

\Memory\Cache Bytes

\Memory\System Code Total Bytes

\Memory\Available MBytes

 

網絡性能計數器:

\Network Interface(Realtek RTL8139 Family PCI Fast Ethernet NIC)\Bytes Received/sec

\Network Interface(Realtek RTL8139 Family PCI Fast Ethernet NIC)\Bytes Sent/sec

\Network 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,[輸入]:

存放計數器路徑字符串的內存指針。

格式:"\\Computer\PerfObject(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_OBJECTUnable to find the specified object on the computer or in the log file.

PDH_FUNCTION_NOT_FOUNDUnable 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,[輸入]:

存放執行可執行文件時傳遞的命令行參數字符串的內存指針,包括'\0'結束符最大長度為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\0name2=value2\0name3=value3\0……"。

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 SuspendThread

DWORD SuspendThread(HANDLE hThread);

該函數用於掛起指定的線程,如果函數執行成功,則線程的執行被終止。

 

2.12.1.3 ResumeThread

DWORD ResumeThread(HANDLE hThread);

該函數用於結束線程的掛起狀態,執行線程。 也就是恢復指定的線程

 

2.12.1.4 ExitThread

VOID ExitThread(DWORD dwExitCode);

該函數用於線程終結自身的執行,主要在線程的執行函數中被調用。其中參數dwExitCode用來設置線程的退出碼。

 

2.12.1.5 TerminateThread

BOOL 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 GetCurrentThreadId

GetCurrentThreadId()

獲取當前線程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,     //     SD  

        BOOL     bManualReset,                                                 //     reset     type  

        BOOL     bInitialState,                                                      //     initial     state  

        LPCTSTR     lpName                                                       //     object     name  

    );  

    該函數創建一個Event同步對象,如果CreateEvent調用成功的話,會返回新生成的對象的句柄,否則返回NULL。

 

參數說明:

    lpEventAttributes     一般為NULL  

 

    bManualReset          創建的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_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Windows\USERPostMessageLimit

消息隊列的最大長度至少為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'結束,該參數可以為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系統的回車換行符為'\n',而Windows系統的回車換行符為'\r\n',用此模式可以自動轉換這些字符。

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系統的回車換行符為'\n',而Windows系統的回車換行符為'\r\n',用此模式可以自動轉換這些字符。

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返回的會話句柄

FtpGetFileEx

FtpDeleteFile在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 Doe 

organization=Acme Products    

[database] 

server=192.0.2.42

; use IP address in case network name resolution is not working 

port=143 

file = "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,[輸入]:

存放多個節點名稱字符串的內存指針,節點之間用'\0'字符分隔,最后一個節點用'\0\0'結束。

例如:"key1=value1\0key2=value2\0\0"。

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,[輸出]:

存放所有的章節名稱字符串的內存指針,節點之間用'\0'字符分隔,最后一個章節用'\0\0'結束。

例如:"Section1\0Section2\0…SectionN\0\0"。

nSize,[輸入]:

存放所有的章節名稱字符串的內存的長度。

lpFileName,[輸入]:

存放INI配置文件的路徑字符串的內存指針,可以是相對或絕對路徑,包括文件名。

返回值

輸出了多少字節到存放所有的章節名稱字符串的內存,包括每個章節名稱的'\0'結束符,不包括最后一個'\0'結束符。

錯誤碼

線程安全

原子操作

是,只在調用本系列函數時。

其他說明

 

 

 

2.17.6   GetPrivateProfileSection(未完成)

函數名稱

GetPrivateProfileSection

頭文件

#include <Windows.h>

函數功能

從指定的INI配置文件的指定章節下讀取所有的節點名稱和值字符串,本系列函數支持多線程同時讀寫同一個INI配置文件。

函數聲明

DWORD GetPrivateProfileSection (

LPCWSTR lpAppName,

LPWSTR lpReturnedString,

DWORD nSize,

LPCWSTR lpFileName

);

函數參數

lpAppName,[輸入]:

存放指定的章節名稱字符串的內存指針,字符串中不區分大小寫字母。

lpszReturnBuffer,[輸出]:

存放所有的節點名稱和值字符串的內存指針,節點之間用'\0'字符分隔,最后一個節點用'\0\0'結束,例如:"Key1=Value1\0Key2=Value2\0…KeyN=ValueN\0\0"。

nSize,[輸入]:

存放所有的節點名稱和值字符串的內存的長度。

lpFileName,[輸入]:

存放INI配置文件的路徑字符串的內存指針,可以是相對或絕對路徑,包括文件名。

返回值

非0:所有的節點名稱和值字符串的長度,包括所有的分隔符'\0',不包括最后的'\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'結束符。

如果讀取失敗,返回值為0,且存放字符串值的內存的第一個字節會設置成'\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格式的文件。

waveInGetDevCaps

waveInGetErrorText

waveInGetID

waveInGetPosition

waveInMessage

waveOutBreakLoop

waveOutClose

waveOutGetDevCaps

waveOutGetErrorText

waveOutGetID

waveOutGetPitch

waveOutGetPlaybackRate

waveOutGetPosition

waveOutGetVolume

waveOutMessage

waveOutPause

waveOutPrepareHeader

waveOutReset

waveOutRestart

waveOutSetPitch

waveOutSetPlaybackRate

waveOutSetVolume

waveOutUnprepareHeader

2.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 7

WAVE_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 7

WAVE_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捕獲系統API

Detours是微軟開發的一個函數庫,可用於捕獲系統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型變量num


else cout<<num<<" "<<name<<endl; //若num不等O,輸出num,name


cout<<"in get_data()"<<endl; //輸出信息,表示目前在fet_data函數中 

}
void fun()
//過程函數(注意可見性)
  { Student stud1(1101,"tan");//建立對象studl

stud1.get_data(); 

//調用studl的getdata函數


Student stud2(0,"Li");
//建立對象stud2 
      stud2.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 begiin
call fun()
constructor-110l
//對立Student類對象stud1,num=1101
110l tan
     //對象stud1調用Student類的成員函數get_data,num不等O
in get_data()

//執行get_data
constructor-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!!\n");

    }

}

 

這段代碼的運行結果是什么?

你一定會說:"屏幕上打出oops,exception!!\n"。

沒錯,理論上的確是這樣。

我們來驗證一下,用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 list

3.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() 合並兩個list

pop_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() 合並兩個list

swap() 交換兩個list

unique() 刪除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個章節中:

  1. Linux-C成長之路(一):Linux下C編程概要 http://www.linuxidc.com/Linux/2014-05/101242.htm
  2. Linux-C成長之路(二):基本數據類型 http://www.linuxidc.com/Linux/2014-05/101242p2.htm
  3. Linux-C成長之路(三):基本IO函數操作 http://www.linuxidc.com/Linux/2014-05/101242p3.htm
  4. Linux-C成長之路(四):運算符 http://www.linuxidc.com/Linux/2014-05/101242p4.htm
  5. Linux-C成長之路(五):控制流 http://www.linuxidc.com/Linux/2014-05/101242p5.htm
  6. Linux-C成長之路(六):函數要義 http://www.linuxidc.com/Linux/2014-05/101242p6.htm
  7. Linux-C成長之路(七):數組與指針 http://www.linuxidc.com/Linux/2014-05/101242p7.htm
  8. Linux-C成長之路(八):存儲類,動態內存 http://www.linuxidc.com/Linux/2014-05/101242p8.htm
  9. Linux-C成長之路(九):復合數據類型 http://www.linuxidc.com/Linux/2014-05/101242p9.htm
  10. Linux-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 input
map<string, int> word_count; // empty map from string to int 
// get an iterator to an element in word_count
map<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 element
cout << " " << map_it->second; // prints the value of the element
 
map_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成員具有const map<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 value
word_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 input
map<string, int> word_count; // empty map from string to int    
string 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 1
word_count.insert(map<string, int>::value_type("Anna", 1));

上面語句的實參可以簡化如下兩種方法:

(1) word_count.insert(make_pair("Anna", 1));

(2)使用 typedef

    typedef 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_Hu
int 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\t\t" << "times" << endl;
 for (valType iter = wordCount.begin(); iter != wordCount.end(); ++iter)
 {
  cout << (*iter).first << "\t\t" << (*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\t\t" << "times" << endl;for (valType iter = word_count.begin(); iter != word_count.end(); ++iter){cout
 << (*iter).first << "\t\t" << (*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_Hu
using 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 output
 map<string, string> trans_map;
    string key, value;
 
 // ´´½¨Á÷
 ifstream myfile ("trans_map.txt");
 ifstream myfilein ("in.txt");
 ofstream outfile("out.txt");
 // ÅжÏÎļþÊÇ·ñ´ò¿ª
 if(!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 map 
    while (myfile >> key >> value) 
 {
  trans_map.insert(make_pair(key, value));
 }
 
 // this block just produces the vector so that we can print it
 // for the book
 cout << "Here is our transform string input:\n\n";
 // read some text to transform
 string word;
 
    // ok, now we're ready to do the transformations
    // open the input file and check that the open succeeded
 string WORD;
 bool firstword = true;  // controls whether a space is printed 
 while (myfilein >> WORD) 
 {
  // ok: the actual mapwork, this part is the heart of the program
  map<string, string>::const_iterator map_it =
   trans_map.find(WORD);
  
  // if this word is in the transformation map
  if (map_it != trans_map.end()) 
  {
   // replace it by the transformation value in the map
   WORD = map_it->second;  
  }
  if (firstword)
   firstword = false;
  else
   cout << " ";  // print space between words
  cout << WORD;
 }
 cout << endl;        // done with this line of input
    return 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)的移動網絡設備。

注意:只有Windows 7和Windows Server 2008 R2及以后的系統支持此類型設備。

IF_TYPE_WWANPP(243)

基於GSM全球移動通信系統(Global System for Mobile communication)標准的移動網絡設備。

注意:只有Windows 7和Windows Server 2008 R2及以后的系統支持此類型設備。

IF_TYPE_WWANPP2(244)

基於CDMA碼分多址技術的移動網絡設備。

注意:只有Windows 7和Windows Server 2008 R2及以后的系統支持此類型設備。

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參數描述字符串的長度,包括'\0'結束符。

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 columns

    PUINT 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 puColumns

 

iItem

存放項目的項目索引號,本參數只能大於等於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_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time 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           0x0249

WAVE_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                       0x2001

WAVE_FORMAT_MAKEAVIS                   0x3313

WAVE_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                   0x706D

WAVE_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                    0xA10D

WAVE_FORMAT_GSM_620                    0xA10E

WAVE_FORMAT_GSM_660                    0xA10F

WAVE_FORMAT_GSM_690                    0xA110

WAVE_FORMAT_GSM_ADAPTIVE_MULTIRATE_WB  0xA111

WAVE_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格式的額外信息系數對編碼和波形音頻數據解碼所需。

 

 

4.11.2   WAVEHDR(未完成)

結構體名稱

WAVEHDR

頭文件

#include <mmeapi.h>

結構體說明

音頻數據塊結構體,用於存放音頻輸入設備和播放設備的一個音頻數據塊。

相關函數

waveInPrepareHeader()、Func2()、Func3()…

結構體聲明

struct WAVEHDR

{

    LPSTR       lpData;                 /* pointer to locked data buffer */

    DWORD       dwBufferLength;         /* length of data buffer */

    DWORD       dwBytesRecorded;        /* used for input only */

    DWORD_PTR   dwUser;                 /* for client's use */

    DWORD       dwFlags;                /* assorted flags (see defines) */

    DWORD       dwLoops;                /* loop control counter */

    struct WAVEHDR * lpNext;     /* reserved for driver */

    DWORD_PTR   reserved;               /* reserved for driver */

};

成員變量

lpData

存放音頻數據塊的實際數據數組的內存指針。

dwBufferLength

存放音頻數據塊的實際數據數組的內存長度,單位字節。

dwBytesRecorded

存放在音頻數據塊的實際數據數組中,實際數據的內存長度,單位字節。

dwUser

存放音頻的額外信息。

如果音頻的格式為PCM格式,本參數無意義。

dwFlags

存放音頻數據塊的控制標記,可以為(用'|'選零至多個):

WHDR_DONE宏(0x0001)Set by the device driver to indicate that it is finished with the buffer and is returning it to the application.

WHDR_PREPARED宏(0x0002)Set by Windows to indicate that the buffer has been prepared with the waveInPrepareHeader or waveOutPrepareHeader function.

WHDR_BEGINLOOP宏(0x0004)This buffer is the first buffer in a loop. This flag is used only with output buffers.

WHDR_ENDLOOP宏(0x0008)This buffer is the last buffer in a loop. This flag is used only with output buffers.

WHDR_INQUEUE宏(0x0010)Set by Windows to indicate that the buffer is queued for playback.

dwLoops

存放播放循環次數,本參數只針對播放設備有效,音頻輸入設備無意義。

lpNext

本參數無意義。

reserved

本參數無意義。

其他說明

 

 

 

5   errno錯誤碼

注意:數值在不同的操作系統上可能不一樣。

 

EPERM            (1) /* Operation not permitted */

ENOENT           (2) /* No such file or directory */

ESRCH            (3) /* No such process */

EINTR            (4) /* Interrupted system call */

EIO              (5) /* Input/output error */

ENXIO            (6) /* No such device or address */

E2BIG            (7) /* Argument list too long */

ENOEXEC          (8) /* Exec format error */

EBADF            (9) /* Bad file descriptor */

ECHILD           (10)/* No child processes */

EDEADLK          (11)/* Resource deadlock avoided */

ENOMEM           (12)/* Cannot allocate memory */

EACCES           (13)/* Permission denied */

EFAULT           (14)/* Bad address */

ENOTBLK          (15)/* Block device required */

EBUSY            (16)/* Device or resource busy */

EEXIST           (17)/* File exists */

EXDEV            (18)/* Invalid cross-device link */

ENODEV           (19)/* No such device */

ENOTDIR          (20)/* Not a directory */

EISDIR           (21)/* Is a directory */

EINVAL           (22)/* Invalid argument */

EMFILE           (24)/* Too many open files */

ENFILE           (23)/* Too many open files in system */

ENOTTY           (25)/* Inappropriate ioctl for device */

ETXTBSY          (26)/* Text file busy */

EFBIG            (27)/* File too large */

ENOSPC           (28)/* No space left on device */

ESPIPE           (29)/* Illegal seek */

EROFS            (30)/* Read-only file system */

EMLINK           (31)/* Too many links */

EPIPE            (32)/* Broken pipe */

EDOM             (33)/* Numerical argument out of domain */

ERANGE           (34)/* Numerical result out of range */

EAGAIN           (35)/* Resource temporarily unavailable */

EWOULDBLOCK   EAGAIN /* Operation would block */

EINPROGRESS      (36)/* Operation now in progress */

EALREADY         (37)/* Operation already in progress */

ENOTSOCK         (38)/* Socket operation on non-socket */

EDESTADDRREQ     (39)/* Destination address required */

EMSGSIZE         (40)/* Message too long */

EPROTOTYPE       (41)/* Protocol wrong type for socket */

ENOPROTOOPT      (42)/* Protocol not available */

EPROTONOSUPPORT  (43)/* Protocol not supported */

ESOCKTNOSUPPORT  (44)/* Socket type not supported */

EOPNOTSUPP       (45)/* Operation not supported */

EPFNOSUPPORT     (46)/* Protocol family not supported */

EAFNOSUPPORT     (47)/* Address family not supported by protocol */

EADDRINUSE       (48)/* Address already in use */

EADDRNOTAVAIL    (49)/* Cannot assign requested address */

ENETDOWN         (50)/* Network is down */

ENETUNREACH      (51)/* Network is unreachable */

ENETRESET        (52)/* Network dropped connection on reset */

ECONNABORTED     (53)/* Software caused connection abort */

ECONNRESET       (54)/* Connection reset by peer */

ENOBUFS          (55)/* No buffer space available */

EISCONN          (56)/* Transport endpoint is already connected */

ENOTCONN         (57)/* Transport endpoint is not connected */

ESHUTDOWN        (58)/* Cannot send after transport endpoint shutdown */

ETOOMANYREFS     (59)/* Too many references: cannot splice */

ETIMEDOUT        (60)/* Connection timed out */

ECONNREFUSED     (61)/* Connection refused */

ELOOP            (62)/* Too many levels of symbolic links */

ENAMETOOLONG     (63)/* File name too long */

EHOSTDOWN        (64)/* Host is down */

EHOSTUNREACH     (65)/* No route to host */

ENOTEMPTY        (66)/* Directory not empty */

EPROCLIM         (67)/* Too many processes */

EUSERS           (68)/* Too many users */

EDQUOT           (69)/* Disk quota exceeded */

ESTALE           (70)/* Stale NFS file handle */

EREMOTE          (71)/* Object is remote */

EBADRPC          (72)/* RPC struct is bad */

ERPCMISMATCH     (73)/* RPC version wrong */

EPROGUNAVAIL     (74)/* RPC program not available */

EPROGMISMATCH    (75)/* RPC program version wrong */

EPROCUNAVAIL     (76)/* RPC bad procedure for program */

ENOLCK           (77)/* No locks available */

ENOSYS           (78)/* Function not implemented */

EFTYPE           (79)/* Inappropriate file type or format */

EAUTH            (80)/* Authentication error */

ENEEDAUTH        (81)/* Need authenticator */

ELAST            (81)/* Must be equal largest errno */

EBACKGROUND      (100)/* Inappropriate operation for background process */

EDIED            (101)/* Translator died */

ED               (102)/* ? */

EGREGIOUS        (103)/* You really blew it this time */

EIEIO            (104)/* Computer bought the farm */

EGRATUITOUS      (105)/* Gratuitous error */

EILSEQ           (106)/* Invalid or incomplete multibyte or wide character */

EBADMSG          (107)/* Bad message */

EIDRM            (108)/* Identifier removed */

EMULTIHOP        (109)/* Multihop attempted */

ENODATA          (110)/* No data available */

ENOLINK          (111)/* Link has been severed */

ENOMSG           (112)/* No message of desired type */

ENOSR            (113)/* Out of streams resources */

ENOSTR           (114)/* Device not a stream */

EOVERFLOW        (115)/* Value too large for defined data type */

EPROTO           (116)/* Protocol error */

ETIME            (117)/* Timer expired */

ECANCELED        (118)/* Operation canceled */

ENOTSUP          (118)/* Not supported */

6   轉義字符

字符

進制

十六

進制

對應按鍵

名稱

Windows控制台下輸出效果

例子

\a

7

0x7

響鈴符(BEL)

在支持的設備(終端)上鳴響一聲

 

\b

8

0x8

Backspace

退格

退格符(BS)

光標在當前位置左移一格

 

\f

12

0xC

分頁符(FF)

打印機跳到下一頁打印

 

\n

10

0xA

Enter

回車

回車換行符(LF)

光標跳到下一行行首

 

\r

13

0xD

回車符(CR)

光標回到當前行首

printf("123456\rABC");

屏幕上輸出:ABC456

\t

9

0x9

Tab

制表

水平制表符(HT)

光標水平跳到下一個制表位

 

\v

11

0xB

垂直制表符(VT)

不支持

 

\?

63

0x3F

?

問號

 

打印一個‘?’

正確:printf("\?");

printf("?");

\\

92

0x5C

\

反斜杠

 

打印一個‘\’

正確:printf("\\");

錯誤:printf("\");

\'

39

0x27

'

單引號

 

打印一個‘'’

正確:printf("\'");

錯誤:printf("'");

\"

34

0x22

"

雙引號

 

打印一個‘"’

正確:printf("\"");

錯誤:printf(""");

\0

0

0x0

NULL

空字符

 

字符串結束標記

printf("abc\0efg");

輸出:abc

\xhh

       

對應一個十六進制ASCII碼值的字符

'\x0A' 相當於 '\n'

'\x1B' 相當於 '\e'

正確:printf("\xA");

printf("\x00a");

錯誤:printf("\x100");

printf("\x");

\bbb

       

對應一個八進制ASCII碼值的字符

'\101' 相當於 'A'

'\033' 相當於 '\e'

printf("\071");

輸出:9

printf("\1013");

輸出:A3

printf("\778");

輸出:?8

           

 

\e

27

0x1B

Esc

退出

操作符

不支持

 

\e[0m

       

不支持

 

\e[1m

       

不支持

 

\e[4m

       

不支持

 

\e[5m

       

不支持

 

\e[7m

       

不支持

 

\e[8m

       

不支持

 

\e[30m

       

不支持

 

\e[31m

       

不支持

 

\e[32m

       

不支持

 

\e[33m

       

不支持

 

\e[34m

       

不支持

 

\e[35m

       

不支持

 

\e[36m

       

不支持

 

\e[37m

       

不支持

 

\e[40m

       

不支持

 

\e[41m

       

不支持

 

\e[42m

       

不支持

 

\e[43m

       

不支持

 

\e[44m

       

不支持

 

\e[45m

       

不支持

 

\e[46m

       

不支持

 

\e[47m

       

不支持

 

\e[nA

       

不支持

 

\e[nB

       

不支持

 

\e[nC

       

不支持

 

\e[nD

       

不支持

 

\e[y;xH

       

不支持

 

\e[2J

       

不支持

 

\e[K

       

不支持

 

\e[s

       

不支持

 

\e[u

       

不支持

 

\e[?25l

       

不支持

 

\e[?25h

       

不支持

 

 

7   常量類型

與變量類似,常量實際上也有多種細分的類型。在C語言中變量需要先定義類型才能在語句中使用,而常量有默認的類型。

數值末尾不添加類型說明符的整型常量默認為是int型的。超出int型范圍的整型常量,默認為是long型的。也就是說,整型常量1234一定是int類型的,而整型常量123467(超過了32767)在int型最大值是32767的系統中是long型的。

數值末尾不添加類型說明符的浮點型常量默認為是double型的。也就是說,任意一個浮點型常量,不論是小數形式表示的,還是指數形式表示的,只要數的末尾沒有加類型說明符F(或者f),一律被編譯程序當成是double型的常量。

如果默認的類型不合適,可以在常量的末尾加上類型說明符。

對於整型常量,可在末尾加U表示無符號整型或加L表示長整型;在整型常量的開頭,還可加上進制說明符,以0開頭表示八進制整數,0x或0X開頭表示十六進制整數。

對浮點型常量,在末尾可加F(或f),表示該常量是單精度浮點型。

(1)數值常量的存儲類型(初學時不必看)

與基本類型變量一樣,常量也分為三大類型:字符型、整型和浮點型。除了字符型常量比較簡單外,常量根據在內存中存儲方式(參見本章提高部分)的不同,可細分為很多類型。所有常量的(不同存儲)類型請參見表3-2:

 

說明:說明常量類型的字符U、L、F都可以用小寫字符u、l、f,多個類型符號連在一起書寫時,符號之間的順序是任意的。比如,123UL、 123LU、123ul都是一樣的。

總之,數值末尾不添加類型說明符的整型常量(比如123)默認是int型的,但是該數的值如果超出了int型的范圍,那么該數默認是long型的;不添加類型說明符的實型常量(比如123.34)一定是double型的。

其他強制指定的常量類型一般很少使用。強制指定常量類型常常是為了減少程序運行時的類型轉換。比如在變量定義時,使用“float  x = 123.3F;”就比使用“floatx=123.3 ;”要好,前者避免了一次不必要的運行時的類型轉換。

(2)數值常量的多種機外書寫形式(初學時不必看)

上表中對常量的分類,是一種本質上的分類,因為上表中各種不同的常量在內存中的存儲方式不同(參見本章提高部分)。但是,常量還可以根據在源程序中的書寫(或輸入輸出中的)形式來進行分類。

上一章已經講過,浮點型常量有兩種書寫形式:十進制小數形式和十進制指數形式。如,小數形式123.45和指數形式1.2345e2,在內存中其實是具有完全相同存儲形式的浮點數(默認為double型的)。它們僅僅是在程序中(或輸入輸出時)的表現形式不同而已。再加上不同的存儲形式(double型與float型),數值大小相同(取值不超過float型范圍)的浮點型常量一共有4種機外表示形式:123.45、1.2345e2、123.45f、1.2345e2f。

整型常量在C語言源程序中(或程序運行的輸入輸出時),除了可以用十進制形式書寫(或輸入輸出)之外,還可以使用八進制和十六進制形式來書寫(或輸入輸出)。

八進制整型常量:常量中只包含數字0~7,用0開頭表示的數都是八進制整型常量。比如,034、065、–013。

十六進制整型常量:常量中包含數字0~9和字符a~f(或者用A~F),以0x(或0X)開頭的,都是十六進制整型常量。比如,0x3d、 0XEF、–0x8a等。

同一個十進制整數123(默認為int型),還可以用八進制整數0173來表示,或者用十六進制整數0x7B來表示。它們也僅僅是在程序中(或輸入輸出時)的表現形式不同而已,在計算機內部,它們是形式完全相同的二進制整數0000000001111011(假設int型占2個字節)。再加上不同的存儲形式(int、long、unsigned、unsigned long),數值大小相同且值不超過int范圍的整型常量一共有3×4=12種機外表示形式:123、123L、123U、123UL、0173、0173L、0173U、0173UL、0x7B、0x7BL、0x7BU、0x7BUL。

八進制和十六進制整數主要應用在系統編程和嵌入式編程方面(主要原因在於:機外形式的八進制和十六進制整數與機內形式的二進制整數之間很容易進行相互轉換)。如果一個二進制整數中的n個位分別用來表示n個開關的狀態,在用C語言編程時,那么就最好使用無符號的八進制整數(或無符號十六進制的整數)來表示此二進制整數,C語言的源程序中無法直接使用二進制整數。

8   ASCII碼字符表

二進制

八進制

十進制

十六進制

對應按鍵

縮寫/字符

解釋

0000 0000

000

0

00

 

NUL (null)

空字符

0000 0001

001

1

01

 

SOH (start of headline)

標題開始

0000 0010

002

2

02

 

STX (start of text)

正文開始

0000 0011

003

3

03

 

ETX (end of text)

正文結束

0000 0100

004

4

04

 

EOT (end of transmission)

傳輸結束

0000 0101

005

5

05

 

ENQ (enquiry)

請求

0000 0110

006

6

06

 

ACK (acknowledge)

收到通知

0000 0111

007

7

07

 

BEL (bell)

響鈴

0000 1000

010

8

08

 

BS (backspace)

退格

0000 1001

011

9

09

Tab制表

HT (horizontal tab)

水平制表符

0000 1010

012

10

0A

Enter回車

LF (NL line feed, new line)

換行鍵

0000 1011

013

11

0B

 

VT (vertical tab)

垂直制表符

0000 1100

014

12

0C

 

FF (NP form feed, new page)

換頁鍵

0000 1101

015

13

0D

 

CR (carriage return)

回車鍵

0000 1110

016

14

0E

 

SO (shift out)

不用切換

0000 1111

017

15

0F

 

SI (shift in)

啟用切換

0001 0000

020

16

10

 

DLE (data link escape)

數據鏈路轉義

0001 0001

021

17

11

 

DC1 (device control 1)

設備控制1

0001 0010

022

18

12

 

DC2 (device control 2)

設備控制2

0001 0011

023

19

13

 

DC3 (device control 3)

設備控制3

0001 0100

024

20

14

 

DC4 (device control 4)

設備控制4

0001 0101

025

21

15

 

NAK (negative acknowledge)

拒絕接收

0001 0110

026

22

16

 

SYN (synchronous idle)

同步空閑

0001 0111

027

23

17

 

ETB (end of trans. block)

傳輸塊結束

0001 1000

030

24

18

 

CAN (cancel)

取消

0001 1001

031

25

19

 

EM (end of medium)

介質中斷

0001 1010

032

26

1A

 

SUB (substitute)

替補

0001 1011

033

27

1B

 

ESC (escape)

換碼(溢出)

0001 1100

034

28

1C

 

FS (file separator)

文件分割符

0001 1101

035

29

1D

 

GS (group separator)

分組符

0001 1110

036

30

1E

 

RS (record separator)

記錄分離符

0001 1111

037

31

1F

 

US (unit separator)

單元分隔符

0010 0000

040

32

20

Space空格

  (space)

空格

0010 0001

041

33

21

 

!

 

0010 0010

042

34

22

 

"

 

0010 0011

043

35

23

 

#

 

0010 0100

044

36

24

 

$

 

0010 0101

045

37

25

 

%

 

0010 0110

046

38

26

 

&

 

0010 0111

047

39

27

 

'

 

0010 1000

050

40

28

 

(

 

0010 1001

051

41

29

 

)

 

0010 1010

052

42

2A

 

*

 

0010 1011

053

43

2B

 

+

 

0010 1100

054

44

2C

 

,

 

0010 1101

055

45

2D

 

-

 

0010 1110

056

46

2E

 

.

 

0010 1111

057

47

2F

 

/

 

0011 0000

060

48

30

 

0

 

0011 0001

061

49

31

 

1

 

0011 0010

062

50

32

 

2

 

0011 0011

063

51

33

 

3

 

0011 0100

064

52

34

 

4

 

0011 0101

065

53

35

 

5

 

0011 0110

066

54

36

 

6

 

0011 0111

067

55

37

 

7

 

0011 1000

070

56

38

 

8

 

0011 1001

071

57

39

 

9

 

0011 1010

072

58

3A

 

:

 

0011 1011

073

59

3B

 

;

 

0011 1100

074

60

3C

 

 

0011 1101

075

61

3D

 

=

 

0011 1110

076

62

3E

 

 

0011 1111

077

63

3F

 

?

 

0100 0000

100

64

40

 

@

 

0100 0001

101

65

41

 

A

 

0100 0010

102

66

42

 

B

 

0100 0011

103

67

43

 

C

 

0100 0100

104

68

44

 

D

 

0100 0101

105

69

45

 

E

 

0100 0110

106

70

46

 

F

 

0100 0111

107

71

47

 

G

 

0100 1000

110

72

48

 

H

 

0100 1001

111

73

49

 

I

 

0100 1010

112

74

4A

 

J

 

0100 1011

113

75

4B

 

K

 

0100 1100

114

76

4C

 

L

 

0100 1101

115

77

4D

 

M

 

0100 1110

116

78

4E

 

N

 

0100 1111

117

79

4F

 

O

 

0101 0000

120

80

50

 

P

 

0101 0001

121

81

51

 

Q

 

0101 0010

122

82

52

 

R

 

0101 0011

123

83

53

 

S

 

0101 0100

124

84

54

 

T

 

0101 0101

125

85

55

 

U

 

0101 0110

126

86

56

 

V

 

0101 0111

127

87

57

 

W

 

0101 1000

130

88

58

 

X

 

0101 1001

131

89

59

 

Y

 

0101 1010

132

90

5A

 

Z

 

0101 1011

133

91

5B

 

[

 

0101 1100

134

92

5C

 

\

 

0101 1101

135

93

5D

 

]

 

0101 1110

136

94

5E

 

^

 

0101 1111

137

95

5F

 

_

 

0110 0000

140

96

60

 

`

 

0110 0001

141

97

61

 

a

 

0110 0010

142

98

62

 

b

 

0110 0011

143

99

63

 

c

 

0110 0100

144

100

64

 

d

 

0110 0101

145

101

65

 

e

 

0110 0110

146

102

66

 

f

 

0110 0111

147

103

67

 

g

 

0110 1000

150

104

68

 

h

 

0110 1001

151

105

69

 

i

 

0110 1010

152

106

6A

 

j

 

0110 1011

153

107

6B

 

k

 

0110 1100

154

108

6C

 

l

 

0110 1101

155

109

6D

 

m

 

0110 1110

156

110

6E

 

n

 

0110 1111

157

111

6F

 

o

 

0111 0000

160

112

70

 

p

 

0111 0001

161

113

71

 

q

 

0111 0010

162

114

72

 

r

 

0111 0011

163

115

73

 

s

 

0111 0100

164

116

74

 

t

 

0111 0101

165

117

75

 

u

 

0111 0110

166

118

76

 

v

 

0111 0111

167

119

77

 

w

 

0111 1000

170

120

78

 

x

 

0111 1001

171

121

79

 

y

 

0111 1010

172

122

7A

 

z

 

0111 1011

173

123

7B

 

{

 

0111 1100

174

124

7C

 

|

 

0111 1101

175

125

7D

 

}

 

0111 1110

176

126

7E

 

~

 

0111 1111

177

127

7F

 

DEL (delete)

刪除

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM