Windows 程序內(nèi)部運(yùn)行機(jī)制 一,、WinMain 函數(shù)原型
int WINAPI WinMain( HINSTANCE hInstance, // handle to current instance 程序當(dāng)前運(yùn)行實(shí)例句柄 HINSTANCE hPrevInstance, // handle to previous instance 前一個(gè)實(shí)例句柄,,參數(shù)總為NULL LPSTR lpCmdLine, // command line 以空字符串結(jié)尾的命令行參數(shù) int nCmdShow // show state 指定窗口的顯示方式 ) 二,、創(chuàng)建一個(gè)窗口 1.設(shè)計(jì)一個(gè)窗口類 2.注冊(cè)一個(gè)窗口類 3.創(chuàng)建窗口 4.顯示及更新窗口 (1).設(shè)計(jì)一個(gè)窗口類 typedef struct _WNDCLASS{ UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HANDLE hInstance; HICON Icon; HCURSOR Cursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; } WNDCLASS; ① style 屬性指定窗口樣式: CS_HREDRAW - 水平寬度變化重繪,。 CS_VREDRAW - 垂直方向高度變化重繪. CS_NOCLOSE - 禁用系統(tǒng)CLOSE命令.設(shè)關(guān)閉按鈕. CS_DBLCLKS - 窗口接收雙擊消息. ?、?lpfnwndproc 函數(shù)指針 指向窗口過程函數(shù) 窗口過程函數(shù)是一個(gè)回調(diào)函數(shù) ③ cbclsExtra; -- 一般值為0 Windows 系統(tǒng)中每一個(gè)窗口類型管理一個(gè)WNDCLASS結(jié)構(gòu) ?、?cbwndExtra; -- 一般值為0 Windows系統(tǒng)中為每一個(gè)窗口管理一個(gè)內(nèi)部數(shù)據(jù)結(jié)構(gòu),在注冊(cè)一個(gè)窗口類時(shí), 應(yīng)用程序能夠指定一定字節(jié)數(shù)的附加內(nèi)存空間,稱為窗口附加內(nèi)存. ?、輍Instance 包含窗口過程的程序?qū)嵗浔?/p> ⑥hIcon 窗口類圖標(biāo)句柄 成員變量須為一個(gè)圖標(biāo)資源句柄且成員為NULL,為系統(tǒng)提供默認(rèn)圖標(biāo) 我們可使用loadIcon函數(shù)來加載一個(gè)圖標(biāo)資源,并且它給系統(tǒng)分配圖標(biāo)句柄. 函數(shù)原型: HIcon loadIcon(HINSTANCE hInstance, LPCTSTR lpIconName) ?、遠(yuǎn)Cursor指定窗口類光標(biāo)句柄 -- 必須加載一個(gè)光標(biāo)資源句柄,如果成員為NULL, 無論何時(shí)鼠標(biāo)進(jìn)入到應(yīng)用程序窗口中,應(yīng)用程序都必須明確設(shè)置光標(biāo)形狀,。 ⑧hbrBackgound指定窗口類背景畫刷句柄 當(dāng)窗口發(fā)生重繪,系統(tǒng)使用這里指定畫刷來擦除窗口背影. ?、?lpszMenuName -- 指定菜單資源名字(以以后終止字符串) 如果使用菜單資源ID,那么需要用MAKENTRESouRCE宏來轉(zhuǎn)換 如果將其初始化為NULL,那么就算默認(rèn)沒有菜單,。 ⑩ lpszClassName - 指定窗口類名字(相當(dāng)于給窗口取名字)
三,、注冊(cè)窗口類 設(shè)計(jì)宏窗口類后(WNDCLASS),,我們還需要用 RegisterClass函數(shù) 對(duì)其進(jìn)行注冊(cè),注冊(cè)成功后,,才可創(chuàng)建該類型窗口 原型如下: ATOM RisterClass(Const WNDCLASS *LPWNDCLass); 函數(shù)只有 - 參數(shù),,即上步驟中所設(shè)計(jì)窗口類對(duì)象指針。 四,、創(chuàng)建窗口 -- CreateWindow 函數(shù) HWND CreateWindow( LPCTSTR lpClassName, // 窗口類的名稱 說明1 LPCTSTR lpWindowName // 窗口的名字 - 窗口樣式又標(biāo)題欄,指定窗口名是在標(biāo)題欄 DWORD dwstyle, // 指定窗口類樣式,具體參考WS_OVERLAPPEDWINDOW類型 int x, // 窗口左上角x.y坐標(biāo) -- 寬,、高。 -- x,設(shè)為CW_USEDEFAULT,窗口默認(rèn)左上角坐標(biāo)忽略y參數(shù),。 int y, int nWidth, int nHeight, // - 設(shè)為 CW_USEDEFAULT 窗口默認(rèn)寬,、高,nHight忽略。 HWND hwndparent, // 創(chuàng)建窗口的父窗口句柄 HMENU hmenu. // 指定窗口菜單句柄 HANDLE hInstance, // 指定窗口所屬應(yīng)用程序?qū)嵗浔?/p> LPVOID lparam // WM_CREATE消息附加參數(shù)lparam傳入數(shù)據(jù)指針 // 創(chuàng)建多文檔界面窗口,lparam指向CLIENTCREATESRUCT結(jié)構(gòu)體多數(shù)窗口設(shè)為NULL // 說明1,、調(diào)用CreateWindows函數(shù)前,沒有用RegisterClass函數(shù),,注冊(cè)名稱的窗口類。 #define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED // 產(chǎn)生層疊窗口有標(biāo)題欄和邊框 WS_CAPTION |\ 創(chuàng)建一個(gè)有標(biāo)題窗口 WS_SYSMENU |\ 創(chuàng)建在標(biāo)題欄上有系統(tǒng)菜單和WS_CAPTION類型一起作用 WS_THICKFRAME |\ 創(chuàng)建一個(gè)具有可調(diào)邊框窗口 WS_MINIMIZEBOX |\ 最小化窗口,設(shè)定WS_SYSMENU類型 WS_MAXIMIZEBOX |\ 最大化窗口,設(shè)定WS_SYSMENU類型 ) 窗口創(chuàng)建成功,CreaeWindow 函數(shù)返回系統(tǒng)為窗口分配句柄,,否則返回NULL 五,、顯示及更新窗口 -- ShowWindow 函數(shù) 原型 Bool ShowWindow( HWND hwnd, // 創(chuàng)建窗口后返回哪個(gè)窗口句柄。 int nCmdshow // 用來指定窗口顯示狀態(tài),。 ); nCmdShow 參數(shù)一般為: SW_HIDE -- 隱藏并激活其他窗口 SW_SHOW --窗口原位置 以原來尺寸激活和顯示窗口 SW_SHOWMAXIMIZED -- 激活窗口并將其最大化顯示 SW_SHOWMINIMIZED -- 激活窗口并將其最小化顯示 SW_SHOWNORMAL -- 激活并顯示窗口 -- 窗口最小化或最大化狀態(tài) 系統(tǒng)其恢復(fù)原來尺寸和大小,。 更新窗口 -- updateWindow來刷新窗口 原型 Bool updateWindow( HWHD hwndl;// 指創(chuàng)建成功后的窗口句柄 ) updateWindow 函數(shù)通過發(fā)送一個(gè)WM_PAINT 消息來刷新窗口 updateWindow 將WM_PAINT消息直接發(fā)送給窗口過程函數(shù)進(jìn)行處理,而沒放到我們前面所說的消息隊(duì)列中。 六,、消息循環(huán) -- GetMessage函數(shù) 原型: Bool Getmessage( LPMSG lpmsg, // 指向一個(gè)消息結(jié)構(gòu)體 -- 將消息隊(duì)列中信息保存在結(jié)構(gòu)體對(duì)象中,。 HWND hwnd, // 接收屬于哪個(gè)窗口消息,通常設(shè)置NULL接收屬于調(diào)用線程所有窗口的窗口消息 UINT WMsgFiltermin, // 獲取消息最小值,設(shè)為0接收所有消息。 UINT WMsgFiltermax // 獲取消息最大值,設(shè)為0接收所有消息,。 );
GetMessage 接收除WM_QUIT外消息的非零值,對(duì)于WM_QUIT消息函數(shù)返回零,如果出現(xiàn)錯(cuò)誤,, 函數(shù)直接返回-1 MSG msg; while (GetMessage(&msg,null,0,0)) { Translatemessage(&msg); // 用于將虛擬鍵消息轉(zhuǎn)換為字符消息 Dispatchmessage(&msg); // 分配一個(gè)消息到窗口過程,窗口過程函數(shù)對(duì)消息進(jìn)行處理 } 七,、編寫窗口過程函 LRESULT CALLBACK WinSunProc( HWND hwnd, // 窗口句柄 UINT uMsg, // 消息代碼 WPARAM wParam, // 第一條消息參數(shù) LPARAM lParam // 第二條消息參數(shù) ); { switch(uMsg) { case WM_CHAR: // 用戶按下字符鍵時(shí)...收到WM_CHAR消息通過Translatemessage函數(shù)轉(zhuǎn)換ASCII值。 char szChar[20]; sprintf(szChar,"char code is %d",wParam); MessageBox(hwnd,szChar,"char",0); break; case WM_LBUTTONDOWN: // 接收窗口按下鼠標(biāo)左鍵 會(huì)產(chǎn)生 WM_LBUTTONDOWN 消息. MessageBox(hwnd,"mouse clicked","message",0); HDC hdc; hdc=GetDC(hwnd); TextOut(hdc,0,50,"程序員之家",strlen("程序員之家")); //ReleaseDC(hwnd,hdc); break; case WM_PAINT: // 對(duì) WM_PAINT 消息進(jìn)行處理,。當(dāng)窗口客戶區(qū)部分或全部無效時(shí),系統(tǒng)發(fā)生 WM_PAINT 消息 // 通知應(yīng)用程序重新繪制窗口,。 HDC hDC; PAINTSTRUCT ps; hDC=BeginPaint(hwnd,&ps); TextOut(hDC,0,0,"http://www.",strlen("http://www.")); EndPaint(hwnd,&ps); break; case WM_CLOSE: // 用戶點(diǎn)擊關(guān)閉按鈕時(shí) 系統(tǒng)會(huì)接收 WM_CLOSE if(IDYES==MessageBox(hwnd,"是否真的結(jié)束,?","message",MB_YESNO)) { DestroyWindow(hwnd); // 當(dāng)用戶在對(duì)話框上選擇 是時(shí)~~會(huì)調(diào)用DestroyWindow銷毀窗口,。 } break; case WM_DESTROY: // 要想讓程序正常退出,必須響應(yīng) WM_DESTROY 消息~~并在消息代碼中調(diào)用 PostQuitMessage 函數(shù) PostQuitMessage(0); break; default: return DefWindowProc(hwnd,uMsg,wParam,lParam); // 函數(shù)調(diào)用默認(rèn)的窗口過程,對(duì)程序沒有處理的其他消息提供默認(rèn)處理。 } |
|