一、windows是事件驅動方式的程序設計
windows程序設計是種事件驅動方式的程序設計,主要基於消息的。當用戶需要完成某種功能時,需要調用OS某種支持,然後OS將用戶的需要包裝成消息,並投入到消息隊列中,最後應用程序從消息隊列中取走消息並進行響應。
二、消息隊列
每個應用程序OS都爲它建立一個消息隊列,消息隊列是個先進先出的緩衝區,其中每個元素都是一個消息,OS將生成的每個消息按先後順序放進消息隊列中, 應用程序總是取走當前消息隊列中的第一條消息,應用程序取走消息後便知道用戶的操作和程序的狀態,然後對其處理即消息響應,消息響應通過編碼實現。
三、Window程序入口
WinMain函數是Windows程序入口點函數,由OS調用,當OS啓動應用程序的時候,winmain函數的參數由OS傳遞的。
四、創建一個完整的窗口需要經過下面四個操作步驟
1, 設計一個窗口類。如:WNDCLASS wndcls。
2, 註冊窗口類。如:RegisterClass(&wndcls)。
3, 創建窗口。如:CreateWindow(),CreateWindowEX();
4, 顯示及更新窗口。如:ShowWindow(),UpdateWindow();
其他值得注意的地方
1, 消息結構
typedef struct tagMSG { // msg
HWND hwnd; //接收消息的窗口句柄。和哪個窗口相關聯。
UINT message; //消息標識。消息本身是什麼。
WPARAM wParam; //消息的附加信息。具體取決於消息本身。
LPARAM lParam;
DWORD time; //消息投遞時間。
POINT pt; //消息投遞時,光標在屏幕上的位置。
} MSG;
2, 掌握windows的消息機制
需要掌握兩方面:(1)消息本身。不同消息所代表的用戶操作和應用程序的狀態。
(2)對於某個特定的消息來說,要讓OS執行某個特定的功能去響應消息。
3, Window入口函數說明
int WINAPI WinMain(
HINSTANCE hInstance, // 當前事例句柄。
HINSTANCE hPrevInstance, // 先前事例句柄。32位系統中此值都爲NULL
LPSTR lpCmdLine, // 命令行指針
int nCmdShow // (窗口)顯示的狀態
);
要帶參調用WinMain,類似於命令行的功能,在ProjectèsettingèDebug頁èProgram arguments項填寫參數
4, Windows提供的窗口類詳解
typedef struct _WNDCLASS {
UINT style; //窗口的類型
WNDPROC lpfnWndProc; //窗口過程函數指針(回調函數)
int cbClsExtra; //窗口類附加字節,爲該類窗口所共享。通常0。
int cbWndExtra; //窗口附加字節。通常設爲0。
HANDLE hInstance; //當前應用程序事例句柄。
HICON hIcon; //圖標句柄 LoadIcon();
HCURSOR hCursor; //光標句柄 LoadCursor();
HBRUSH hbrBackground; //畫刷句柄 (HBRUSH)GetStockObject();
LPCTSTR lpszMenuName; //菜單名字
LPCTSTR lpszClassName; //類的名字
} WNDCLASS;
5, 消息循環:
MSG msg;
while(GetMessage(&msg,...)) //從消息隊列中取出一條消息
{
TranslateMessage(&msg); //進行消息(如鍵盤消息)轉換
DispatchMessage(&msg); //分派消息到窗口的回調函數處理,(OS調用窗口回調函數進行處理)。
}
6, 回調函數
LRESULT CALLBACK WindowProc( //這裏WindowProc是個代號名字。
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
說明:兩種函數調用約定(__stdcall 和 __cdecl):
#define CALLBACK __stdcall
//__stdcall 標準調用預定,是PASCAL 調用約定,象DELPHI使用的就是標準調用約定
#define WINAPIV __cdecl
// __cdecl 是C 語言形式的調用約定。
主要區別:函數參數傳遞順序 和 對堆棧的清除上。
問題:除了那些可變參數的函數調用外,其餘的一般都是__stdcall約定。但 C/C++編譯默然的是__cdecl約定。所以如果在VC等環境中調用__stdcall約定的函數,必須要在函數聲明的時加上 __stdcall 修飾符,以便對這個函數的調用是使用__stdcall約定(如使用DELPHI編寫的DLL時候)。
(VC中可通過這途徑修改:projectèsettingsèc/c++ècategary選”Code Generation”,出現Call convention選項,修改之)
7, DC句柄的使用
(1)使用BeginPaint(),EndPaint()對。注意只能在響應WM_PAINT消息時使用。
(2)使用GetDc(),ReleaseDC()對。注意他們不能在響應WM_PAINT中使用。
8, 其它
(1)函數名代表函數的首地址。
(2)創建窗口的時候一定要基於已經註冊的窗口類.