《VC++深入详解》学习笔记 第一章 Windows程序内部运行机制
(金光鱗閃影若茫)
窗口四步走:
設(shè)計(jì)窗口類
注冊(cè)窗口類
創(chuàng)建窗口
顯示更新窗口
最后創(chuàng)建消息循環(huán)和響應(yīng)函數(shù)
設(shè)計(jì)窗口類:
typedef struct {UINT style;//窗口類型 WNDPROC lpfnWndProc;//窗口處理函數(shù)int cbClsExtra;//窗口擴(kuò)展int cbWndExtra;//窗口實(shí)例擴(kuò)展HINSTANCE hInstance;//實(shí)例句柄HICON hIcon;//窗口的最小化圖標(biāo)HCURSOR hCursor;//窗口鼠標(biāo)光標(biāo)HBRUSH hbrBackground;//窗口背景色LPCTSTR lpszMenuName;//窗口菜單LPCTSTR lpszClassName;// 窗口類名 } WNDCLASS, *LPWNDCLASS說明:
舉例:
WNDCLASS wndclass;char lpszClassName[]="窗口"; //窗口類名char lpszTitle[]="測(cè)試窗口"; //窗口標(biāo)題名//窗口類定義,窗口類定義了窗口的形式與功能,窗口類定義通過給窗口類數(shù)據(jù)結(jié)構(gòu)WNDCLASS賦值完成//該數(shù)據(jù)結(jié)構(gòu)中包含窗口類的各種屬性wndclass.style =0; // 窗口類型為缺省類型CS_ Class Stylewndclass.lpfnWndProc=WndProc; //定義窗口處理函數(shù)wndclass.cbClsExtra=0; //窗口類無擴(kuò)展wndclass.cbWndExtra=0; //窗口實(shí)例無擴(kuò)展wndclass.hInstance=hInstance; //當(dāng)前實(shí)例句柄wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION); //窗口的最小化圖標(biāo)為缺省圖標(biāo)wndclass.hCursor=LoadCursor(NULL,IDC_ARROW); // 窗口采用箭頭光標(biāo)wndclass.hbrBackground=(HBRUSH)(GetStockObject(WHITE_BRUSH)); //窗口背景為白色wndclass.lpszMenuName=NULL; //窗口無菜單wndclass.lpszClassName=lpszClassName; //窗口類名為“窗口”注冊(cè)窗口類:
//以下是窗口類的注冊(cè)-----------Windows系統(tǒng)本身提供部分預(yù)定義的窗口類,程序員也可以自定義窗口類,窗口類必須先注冊(cè)后使用。 if(!RegisterClass(&wndclass)) //如果注冊(cè)失敗 發(fā)出警告 {MessageBeep(0); return FALSE;}說明:注冊(cè)內(nèi)容為窗口類對(duì)象指針(服務(wù)消息處理)
?創(chuàng)建窗口:
//創(chuàng)建窗口創(chuàng)建一個(gè)窗口的實(shí)例由函數(shù)CreateWindow()實(shí)現(xiàn) CreateWindow(lpszClassName, //窗口類名,創(chuàng)建窗口時(shí)一定要基于我們已經(jīng)注冊(cè)過的窗口類名,即"窗口"。lpszTitle, //窗口標(biāo)題名WS_OVERLAPPEDWINDOW, //窗口的風(fēng)格 WS_ Windows StyleCW_USEDEFAULT, //窗口左上角坐標(biāo)值為缺省值 CW_ Create Wndow CW_USEDEFAULT, CW_USEDEFAULT, //窗口的高和寬為缺省值 CW_USEDEFAULT, NULL, //此窗口無父窗口NULL, //此窗口無子菜單hInstance, //創(chuàng)建此窗口的應(yīng)用程序的當(dāng)前句柄NULL //不使用該值 );說明:創(chuàng)建方式應(yīng)為 HWND hwnd = CreateWindow(...);
hwnd值為NULL(創(chuàng)建失敗)或者窗口句柄(創(chuàng)建成功)
顯示更新窗口:
顯示窗口:
//顯示窗口
ShowWindow(hwnd,nCmdShow);
窗口句柄以及指定顯示狀態(tài)
更新窗口:
//繪制用戶區(qū),在顯示后必須需要
UpdateWindow(hwnd);
循環(huán)及響應(yīng):
?消息循環(huán):
BOOL GetMessage(LPMSG lpMsg,//指向 MSG 結(jié)構(gòu)的指針,用于存放獲取到的消息HWND hWnd,//當(dāng)其值是 NULL 時(shí),將獲取所有的當(dāng)前線程的窗口消息和線程消;當(dāng)其值是 -1 時(shí),只獲取當(dāng)前線程消息UINT wMsgFilterMin,//指定被可以被獲取的消息值的最小整數(shù)(消息其實(shí)就是一個(gè)被定義的整數(shù))UINT wMsgFilterMax,//指定被可以被獲取的消息值的最大整數(shù) );說明:Min和Max都設(shè)置為0時(shí)接收所有消息;返回值都為非零值(除了WM_QUIT)錯(cuò)誤返回值為-1;
消息循環(huán)一條線程一個(gè),是保證windows消息響應(yīng)模式就基礎(chǔ),而非一個(gè)窗口一個(gè);
舉例:
//消息循環(huán) while(GetMessage(&Msg,NULL,0,0)) {TranslateMessage(&Msg);//對(duì)"消息對(duì)"的轉(zhuǎn)化,如對(duì)鍵盤的WM_KEYDOWN和WM_KEYUP消息對(duì)轉(zhuǎn)化為WM_CHAR消息,并且將轉(zhuǎn)換后的新消息投遞到我們的消息隊(duì)列中去,//這個(gè)轉(zhuǎn)化操作不會(huì)影響原來的消息,只會(huì)產(chǎn)生一個(gè)新的消息。DispatchMessage(&Msg);//DispatchMessage()函數(shù)是將我們?nèi)〕龅南鞯酱翱诘幕卣{(diào)函數(shù)去處理;可以理解為該函數(shù)將取出的消息路由給操作系統(tǒng),然后操作系統(tǒng)去調(diào)用我們的窗口回調(diào)函數(shù)對(duì)這個(gè)消息進(jìn)行處理。 }
窗口過程函數(shù):
LRESULT CALLBACK WindowProc ( HWND hwnd, // 消息句柄 UINT uMsg, // 消息代碼 WPARAM wParam, // first message parameter LPARAM lParam // second message parameter );說明:
函數(shù)名隨意但要對(duì)應(yīng)設(shè)計(jì)時(shí)的名稱,一個(gè)窗口對(duì)應(yīng)一個(gè)過程函數(shù)
過程函數(shù)配合switch/case處理窗口中其他控件消息
舉例:
long CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) {switch(message){case WM_DESTROY:PostQuitMessage(0);default: //缺省時(shí)采用系統(tǒng)消息缺省處理函數(shù)return DefWindowProc(hwnd,message,wParam,lParam);}return (0); }?說明:其中message 通過translatemessage()將事件轉(zhuǎn)化而來
?
?
綜合:
long CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);//聲明 //WinMain函數(shù)是所有Windows應(yīng)用程序的入口,類似c語言中的main函數(shù)其功能是完成//一系列的定義和初始化,并產(chǎn)生消息循環(huán)。函數(shù)說明: int WINAPI WinMain(HINSTANCE hInstance, // handle to current instanceHINSTANCE hPrevInstance, // handle to previous instanceLPSTR lpCmdLine, // command lineint nCmdShow // show state ) {//初始化,初始化包括窗口類的定義、注冊(cè)、創(chuàng)建窗口實(shí)例和顯示窗口四部分 HWND hwnd;MSG Msg;WNDCLASS wndclass;char lpszClassName[]="窗口"; //窗口類名char lpszTitle[]="測(cè)試窗口"; //窗口標(biāo)題名//窗口類定義,窗口類定義了窗口的形式與功能,窗口類定義通過給窗口類數(shù)據(jù)結(jié)構(gòu)WNDCLASS賦值完成//該數(shù)據(jù)結(jié)構(gòu)中包含窗口類的各種屬性wndclass.style =0; // 窗口類型為缺省類型CS_ Class Stylewndclass.lpfnWndProc=WndProc; //定義窗口處理函數(shù)wndclass.cbClsExtra=0; //窗口類無擴(kuò)展wndclass.cbWndExtra=0; //窗口實(shí)例無擴(kuò)展wndclass.hInstance=hInstance; //當(dāng)前實(shí)例句柄wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION); //窗口的最小化圖標(biāo)為缺省圖標(biāo)wndclass.hCursor=LoadCursor(NULL,IDC_ARROW); // 窗口采用箭頭光標(biāo)wndclass.hbrBackground=(HBRUSH)(GetStockObject(WHITE_BRUSH)); //窗口背景為白色wndclass.lpszMenuName=NULL; //窗口無菜單wndclass.lpszClassName=lpszClassName; //窗口類名為“窗口”//以下是窗口類的注冊(cè)-----------Windows系統(tǒng)本身提供部分預(yù)定義的窗口類,程序員也可以自定義窗口類,窗口類必須先注冊(cè)后使用。if(!RegisterClass(&wndclass)) //如果注冊(cè)失敗 發(fā)出警告{MessageBeep(0); return FALSE;}//創(chuàng)建窗口創(chuàng)建一個(gè)窗口的實(shí)例由函數(shù)CreateWindow()實(shí)現(xiàn)hwnd=CreateWindow( lpszClassName, //窗口類名,創(chuàng)建窗口時(shí)一定要基于我們已經(jīng)注冊(cè)過的窗口類名,即"窗口"。lpszTitle, //窗口標(biāo)題名WS_OVERLAPPEDWINDOW, //窗口的風(fēng)格 WS_ Windows StyleCW_USEDEFAULT, //窗口左上角坐標(biāo)值為缺省值 CW_ Create Wndow CW_USEDEFAULT,CW_USEDEFAULT, //窗口的高和寬為缺省值 CW_USEDEFAULT,NULL, //此窗口無父窗口NULL, //此窗口無子菜單hInstance, //創(chuàng)建此窗口的應(yīng)用程序的當(dāng)前句柄NULL //不使用該值 );//顯示窗口 ShowWindow(hwnd,nCmdShow);//繪制用戶區(qū) UpdateWindow(hwnd);//消息循環(huán)while(GetMessage(&Msg,NULL,0,0)) //GetMessage()函數(shù)是從調(diào)用線程的消息隊(duì)列中取出一條消息;對(duì)于每一個(gè)應(yīng)用程序窗口線程,操作系統(tǒng)都會(huì)為其建立一個(gè)消息隊(duì)列,當(dāng)我們的窗口有消息時(shí)(即所有與這個(gè)窗口線程相關(guān)的消息),操縱系統(tǒng)會(huì)把這個(gè)消息放到該線程的消息隊(duì)列當(dāng)中,我們的窗口程序就通過這個(gè)GetMessage()函數(shù)從自己的消息隊(duì)列中取出一條一條具體的消息并進(jìn)行響應(yīng)操作。 {TranslateMessage(&Msg);//對(duì)"消息對(duì)"的轉(zhuǎn)化,如對(duì)鍵盤的WM_KEYDOWN和WM_KEYUP消息對(duì)轉(zhuǎn)化為WM_CHAR消息,并且將轉(zhuǎn)換后的新消息投遞到我們的消息隊(duì)列中去,
這個(gè)轉(zhuǎn)化操作不會(huì)影響原來的消息,只會(huì)產(chǎn)生一個(gè)新的消息。DispatchMessage(&Msg);//DispatchMessage()函數(shù)是將我們?nèi)〕龅南鞯酱翱诘幕卣{(diào)函數(shù)去處理;可以理解為該函數(shù)將取出的消息路由給操作系統(tǒng),然后操作系統(tǒng)去調(diào)用我們的窗口回調(diào)函數(shù)對(duì)這個(gè)消息進(jìn)行處理。 }return Msg.wParam; //消息循環(huán)結(jié)束 即程序結(jié)束時(shí) 將信息返回系統(tǒng) } //窗口函數(shù),窗口函數(shù)定義了應(yīng)用程序?qū)邮盏降牟煌⒌捻憫?yīng),其中包含了應(yīng)用程序?qū)Ω鞣N可能接受到的消息的處理過程,時(shí)消息處理分支控制語句的集合 long CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) {switch(message){case WM_DESTROY:PostQuitMessage(0);default: //缺省時(shí)采用系統(tǒng)消息缺省處理函數(shù)return DefWindowProc(hwnd,message,wParam,lParam);}return (0); } 注:窗口回調(diào)函數(shù)的函數(shù)指針定義typedef LRESULT CALLBACK (* WNDPROC)(HWND, UINT, WPARAM, LPARAM); WNDPROC OldWndProc; LRESULT CALLBACK NewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){switch (Msg){......}return CallWindowProc(OldWndProc,g_Wnd,Msg,wParam,lParam); } OldWndProc = (WNDPROC)GetWindowLong(g_Wnd,GWL_WNDPROC); SetWindowLong(hwnd, GWL_WNDPROC,(LPARAM)(WNDPROC)NewWndProc); 通過調(diào)用SetWindowLong函數(shù)可以修改該窗體類的回調(diào)函數(shù)。
?
轉(zhuǎn)載于:https://www.cnblogs.com/sepmaple/p/9321732.html
總結(jié)
以上是生活随笔為你收集整理的《VC++深入详解》学习笔记 第一章 Windows程序内部运行机制的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Redis使用场景一,查询出的数据保存到
- 下一篇: c/c++拷贝构造函数和关键字expli