C++ WINDOWS API 第2章 Windows API概要
目錄
2.1?????? Windows數(shù)據(jù)類型.. 1
2.1.1?????? Windows數(shù)據(jù)類型示例.. 1
2.1.2?????? Windows 數(shù)據(jù)類型與標(biāo)準(zhǔn)C 數(shù)據(jù)類型的關(guān)系.. 5
2.1.3?????? Windows 數(shù)據(jù)類型與Windows API 5
2.1.4?????? Windows 中的數(shù)據(jù)結(jié)構(gòu).. 6
2.2?????? Windows API 的功能分類.. 7
2.2.1?????? 系統(tǒng)基本服務(wù).. 7
2.2.2?????? 系統(tǒng)管理.. 9
2.2.3?????? 用戶界面.. 9
2.2.4?????? 圖像和多媒體.. 15
2.2.5?????? 網(wǎng)絡(luò).. 15
2.2.6?????? 其他功能.. 15
2.3?????? Windows API核心DLL. 16
2.3.1?????? Kerne132.dll 16
2.3.2?????? User32.dll 16
2.3.3?????? Gdi32.dll 16
2.3.4?????? 標(biāo)準(zhǔn)C函數(shù).. 17
2.3.5?????? 其他Dll 17
2.4?????? Unicode和多字節(jié).. 17
2.4.1?????? W版本和A版本的API 21
2.4.2?????? Unicode與ASGII的轉(zhuǎn)換.. 22
2.4.3?????? 對Windows程序設(shè)計規(guī)范的建議.. 22
2.5?????? 小結(jié).. 23
?
?
?
2.1??? Windows數(shù)據(jù)類型
Windows API 使用了很多 Windows 自己定義的數(shù)據(jù)類型。讀者可能較為熟悉 C 語言或 C++語言的數(shù)據(jù)類型。要熟練使用 Windows API 必須要熟悉 Windows 數(shù)據(jù)類型。這些數(shù)據(jù)類型是Windows 特有的。在 SDK 的相關(guān)頭文件中有定義。
在眾多的Windows 數(shù)據(jù)類型中,最常用的有 DWORD、HANDLE、LPTSTR、WORD、BYTE、CHAR 等。在 Windows 系統(tǒng)中,DWORD 用于表示無符號整型的數(shù)據(jù),意為 double word,32位。
在一般情況下 BYTE 是 8 位的,而 WORD 是 16 位,DWORD 就是 32 位的。
Windows 系統(tǒng)的應(yīng)用程序中還具有一個特有的數(shù)據(jù)類型-HANDLE,通常 HANDLE 類型的變量用于唯一標(biāo)識一個“對象”,如窗口、控件、文件等,Windows 平臺中存在眾多這樣的對象,對象是程序操作的目標(biāo)。HANDLE 也是一個 32 位的數(shù)據(jù)類型。
2.1.1??? Windows數(shù)據(jù)類型示例
實例2-1使用了幾種基本的 Windows 數(shù)據(jù)類型,演示 Windows 數(shù)據(jù)類型在程序中的使用方法。
本實例定義了幾個常用常量的 Windows 數(shù)據(jù)類型,包括 DWORD,LPSTR 和 CHAR,并演示了如何使用它們進(jìn)行了復(fù)制、比較大小等操作。
/* ************************************ *《精通 Windows API》 * 示例代碼 * windata.c * 2.1.1 常用的 Windows 數(shù)據(jù)類型 **************************************/ /* 頭文件 */ #include <windows.h> #include <stdio.h> /* ************************************ * 功能 Windows 數(shù)據(jù)類型演示 **************************************/ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { //定義字符串 LPSTR szString = "Windows data type, string."; //定義字符數(shù)組 CHAR lpString[120];//要大于 szString 的長度 //定義 DWORD 類型的數(shù)據(jù) DWORD dwMax = 0xFFFFFFFF; DWORD dwOne = 0x1; //定義 INT 類型的數(shù)據(jù) INT iMax = 0xFFFFFFFF; INT iOne = 0x1; //顯示字符串 MessageBox(NULL,szString,"LPSTR",MB_OK); //復(fù)制內(nèi)存,將字符串復(fù)制到數(shù)組中(包括 NULL 結(jié)束符) CopyMemory(lpString, szString,lstrlen(szString)+1); //顯示復(fù)制的字符串 MessageBox(NULL,lpString,"CHAR[]",MB_OK); //比較 DWORD 并顯示結(jié)果 if(dwMax>dwOne) { MessageBox(NULL,"DWORD 類型的數(shù)據(jù) OxFFFFFFFF > 0x1","DWORD",MB_OK); } //比較 INT 并顯示結(jié)果 if(iMax<iOne) { MessageBox(NULL,"INT 類型的數(shù)據(jù) OxFFFFFFFF < 0x1","INT",MB_OK); } return 0; }?
?
在這個程序中,使用了 4 種 Windows 數(shù)據(jù)類型,分別是 LPSTR、CHAR、DWORD 和 INT。
LPSTR 類型的數(shù)據(jù)是字符串,也就是字符指針,CHAR 是字符,DWORD 是 32 位的無符號整數(shù),INT 是 32 位有符號整數(shù)。程序運行后會彈出 4 個對話框。這說明 dwMax>dwOne 是成立的。iMax<iOne 也是成立的。dwMax 與 iMax 的數(shù)值是一樣的,dwOne 與 iOne 的數(shù)值也是一樣的。但是比較結(jié)果不同,是因為二者的數(shù)據(jù)類型不一樣。
?
在 Visual Studio 中可以查看數(shù)據(jù)類型的定義。在數(shù)據(jù)類型的類型名(比如“DWORD”)上單擊右鍵,選擇“轉(zhuǎn)到定義”,如圖 2-1 所示。
?
圖2-1
可以從 SDK 的頭文件中看到各類型的類型定義。
“INT”的定義如下:
typedef int INT;?
“DWORD”的定義如下:
typedef unsigned long DWORD;?
"CHAR"的定義如下:
typedef char CHAR;?
??? 從中可以發(fā)現(xiàn),這些 Windows 數(shù)據(jù)類型都是從標(biāo)準(zhǔn) C 的數(shù)據(jù)類型經(jīng)過類型重定義而來。INT 數(shù)據(jù)類型是有符號整型,DWORD 數(shù)據(jù)類型是無符號整型。 這就說明了為什么在實例 2-1 中 INT 數(shù)據(jù)類型的變量 iMax 實際是“-1”,而 DWORD 類型的變量 dwMax 實際是“4294967295”,所以會出現(xiàn)如上的比較結(jié)果。
表2.1 常用的基本W(wǎng)indows數(shù)據(jù)類型
| 類型 | 描述 |
| BOOL | 布爾型變量(值只能是True或False) |
| BYTE | 字節(jié)類型(8位) |
| CHAR | 8比特字節(jié)(ANSI) |
| CONST | 常量,相當(dāng)于標(biāo)準(zhǔn)C中的”const”關(guān)鍵字 |
| DWORD | 32字節(jié)無符號整型數(shù)據(jù) |
| DWORD32 | 32字節(jié)無符號整型數(shù)據(jù) |
| DWORD64 | 64字節(jié)無符號整型數(shù)據(jù) |
| FLOAT | 浮點數(shù)據(jù)類型 |
| HANDLE | 對象的句柄,最基本的句柄類型 |
| HICON | 圖標(biāo)的句柄 |
| HINSTANCE | 程序?qū)嵗木浔?/p> |
| HKEY | 注冊表鍵的句柄 |
| HMODULE | 模塊的句柄 |
| HWND | 窗口的句柄 |
| INT | 32位符號整型數(shù)據(jù)類型 |
| INT_PTR | 指向INT類型數(shù)據(jù)的指針類型 |
| INT32 | 32位符號整型 |
| INT64 | 64位符號整型 |
| LONG | 32位符號整型,相當(dāng)于C語言的標(biāo)準(zhǔn)數(shù)據(jù)類型long |
| LONGLONG | 64位符號整型 |
| LONG32 | 32位符號整型 |
| LONG64 | 64位符號整型 |
| LPARAM | 消息的L參數(shù) |
| WPARAM | 消息的W參數(shù) |
| LPCSTR | Windows(ANSI)字符串常量 |
| LPCTSTR | 根據(jù)環(huán)境配置,如果定義了UNICODE宏,則是LPCWSTR類型,否則是LPCSTR類型 |
| LPCWSTR | UNICODE字符串常量 |
| LPDWORD | 指向DWORD類型數(shù)據(jù)的指針 |
| LPSTR | Windows(ANSIC)字符串常量 |
| LPTSTR | 根據(jù)環(huán)境配置,如果定義了UNICODE宏,則是LPTSTR類型,否則是LPSTR類型 |
| LPWSTR | UNICODE字符串常量 |
| SHORT | 無符號短整型(16位) |
| SIZE_T | 表示內(nèi)存大小,以字節(jié)為單位,其最大值是CPU最大尋址范圍 |
| TCHAR | 如果定義了UNICOD,則為WCHAR,否則為CHAR |
| UCHAR | 無符號CHAR |
| UINT | 無符號INT |
| ULONG | 無符號LONG |
| VOID | 無類型,相當(dāng)于標(biāo)準(zhǔn)C語言的void |
| WCHAR | 16位Unicode字符 |
| WINAPI | Windows API的函數(shù)調(diào)用方式,常見于SDK頭文件中對API函數(shù)的聲明中,相當(dāng)于__stdcall(更嚴(yán)格講,不是數(shù)據(jù)類型,而是函數(shù)調(diào)用約定) |
| WORD | 16位無符號整型數(shù)據(jù) |
Windows 數(shù)據(jù)類型的命名都很有規(guī)律。
基本數(shù)據(jù)類型包括 BYTE、CHAR、WORD、SHORT、DOWRD、INT 等。
指針類型的命令方式一般是在其指向的數(shù)據(jù)類型前加“LP”或“P”,比如指向 DWORD的指針類型為“LPDWORD”和“PDWORD”。
各種句柄類型的命令方式一般都是在對象名前加“H”。Windows 系統(tǒng)中有很多對象,所有表示一個對象的數(shù)據(jù)類型都是句柄,每一種對象都對應(yīng)著一種句柄類型,比如與位圖( BITMAP)對應(yīng)的句柄類型為“HBITMAP”,與菜單(MENU)對應(yīng)的句柄類型為“HMENU”,與窗口(WINDOW)對應(yīng)的句柄類型為“HWND”。無符號類型一般是以“U”開頭,比如“INT”是符號類型,“UINT”是無符號類型,“LONG”是符號類型“ULONG”是無符號類型等。
2.1.2??? Windows 數(shù)據(jù)類型與標(biāo)準(zhǔn)C 數(shù)據(jù)類型的關(guān)系
查看 Windows 數(shù)據(jù)類型的定義可以看到,所有的 Windows 數(shù)據(jù)類型都是由 C 數(shù)據(jù)類型經(jīng)過類型重定義得到的。如 DWORD 實質(zhì)上就是 unsigned long 數(shù)據(jù)類型,32 位的無符號整型:
typedef unsigned long DWORD;?
實際上 VC 編譯器是一個完整的 C 編譯器,此外并沒有過多的擴(kuò)展。Windows 數(shù)據(jù)類型也不是 VC 的內(nèi)建類型,而從標(biāo)準(zhǔn) C 類型重定義得到。
2.1.3??? Windows 數(shù)據(jù)類型與Windows API
Windows API 函數(shù)的參數(shù)、返回值或一些重要的常量使用的數(shù)據(jù)類型都是 Windows 數(shù)據(jù)類型。如:
int MessageBox( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType );?
MessageBox 函數(shù)的返回值是 int 型的,是標(biāo)準(zhǔn) C 數(shù)據(jù)類型,但是所有的參數(shù)都使用了Windows 數(shù)據(jù)類型。如 HWND 是一種 W indows 數(shù)據(jù)類型,用于表示窗口的句柄;LPCTSTR 也是Windows 數(shù)據(jù)類型,表示字符串常量;UINT 也是 Windows 數(shù)據(jù)類型,為無符號整型。
2.1.4??? Windows 中的數(shù)據(jù)結(jié)構(gòu)
Windows 中包含很多種數(shù)據(jù)結(jié)構(gòu)類型,在不同類型的 API 中會使用到不同的數(shù)據(jù)結(jié)構(gòu),由于數(shù)據(jù)結(jié)構(gòu)的數(shù)量眾多,將在后續(xù)章節(jié)具體的實例中介紹實現(xiàn)每一種功能所使用的數(shù)據(jù)結(jié)構(gòu)。數(shù)據(jù)結(jié)構(gòu)通常會作為一些 API 的參數(shù)輸入。
typedef struct _WIN32_FILE_ATTRIBUTE_DATA{ DWORD dwFileAttributes; FILETIME ftCreationTime; FILETIME ftLastAccessTime; FILETIME ftLastWriteTime; DWORD nFileSizeHigh; DWORD nFileSizeLow; } WIN32_FILE_ATTRIBUTE_DATA,*LPWIN32_FILE_ATTRIBUTE_DATA;?
相當(dāng)于:
typedef struct _WIN32_FILE_ATTRIBUTE_DATA{ DWORD dwFileAttributes; FILETIME ftCreationTime; FILETIME ftLastAccessTime; FILETIME ftLastWriteTime; DWORD nFileSizeHigh; DWORD nFileSizeLow; }; typedef _WIN32_FILE_ATTRIBUTE_DATA WIN32_FILE_ATTRIBUTE_DATA; typedef _WIN32_FILE_ATTRIBUTE_DATA *LPWIN32_FILE_ATTRIBUTE_DATA;?
Windows SDK 中,結(jié)構(gòu)體也有自己的命名規(guī)范。一般情況下,Windows 系統(tǒng)中使用全大寫來命名結(jié)構(gòu)體、共用體,并使用“_”來分隔單詞,在結(jié)構(gòu)名加“LP”或“P”表示指向數(shù)據(jù)結(jié)構(gòu)的指針。
2.2??? Windows API 的功能分類
Windows API 所能實現(xiàn)的功能包括很多方面,在進(jìn)行應(yīng)用程序的開發(fā)時,開發(fā)人員可能會使用到文件、進(jìn)程、內(nèi)存、權(quán)限、系統(tǒng)信息等系統(tǒng)的基本服務(wù)和系統(tǒng)管理類的 API,可能會用到圖形用戶界面、控件等函數(shù)和對象,可能需要在界面上繪制圖像處理多媒體信息等,還包括進(jìn)行網(wǎng)絡(luò)通信開發(fā)等。
2.2.1??? 系統(tǒng)基本服務(wù)
系統(tǒng)基本服務(wù)是 Windows API 最基本的內(nèi)容,是最常使用到的程序接口。系統(tǒng)基本服務(wù)API 包括以下幾個方面。
對文件的基本操作包括文件的創(chuàng)建、打開、讀寫、關(guān)閉、刪除,文件屬性的設(shè)置與獲取,目錄操作,以及磁盤分卷的操作,還包括鏡像文件、加密文件系統(tǒng)等。
主要是內(nèi)在的分配、共享、釋放等內(nèi)容,包括虛擬內(nèi)存管理、分頁機(jī)制、堆管理等。
包括進(jìn)程主程序( exe)、模塊、動態(tài)鏈接庫(dll)的編寫;線程的基本概念,線程創(chuàng)建、遍歷、同步等操作;進(jìn)程與權(quán)限;線程與纖程等內(nèi)容。
包括設(shè)備對象等基本概念。加載與卸載驅(qū)動程序,控制驅(qū)動程序,與驅(qū)動程序通信等。
包括如何開發(fā)調(diào)試器,程序運行錯誤的處理,日志的記錄、Windows 可執(zhí)行文件的結(jié)構(gòu)等。
包括注冊表的操作,如打開注冊表,讀取、寫入鍵值,創(chuàng)建、刪除鍵;還包括系統(tǒng)基本信息的獲取和設(shè)置,如系統(tǒng)目錄、系統(tǒng)版本、計算機(jī)名等。
包括使用共享文件進(jìn)行進(jìn)程間通信的方法,使用消息進(jìn)行進(jìn)程間通信的方法,使用郵槽、管道等進(jìn)行進(jìn)程間通信的方法,使用網(wǎng)絡(luò)共享進(jìn)行進(jìn)程間通信的方法。
消息機(jī)制是 Windows 系統(tǒng)中很重要的一種機(jī)制。幾乎所有的 Windows 應(yīng)用程序都在與消息打交道,而 Windows 的消息機(jī)制又是依賴于定時器的。所以了解 Windows 消息機(jī)制是學(xué)習(xí)Windows 應(yīng)用程序開發(fā)的重要內(nèi)容。
Windows 的系統(tǒng)基本服務(wù)還包括性能監(jiān)視、電源管理、索引與數(shù)據(jù)存儲等,也將在本書中有所涉及。
本實例使用了 Windows 系統(tǒng)基本服務(wù)中的部分 API,實現(xiàn)將系統(tǒng)目錄路徑寫入文件中。在這里不對實現(xiàn)原理做過多的解釋,只是使讀者對 Windows 系統(tǒng)服務(wù) API 有初步的了解。
/* ************************************ *《精通 Windows API》 * 示例代碼 * basic.c * 2.2 Windows API 的功能分類 **************************************/ /* 頭文件 */ #include <windows.h> /* ************************************ * 功能 獲取系統(tǒng)目錄信息,并存儲到文件中 **************************************/ int main(int argc, TCHAR argv[]) { //文件句柄 HANDLE hFile; DWORD dwWritten; //字符數(shù)組,用于存儲系統(tǒng)目錄 TCHAR szSystemDir[MAX_PATH]; //獲取系統(tǒng)目錄 GetSystemDirectory(szSystemDir,MAX_PATH); //創(chuàng)建文件 systemroot.txt hFile = CreateFile("systemroot.txt", GENERIC_WRITE, 0,NULL,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); //判斷文件是否創(chuàng)建成功 if(hFile != INVALID_HANDLE_VALUE) { //將系統(tǒng)目錄系統(tǒng)信息寫入文件 if(!WriteFile(hFile,szSystemDir,lstrlen(szSystemDir),&dwWritten,NULL)) { return GetLastError(); } } //關(guān)閉文件,返回。 CloseHandle(hFile); return 0; }?
運行程序,在程序所在的目錄會生成文件“systemroot.txt”,文件內(nèi)容為系統(tǒng)目錄。
2.2.2??? 系統(tǒng)管理
系統(tǒng)管理是 Windows 系統(tǒng)中很重要的內(nèi)容。Windows 系統(tǒng)提供了以下方面的 API 供應(yīng)用程序開發(fā)人員使用,包括:管理控制臺接口、程序安裝、系統(tǒng)恢復(fù)、任務(wù)調(diào)度、Windows 運程管理。
2.2.3??? 用戶界面
用戶界面開發(fā)是 Windows 應(yīng)用程序開發(fā)的重要內(nèi)容。Windows 用戶界面主要包括兩個部分,Windows Shell 和 Windows 圖形用戶界面。Windows 圖形用戶界面包括窗口對象的相關(guān)內(nèi)容,界面資源,控件、用戶數(shù)據(jù)交換(粘貼板等)和用戶輸入的處理。
包括一些基本數(shù)據(jù)概念和對象:窗口類、消息對列、窗口過程(消息處理函數(shù))、窗口屬性等。 主要包括的 API 有窗口類注冊的函數(shù)、窗口建立與關(guān)閉函數(shù)、窗口屬性修改函數(shù)等。
資源是 Windows 應(yīng)用程序中很重要的一項內(nèi)容,在可執(zhí)行文件中,專門有用于存儲資源的節(jié)。 這里所說的資源是界面資源,包括圖標(biāo)、菜單、字符串、版本信息、對話框、動態(tài)光標(biāo)、插入號(Carets)等。資源的處理涉及眾多 API 函數(shù)。
包括對話框、鍵盤加速器(快捷鍵)、鍵盤輸入、鼠標(biāo)輸入、原始數(shù)據(jù)輸入等。這些概念是程序通過用戶界面與用戶進(jìn)行交互的基本概念。
包括 Atom 表(包括了若干字符串和標(biāo)識符)、粘貼板、數(shù)據(jù)復(fù)制、動態(tài)數(shù)據(jù)交接等基本概念,是用戶和應(yīng)用程序通過用戶界面進(jìn)行數(shù)據(jù)交換的主要載體。
Windows 系統(tǒng)提供了不少于 30 種的控件供應(yīng)用程序使用,其中最常用的幾種包括 Edit控件(文本框)、Button 控件(按鈕)、ListView 控件(列表)、ToolTip 控件(提示框)、ComboBox 控件(下拉選擇框)、Tree-View 控件(樹)、Rich-Edit 控件(多功能文本框)、Tab 控件(分頁)、Process 控件(進(jìn)度條)等。
Windows 桌面瀏覽器(explorer.exe)的功能強(qiáng)大,Windows Shell 應(yīng)用程序可以利用WindowsShell 桌面的程序接口達(dá)到管理系統(tǒng)、定制圖標(biāo)和默認(rèn)程序、擴(kuò)展桌面功能等目的。
?
實例中,首先注冊了窗口類,然后創(chuàng)建了一個窗口,創(chuàng)建窗口時指定的窗口的屬性和窗口消息的處理函數(shù)。函數(shù)消息的處理函數(shù)大多調(diào)用系統(tǒng)默認(rèn)函數(shù)來處理。如下:
D:\002>cl window.cpp user32.lib gdi32.lib 用于 80x86 的 Microsoft (R) 32 位 C/C++ 優(yōu)化編譯器 15.00.21022.08 版 版權(quán)所有(C) Microsoft Corporation。保留所有權(quán)利。 window.cpp Microsoft (R) Incremental Linker Version 9.00.21022.08 Copyright (C) Microsoft Corporation. All rights reserved. /out:window.exe window.obj user32.lib gdi32.lib?
運行效果:
?
2.2.4??? 圖像和多媒體
Windows 的圖像引擎和多媒體編程有多種接口,包括最基本的 GDI、GDI+,以及更高級的OpenGL、DirectX 等圖像引擎編程接口。DirectX 和 OpenGL 在游戲開發(fā)、動畫制作等方面應(yīng)用比較廣泛,使用它們進(jìn)行應(yīng)用程序開發(fā)需要專門的 SDK。本書只講解 GDI,對一般的應(yīng)用程序開發(fā),已經(jīng)足夠使用。
GDI 的基本概念包括圖像(Image)、位圖(Bitmaps)、筆(Pen)、畫刷(Brush)、文本和字體( Text and Fonts)、線(Line)、區(qū)域(Regions)、形狀(Shapes)等。其基本的功能是對顯示設(shè)備進(jìn)行控制、獲取和修改相關(guān)配置,在計算機(jī)屏幕上顯示用戶所需要顯示的內(nèi)容。
2.2.5??? 網(wǎng)絡(luò)
用戶利用 Windows API 可以開發(fā)基于各種網(wǎng)絡(luò)協(xié)議的應(yīng)用程序,例如 TCP\UDP Socket、HTTP、DHCP、RPC、QOS、藍(lán)牙,以及傳真、點對點文件傳輸、即插即用設(shè)備管理等。 還可以進(jìn)行網(wǎng)絡(luò)管理,包括網(wǎng)絡(luò)的基本信息,使用 IP helper 獲取網(wǎng)絡(luò)配置和網(wǎng)絡(luò)信息、進(jìn)行網(wǎng)絡(luò)監(jiān)視等。 同時微軟還提供了進(jìn)行網(wǎng)絡(luò)安全編程的部分接口,主要是防火墻 Windows、防火墻 API,以及一些 Windows 自帶的網(wǎng)絡(luò)應(yīng)用程序的接口,包括 IE、Outlook 等。
2.2.6??? 其他功能
Windows API 能實現(xiàn)的功能還有很多,限于篇幅不能全部介紹。有一些內(nèi)容本書未涉及,但是 Windows API 也提供了相關(guān)接口。
包括微軟的“動態(tài)數(shù)據(jù)存取組件”技術(shù)(MDAC,包含了 ADO、ODBC)、OLE 數(shù)據(jù)庫、XML 標(biāo)準(zhǔn)、微軟 XML、可擴(kuò)展存在引擎等多方面內(nèi)容。主要是 Windows 系統(tǒng)內(nèi)的數(shù)據(jù)庫文件、Windows.系統(tǒng)對數(shù)據(jù)庫的訪問接口等技術(shù)。
2.消息與協(xié)作
消息與協(xié)作大多是 Windows 系統(tǒng)自帶的一些應(yīng)用程序所提供的開發(fā)接口。其中最主要的內(nèi)容是“協(xié)作數(shù)據(jù)對象”( CDO)。CDO 包括了若干種 Windows 數(shù)據(jù)傳輸?shù)湫蛻?yīng)用,包括 Mssager (MSN)、郵件 SMTP (Outlook)應(yīng)用接口等。
3.Web 開發(fā)
IIS(Intemet Information Server,互聯(lián)網(wǎng)信息服務(wù))等應(yīng)用程序提供的開發(fā)接口,使用戶可以直接在 Windows 平臺上進(jìn)行 Web 開發(fā),開發(fā)的程序運行于 ns 框架下。“數(shù)據(jù)存在與訪問”、“消息與協(xié)作”、“Web 開發(fā)”等都可以歸為 COM 開發(fā)的范圍內(nèi)。COM 是 Windows 應(yīng)用程序接口的一種,具有固定的接口模式,大多是 Windows 系統(tǒng)中自帶的應(yīng)用程序所提供的開發(fā)接口的集合。
2.3??? Windows API核心DLL
在 Windows 的系統(tǒng)目錄中,存在著很多的動態(tài)鏈接庫文件(DLL 文件)。這些 DLL 文件中 包括了 Windows API 函數(shù)可執(zhí)行程序。DLL 將各函數(shù)“導(dǎo)出”,這樣應(yīng)用程序就可以找到 DLL中的函數(shù)地址,當(dāng)應(yīng)用程序調(diào)用 Windows API 時,程序會運行到 DLL 中。API 函數(shù)主要存在于幾個核心的動態(tài)連接庫文件中。Keme132.dll 是最重要的 DLL,Windows 系統(tǒng)最主要的系統(tǒng)服務(wù) API 函數(shù)都存在于 Kerne132.dll 中。User32.dll 主要包括圖形用戶界面中所使用到的一些函數(shù)接口。 GDI32.dll 中,主要包括 Windows 圖形引擎中的接口函數(shù)。
當(dāng)用戶調(diào)用一個 API 時,系統(tǒng)會通過程序文件中的導(dǎo)入表結(jié)構(gòu)找到需要調(diào)用的 API 函數(shù)位于哪個 DLL,確定函數(shù)的地址,以便應(yīng)用程序可以成功調(diào)用 API 函數(shù)。
2.3.1??? Kerne132.dll
Keme132.dll 包括了系統(tǒng)基本服務(wù)中最基本的 API 函數(shù),如文件系統(tǒng)、進(jìn)程與線程、內(nèi)存管理等。 Windows XPSP2 系統(tǒng)中,Keme132.d11 有 949 個導(dǎo)出函數(shù),例如,CreateFileA、CreateProcessA、OpenThread、SetFileTime 等。本書將在后續(xù)章節(jié)中通過實例介紹這些 API的使用。
2.3.2??? User32.dll
User32.dll 是 Windows 圖形用戶界面的主要支持。一些重要的圖形用戶界面函數(shù)由User32.dll 函數(shù)導(dǎo)出。Windows XP SP2 系統(tǒng)中,User32.dll 有 732 個導(dǎo)出函數(shù),例如CreateWindowExW、RegisterClassA 等。
2.3.3??? Gdi32.dll
Gd132.dll 是 Windows GDI 應(yīng)用程序設(shè)計接口,Gdi32.dll 導(dǎo)出了與此相關(guān)的若干函數(shù),如 GetTextColor、LineTo、TextOutA 等。
2.3.4??? 標(biāo)準(zhǔn)C函數(shù)
標(biāo)準(zhǔn) C 程序是一種標(biāo)準(zhǔn),任何支持 C 語言應(yīng)用程序開發(fā)的系統(tǒng)都應(yīng)該提供 C 語言庫函數(shù)的 調(diào)用。在系統(tǒng)環(huán)境下使用標(biāo)準(zhǔn) C 進(jìn)行程序開發(fā)時,用戶所使用的庫函數(shù)實際上是由操作系統(tǒng)提供的。正是由于各個主流操作系統(tǒng)都提供了一套標(biāo)準(zhǔn) C 庫所定義的函數(shù)接口,標(biāo)準(zhǔn) C 函數(shù)庫才會有如此廣泛的跨越操作系統(tǒng)平臺。所以 C 程序仍然依賴于操作系統(tǒng)開發(fā)人員為其實現(xiàn)接口,而 C 庫函數(shù)的實現(xiàn)仍然依賴于操作系統(tǒng)提供的調(diào)用接口,如標(biāo)準(zhǔn) C 函數(shù) fopen 函數(shù)在Windows 系統(tǒng)中的實現(xiàn)就依賴于 API CreateFile 函數(shù)(CreateFile 實現(xiàn)了文件的創(chuàng)建和打開等操作)。
Windows 系統(tǒng)的 C 標(biāo)準(zhǔn)庫函數(shù)接口主要存在于crtdll.dll 中。實際上,C 標(biāo)準(zhǔn)函數(shù)庫必須由操作系統(tǒng)為其提供接口,否則使用標(biāo)準(zhǔn) C 開發(fā)的程序無法在特定的系統(tǒng)上運行。 Windows XP SP2 系統(tǒng)中,crtdll.dll 有 526 個導(dǎo)出函數(shù),如 fopen、printf. strlen等。
2.3.5??? 其他Dll
當(dāng)然,Windows 系統(tǒng)中的 DLL 文件遠(yuǎn)遠(yuǎn)不止這幾個,Windows 系統(tǒng)提供了非常豐富而且功能強(qiáng)大的 API,上文已經(jīng)介紹了 Windows API 所主要依賴的幾個 DLL,其他的 DLL 庫文件由于過于龐雜,就不一一介紹,將在后續(xù)的章節(jié)中有所涉及。讀者只需要了解調(diào)用 Windows API 的基本原理就可以了。
2.4??? Unicode和多字節(jié)
Windows 既可以使用 Unicode 字符集又可以使用傳統(tǒng)的字符集(如多字節(jié)編碼)來實現(xiàn)對多種語言的支持,以適應(yīng)國際市場的要求。與傳統(tǒng)的字符集編碼相比,Unicode 是世界通用的字符編碼標(biāo)準(zhǔn),使用 16 位數(shù)據(jù)表示一個字符,一共可以表示 65535 種字符,可以包括現(xiàn)代計算機(jī)中所使用的所有字符,包括各種字母、文字、在出版業(yè)中使用的特殊符號等。 傳統(tǒng)的字符集,如 Windows ASNI 字符集,使用 8 位數(shù)據(jù)或?qū)⑾噜彽膬蓚€ 8 位的數(shù)據(jù)組合在一起表示特殊的語言字符。Windows 系統(tǒng)采用了 ASNI 字符的擴(kuò)展方式,如果一個字節(jié)是負(fù)數(shù),則將其后續(xù)的一個字節(jié)組合在一起表示一個字符。這種編碼方式的字符集也稱作“多字節(jié)”字符集。
在 Windows 系統(tǒng)中,Unicode 字符編碼和多字節(jié)字符編碼都可以使用。
?
在本實例中,一共使用了 3 種類型的字符串變量,每種類型的字符串變量的初始化是不同的,如表 2.2 所示。
表2.2 字符串與初始化
| 類型 | 變量類型 | 初始化形式 |
| Unicode | LPWSTR | L”string” |
| 多字節(jié) | LPSTR | ”string” |
| 根據(jù)開發(fā)環(huán)境的設(shè)置自動適應(yīng) | LPTSTR | TEXT(”string”) |
本實例首先使用“多字節(jié)”方式進(jìn)行編譯。可以使用二進(jìn)制編輯器來查看編譯得到的可執(zhí)行文件,上例中定義的字符串分別存儲為以下形式。使用二進(jìn)制編輯器查看,可以從 exe可執(zhí)行文件中找到如下信息。讀者可以對照 ASCII 編碼表查看。
“This is a Unicode String;”使用 Unicode 方式的十六進(jìn)制編碼:
54 00 68 00 69 00 73 00 20 00 69 00 73 00 20 00 61 00 20 00 55 00 6e 00 69 00 63 00 6f 00 64 00 65 00 20 00 53 00 74 00 72 00 69 00 6e 00 67 00 3b 00?
?
“This is not a Unicode String;”使用 ASCII 方式的十六進(jìn)制編碼:
54 68 69 73 20 69 73 20 61 20 55 6e 69 63 6f 64 65 20 53 74 72 69 6e 67 3b?
?
“This string is Unicode or not depends on the option.”的ASCII 方式的十六進(jìn)制編碼:
54 68 69 73 20 73 74 72 69 6e 67 20 69 73 20 55 6e 69 63 6f 64 65 20 6f 72 20 6e 6f 74 20 64 65 70 65 6e 64 73 20 6f 6e 20 74 68 65 20 6f 70 74 69 6f 6e 2e?
之后是“<字符編碼 1>”和 Unicode 編碼、“<字符編碼 2>”和“<字符編碼 3>”的多字節(jié)編碼。對漢字字符,兩種編碼的方式是不同的,如“字符編碼”四個字,兩種編碼分別為:
Unicode編碼
57 5b 26 7b 16 7f 01 78?
?
和多字節(jié)ASCII
d7 d6 b7 fb b1 e0 c2 eb?
?
讀者可以分析設(shè)置使用 Unicode 字符集后編譯完成的可執(zhí)行文件與設(shè)置為多字節(jié)字符集后編譯得到的可執(zhí)行文件有什么不同。
?
設(shè)置的方法是在Visual Studio工程屬性中選擇“配置屬性”→“常規(guī)”→“字符集”選項中進(jìn)行選擇。
2.4.1??? W版本和A版本的API
Windows 支持 Unicode 和 ASCII 編碼的字符。Windows 系統(tǒng) API 凡是以字符串作為參數(shù)的很多具有 W 和 A 兩個版本以實現(xiàn)兩種不同編碼的字符處理。
下面以 MessageBox 為例介紹兩種不同版本 API 函數(shù)的使用。在 User32.dll 中導(dǎo)出的函數(shù)實際上沒有 MessageBox,只有 MessageBoxA 和 MessageBoxW,這兩者是同一個 API,實現(xiàn)了同樣的功能。不同的是,MessageBoxA 以多字節(jié)字符串作為參數(shù)輸入,MessateBoxW 以Unicode 字符串作為參數(shù)輸入。
可以從 User32.dll 的導(dǎo)出函數(shù)看到兩個不同版本的 API 函數(shù)。在 Platform SDK 中,MessageBox 函數(shù)聲明所在的頭文件中發(fā)現(xiàn)如下定義(以下代碼來自于 Microsoft Platform SDK):
WINUSERAPI int WINAPI MessageBoxA( __in_opt HWND hWnd, __in_opt LPCSTR lpText, __in_opt LPCSTR lpCaption, __in UINT uType); WINUSERAPI int WINAPI MessageBoxW( __in_opt HWND hWnd, __in_opt LPCWSTR lpText, __in_opt LPCWSTR lpCaption, __in UINT uType); #ifdef UNICODE #define MessageBox MessageBoxW #else #define MessageBox MessageBoxA #endif // !UNICODE?
可以看到,在程序進(jìn)行編譯和連接時,如果程序在 UNICODE 環(huán)境下,會使用 MessageBoxW,否則使用 MessageBoxA。
軟件開發(fā)人員可以自行設(shè)定使用 Unicode 編碼或都多字節(jié)編碼文件,不影響程序的正常功能。
但如果在編寫程序時,使用的字符集與代碼中使用的函數(shù)不一致、定義的字符串變量不兼容,將會引起編譯錯誤或者運行程序顯示亂碼,甚至可能引起程序運行錯誤,這一點需要引起注意。
2.4.2??? Unicode與ASGII的轉(zhuǎn)換
Windows 專門提供了若干個 API 來實現(xiàn)對字符編碼的轉(zhuǎn)換工作。ideCharToMultiByte、MultiByteToWideChar、UnicodeToBytes 函數(shù)可以完成這些工作。
WideCharToMultiByte 函數(shù)將 Unicode 字符串轉(zhuǎn)換為多字節(jié)字符串,以適應(yīng) A 版本的API,MultiByteToWideChar 函數(shù)將多字節(jié)字符串轉(zhuǎn)換為了 Unicode 字符串,以適應(yīng) W 版本的 API 的參數(shù)形式要求。
2.4.3??? 對Windows程序設(shè)計規(guī)范的建議
每個程序員都有自己的規(guī)范化編程習(xí)慣。代碼的規(guī)范不是本書的重點,所以這里只給出一些微軟經(jīng)常使用代碼規(guī)范,MSDN 的示例中,SDK 的頭文件和例子中幾乎都是使用的這種方法。
變量名:通常采用所謂的“匈牙利命名法”,變量名由“類型縮寫(小寫)”+“變量描述(單詞首字母大寫)”構(gòu)成,如字符串類型的變量可以命名為 szFileName,DWORD 類型的數(shù)據(jù)可以命名為 dwFileSize,指針類型可以命名為 lpBuffer,句柄類型的變量可以命名為 hLogFile 等。
函數(shù)名:各單詞的首字母大寫,如 EnumerateFilesInDrectory、ShowFileSize 等。
類型名:全大寫,各單詞以下劃線分隔,如 WIN32_FILE_ ATTRIBUTE_DATA、DWORD、 HANDLE 等。
常量:同類型名的命名方式。
宏:多與類型名命名方式相同,有的也與函數(shù)名命名方式相同。 大括號與代碼段:一般大括號獨立占一行,大括號內(nèi)的代碼段縮進(jìn)。如果代碼段僅一行(如 if-else 后的語句),也建議使用大括號。
在調(diào)用或定義函數(shù)時,如果函數(shù)太長,可以分行寫,將每個參數(shù)寫一行。一般多于 3個參數(shù)的函數(shù)需要分行寫,以美觀和方便閱讀為原則。
在本書的示例中,都將盡量使用這些規(guī)范化的方式。
?
2.5??? 小結(jié)
PDF下載:http://files.cnblogs.com/yongfeng/WINDOWSAPI02.rar
摘自:《精通Windows.API-函數(shù)、接口、編程實例》 人民郵電出版社
范文慶、周彬彬、安靖編著
from:?http://www.cnblogs.com/yongfeng/archive/2013/04/30/3051696.html
總結(jié)
以上是生活随笔為你收集整理的C++ WINDOWS API 第2章 Windows API概要的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++ WINDOWS API 第1章
- 下一篇: C++ WINDOWS API 如何使用