孙鑫01
1.消息和事件
用戶在操作系統中任何一個操作都是事件。比如鼠標單擊了一個按鈕就是一個鼠標事件。消息是操作系統將事件傳遞給用戶程序的數據格式,是一種數據通訊協議。操作系統將每個事件都包裝成一個稱為消息的結構體MSG來傳遞給應用程序。
MSG結構定義如下:
- 句柄,資源的標識,操作系統要管理和操作這些資源,都是通過句柄來找到對應的資源。句柄又可以分為圖標句柄(HICON),光標句柄(HCURSOR),窗口句柄(HWND),應用程序實例句柄(HINSTANCE)。操作系統給每一個窗口指定一個唯一的標識號即窗口句柄。
- 消息,實質是整數,為了便于記憶采用了宏的形式,比如用WM_開頭的各種窗口消息。
- WParam LParam都是整型,表示消息的附加信息。比如WM_CHAR消息,WParam用來存放按鍵的ASCII碼,LParam比較復雜,MSDN說明如下:
The repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag, as shown in the following table.
Bits Meaning
0-15 The repeat count for the current message. The value is the number of times the keystroke is autorepeated as a result of the user holding down the key. If the keystroke is held long enough, multiple messages are sent. However, the repeat count is not cumulative.
16-23 The scan code. The value depends on the OEM.
24 Indicates whether the key is an extended key, such as the right-hand ALT and CTRL keys that appear on an enhanced 101- or 102-key keyboard. The value is 1 if it is an extended key; otherwise, it is 0.
25-28 Reserved; do not use.
29 The context code. The value is 1 if the ALT key is held down while the key is pressed; otherwise, the value is 0.
30 The previous key state. The value is 1 if the key is down before the message is sent, or it is 0 if the key is up.
31 The transition state. The value is 1 if the key is being released, or it is 0 if the key is being pressed. - DWORD 記錄消息發送的時間
- POINT 記錄光標的位置
2.windows的入口函數
int WINAPI WinMain {HINSTANCE hInstance, //handle to current instanceHINSTANCE hPreInstance, //handle to previous instanceLPSTR lpCmdLine, //command lineint nCmdShow //show state }- hPreInstance 比如有兩個一樣的程序,就有當前和先前之分了。如果只有一個程序,那么hPreInstance應該為空
- LPSTR 長指針,類似于char*。命令行參數 比如在windows運行欄中輸入 notepad 1.txt 就能啟動1.txt
這就是命令行參數。下圖是如何設定一個命令行參數。
- nCmdShow 顯示狀態,比如窗口的最大化 最小化 隱藏顯示等
注意WinMain函數是由操作系統調用的。
2.創建一個完整窗口的步驟
- 設計一個窗口
- 注冊一個窗口
- 創建一個窗口
- 顯示及更新一個窗口
在我們的程序中,經常要用到一類變量,這個變量的每一位,都對應一種特性,當該變量的某位為1時,表示有該位對應的那種特性,當該位為0時,即沒有該位所對應的那種特性。當變量中的某幾位同時為1時,就表示同時具有幾種特性的組合。一個變量中的哪一位代表哪種意義不容易記憶,所以我們根據特征的英文拼寫的大寫去定義一些宏,我們可以用二進制or|操作符將他們進行或運算相組合。如果要去掉某個特征,去反~之后再進行&運算就可以實現。例如style &~CS_NOCLOSE
窗口類
- WNDPROC lpfnWndProc回調函數指針?;卣{函數的原理是這樣的,當應用程序收到給某一個窗口的消息時,就應該調用某一函數來處理這條消息。這一調用過程不用應用程序自己來實施,而由操作系統來完成,但是回調函數本身的代碼必須由應用程序自己來完成。對于一條消息,操作系統到底調用應用程序中的那個函數來處理呢,操作系統就調用接受消息的窗口所屬類型中的lpfnWndProc成員指定的函數,每一種不同類型的窗口都有自己專用回調函數,該函數就是通過lpfnWndProc成員指定
WNDCLASSEX wcex;
3.HWND和HINSTANCE的區別
hWnd,是指窗口句柄,通過該句柄可以操作窗口資源;hInstance是應用程序句柄,是操作系統分配給實例的指針. 程序根據hInstance訪問其相應的內存空間。
應用程序一定有hInstance,但不一定有hWnd.
4.注冊窗口
在用WNDCLASS設定好窗口的相關參數后,調用RegisterClass(&wndclass)就可以實現窗口類的注冊
5.創建窗口
先定義一個句柄
HWND hwnd; CreatWindow(LPCTSTR lpClassName //register calss name 即在wndclass注冊的類名,否則啟動不了窗口LPCTSTR lpWindowName//window nameDWORD dwStyle //window styleint x //horizental position of windowint y //vertical position of windowint nWidth //window widthint nHeight //window heightHWND hWndParent //handle to parent or owner windowHINSTANCE hInstance //handle to application instanceLPVOID lpParam //window creation data);6.顯示窗口
ShowWindow(HWnd,int nCmdShow)
7.更新窗口
UpDateWindow(hwnd)
8.消息循環
MSG msg;
while(GetMessage(&MSG,NULL,0,0))
{
TranslateMessage(&MSG);
DispatchMessage(&MSG);
}
GetMessage是從消息隊列中獲取消息,
GetMessage{
LPMSG lpMsg //message information
HWND hwnd //handle to window
UINT wMsgFilterMin,//first message
UINT wMsgFilterMax //last message
}
HWND hwnd=NULL時表示調用線程的任何窗口的消息,也就是獲取所有的消息
wMsgFilterMin,wMsgFilterMax為NULL時表示接受所有的消息
返回值為bool,有返回值時即為真
- TranslateMessage(&MSG)
消息轉化,對取到的消息對轉化。比如keydown和keyup消息時,能轉化到WM_char消息,并將轉換后的消息投放到消息隊列中,只會產生新消息,不會影響原來的消息 - DispatchMessage(&MSG)
將搜到的消息傳到窗口回調函數中處理。將消息路由到操作系統,然后操作系統調用窗口的回調函數。
9.窗口過程的回調函數
LRESULT CALLBACK WindowProc
(
HWND hwnd,
MSG msg,
WParam wParam,
LParam lParam,
)
10.BeginPaint 和EndPaint
PAINTSTRUCT ps;
HDC hdc;
switch(umsg)
{
case WM_PAINT:
{
hdc=BeginPaint (hwnd,&ps);
EndPaint(hwnd,&ps);
break;
}
}
注意WM_PAINT中只能使用BeginPaint 和EndPaint,
GetDC和RRelaeaseDC不能再這里使用
11.關閉窗口消息WM_Close
case WM_Close:
if(IDYES==MessageBox(hend,“你是否要退出程序”,“維新”,MB_YESNO))
{
DestroyWindow(hwnd); //銷毀窗口,并發送WM_DESTROY消息,但不銷毀程序
}
break;
12.WM_DESTROY
case WM_DESTROY:
PostQuitMessage(0);
break;
通知系統線程請求終止,其形參是給出應用程序退出的代碼,其值作為WM_QUIT消息的附加參數,放到WParam中。發出的WM_QUIT消息發送到線程消息隊列中。PostQuitMessage()返回值為0,使GetMessage得到0值,退出程序。
13.缺省消息處理
default :
return DefWindowProc(hwnd,uMSG,WParam,LParam);
讓系統處理我們沒有定義的消息,注意此處不能缺省,不然無法正常啟動程序
總結
- 上一篇: 直流单臂桥的使用注意事项:
- 下一篇: DO测量仪e+h溶解氧变送器维修COM2