英吋 C++

Win32 基礎視窗

嗯…
每次用視窗,全部都忘光
借這次機會複習一下!
天殺的 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.lpfnWndProc = WndProc;
 wndclass.cbClsExtra = 0;
 wndclass.cbWndExtra = 0;
 wndclass.hInstance = hInstance ;
 wndclass.hIcon = LoadIcon (NULL, "eco.ico");
 wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
 wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
 wndclass.lpszMenuName = MAKEINTRESOURCE (IDR_MyMenu);
 wndclass.lpszClassName = szAppName;


請參考「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))
  { …


請參考「RegisterClass Function

申請後並沒有實體,需要 Create

 hwnd = CreateWindow (szAppName,                                  // window class name
                             TEXT ( "丟系視窗標題" ),                      // window caption
                             WS_OVERLAPPEDWINDOW,                // window style
                        &nbsp
;    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 的部分另一篇在說囉~

–End

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google photo

您的留言將使用 Google 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.