嗯…
每次用視窗,全部都忘光
借這次機會複習一下!
天殺的 FireFox 給我出錯當機
所以會打得簡約一點…
Win32視窗原理可參考「概論 Win32 C++程式之標準視窗建立過程、架構」
節錄一段…
1. 與Console程式不同的是,Win32視窗程式的進入點為WinMain() 2. 在WinMain中呼叫RegisterClass向作業系統註冊類別,其中必須設定視窗的屬性、以及所對應的Windows Procedure(視窗函式)函數名稱 3. 呼叫CreateWindow建立視窗,送出WM_CREATE讓該視窗初始化。 4. 呼叫ShowWindow將視窗顯示出來 5. 程式運作時,不斷的呼叫GetMessage,從系統訊息佇列中抓取訊息。當取得WM_QUIT時,便回傳0中斷此迴路 6. 呼叫TranslateMessage轉化,再呼叫DispatchMessaeg,透過Windows User模組,把訊息分派給視窗函式 7. 重複5~6,不斷的GetMessage→TranslateMessage→DispatchMessage 8. 當使用者按下功能表的Close,系統送出WM_CLOSE,通常程式並不會攔截該訊息,由DefWindowProc處理 9. DefWindowProc收到WM_CLOSE之後,呼叫DestroyWindow將視窗清除,本身再送出WM_DESTROY 10. 程式對WM_DESTROY的標準反應:呼叫PostQuitMessage 11. PostQuitMessage送出WM_QUIT,使步驟五可結束迴路,以免佔據資源 |
Win32 和 Console 最開始的不同處就是進入點
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) |
首先,填寫註冊表
WNDCLASS wndclass ; static TCHAR szAppName[] = TEXT ("挖ㄟ視窗") ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; |
請參考「WNDCLASS Structure」「MAKEINTRESOURCE Macro」
「LoadMenu Function」「LoadIcon Function」「LoadCursor Function」
讀取資源相關的可參考「LoadIcon」的介紹。
其中 lpfnWndProc 是函數指標,詳見「CallWindowProc Function」
當然要在填寫註冊表之前先宣告
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); |
接著提出申請
// wndclass 是上面填寫的註冊表 if (!RegisterClass (&wndclass)) { … |
申請後並沒有實體,需要 Create
hwnd = CreateWindow (szAppName, // window class name TEXT ( "丟系視窗標題" ), // window caption WS_OVERLAPPEDWINDOW, // window style   ; CW_USEDEFAULT, // initial x position CW_USEDEFAULT, // initial y position 100, // initial x size 100, // initial y size NULL, // parent window handle NULL, // window menu handle hInstance, // program instance handle NULL) ; // creation parameters |
請參考「CreateWindow Function」
第一個參數是用來判別之前申請的視窗名稱(lpszClassName),差一個字都不行嘿!
hwnd 是用來接收 CreateWindow 回傳的視窗 handle
基本上,剛產出來的新視窗都是隱藏狀態的,要把他們 show 出來
// hWnd 是上面產生的新視窗 // iCmdShow 是從 WinMain 的參數列來的 ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; |
請參考「ShowWindow Function」「UpdateWindow」
再來就是不斷的接收、轉換和傳送訊息…
// msg 是一個用來接收訊息的 MSG 變數 while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } |
請參考「GetMessage Function」「TranslateMessage Function」「DispatchMessage Function」
最後回傳結果
return msg.wParam ; |
大致上就是這樣,CallWindowProc 的部分另一篇在說囉~