Windows簡單窗口的創建

Windows窗口的創建主要需要兩個部分,一個是窗口類,一個就是處理你窗口類消息的窗口過程,可以簡單理解窗口過程是用於處理Windows傳遞到窗口的消息,例如這消息可以是鼠標的輸入。

Windows對於窗口的處理是通過它對窗口發送消息,然後藉由這個消息進行窗口的窗口過程從而影響窗口。

Windows通過消息隊列和非消息隊列對窗口進行維護,在Windows程序開始執行時,Windows首先會爲程序創建一個消息隊列,該消息隊列存放這應用程序可能創建的所有窗口的消息。然後通過名爲“消息循環”的代碼,從消息隊列中檢索消息,並將其發給相應的窗口過程,其他消息則不通過消息隊列發給窗口過程。


下面是具體的實現代碼,由Charles Petzold大師所編寫,然後添加了我的註釋:

編譯環境:win7 64位 IDE:vs2010

/*------------------------------------------------------------
   HELLOWIN.C -- Displays "Hello, Windows 98!" in client area
                 (c) Charles Petzold, 1998
  ------------------------------------------------------------*/

#include <windows.h>

using namespace std;
 
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;//窗口過程,可以簡單理解爲處理窗口的機制,如創建窗口,關閉窗口等等

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     static TCHAR szAppName[] = TEXT ("HelloWin") ;
     HWND         hwnd ;//HWND是窗口句柄,類似的有HDC(設備環境句柄),HINSTANCE(實例句柄——程序本身)
     MSG          msg ;//MSG是消息結構,可以傳遞鼠標,鍵盤之類操作的消息
     WNDCLASS     wndclass ;//WNDCLASS是窗口類,這裏定義了一個叫wndclass的窗口

	 /*------------------------------------------------------------
	   窗口類的結構
	   typedef struct
	   {
	       UINT       style;//窗口的風格
		   WNDPROC    lpfnWndProc;//用於基於該窗口類的所有窗口的窗口過程的地址
		   int        cbClsExtra;//Windows系統應該預留分配給類的額外內存數量
		   int        cbWndExtra;//Windows系統應該預留分配給窗口的額外內存數量
		   HINSTANCE  hInstance;//
		   HICON      hIcon;//窗口圖標
		   HCURSOR    hCursor;//窗口上鼠標樣式
		   HBRUSH     hbrBackground;//窗口背景色
		   LPCTSTR    lpszMenuName;//窗口類的菜單
		   LPCTSTR    lpszClassName;//窗口類的名稱
		}
		WNDCLASS,* PWNDCLASS;
		------------------------------------------------------------*/

     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;//定義窗口的風格,CS_HREDRAW(窗口的水平尺寸),CS_VREDRAW(窗口的垂直尺寸)
	                                                   //這裏表示當窗口的水平尺寸或垂直尺寸改變時,基於該窗口類的所有窗口都將被重新繪製
     wndclass.lpfnWndProc   = WndProc ;//定義該窗口類的窗口過程
     wndclass.cbClsExtra    = 0 ;//這個窗口不需要額外的空間
     wndclass.cbWndExtra    = 0 ;//這個窗口不需要額外的空間
     wndclass.hInstance     = hInstance ;//應用程序的實例句柄
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;//使用LoadIcon函數創建窗口的圖標
	                                                            //這裏使用的是預定義的圖標,所以第一個參數是NULL
	                                                            //如果是保存在磁盤裏的應用程序中的可執行文件加載自定義圖標,該參數必須爲hInstance
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;//使用LoadCursor函數創建窗口上鼠標圖標,如IDC_ARROW是個箭頭,IDC_HAND是隻手
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;//使用GetStockObject取得窗口背景色,這裏WHITE_BRUSH是白色,BLACK_BRUSH是黑色
     wndclass.lpszMenuName  = NULL ;//這裏沒使用菜單,設爲NULL
     wndclass.lpszClassName = szAppName ;//定義類的名稱

     if (!RegisterClass (&wndclass))//註冊一個窗口類
     {
          MessageBox (NULL, TEXT ("This program requires Windows NT!"), 
                      szAppName, MB_ICONERROR) ;//MessageBox有ASCALL碼和Unicode編碼形式,當時windows1998的MessageBox似乎不支持Unicode形式的這個函數
          return 0 ;
     }
     
     hwnd = CreateWindow (szAppName,                  // 窗口類的名稱
                          TEXT ("The Hello Program"), // 窗口的標題
                          WS_OVERLAPPEDWINDOW,        // 窗口的風格,overlapped是層疊窗口
                          CW_USEDEFAULT,              // 初始x座標,指定窗口左上角相對於屏幕左上角的初始位置,這裏取默認值
                          CW_USEDEFAULT,              // 初始y座標,指定窗口左上角相對於屏幕左上角的初始位置,這裏取默認值
                          CW_USEDEFAULT,              // 初始x方向尺寸
                          CW_USEDEFAULT,              // 初始y方向尺寸
                          NULL,                       // 其父窗口的句柄,這裏是頂級窗口,所以爲NULL
                          NULL,                       // 窗口菜單句柄,由於沒有菜單,所以爲NULL
                          hInstance,                  // 程序實例句柄,這裏用的是WinMain傳入的程序實例句柄
                          NULL) ;                     // 創建參數,這個還不懂
     
     ShowWindow (hwnd, iCmdShow) ;//顯示窗口,第一個參數是所需窗口的句柄
	                              //第二個參數決定窗口在屏幕中的初始顯示位置
	                              //如SW_SHOWNORMAL是窗口正常顯示,SW_SHOWMAXIMIZED是最大化,SW_SHOWMINNOACTIVE是顯示在任務欄
     UpdateWindow (hwnd) ;//這裏需要繪製窗口


     /*------------------------------------------------------------
	   MSG類的結構
	   typedef struct tagMSG
	   {
	       HWND      hwnd;//消息所指向的窗口句柄
		   UINT      message;//消息標識符,比如將鼠標放置在窗口的客戶區按下鼠標左鍵就是一個消息
		   WPARAM    wParam;//消息參數
		   LPARAM    lParam;//另一個消息參數
		   DWORD     time;//消息進入消息隊列的時間
		   POINT     pt;//消息進入消息隊列時鼠標所在位置座標
		}
		MSG,* PMSG;
		
		POINT是另一種結構
		typedef struct tagPOINT
		{
		   LONG x;
		   LONG y;
		}POINT,* PPOINT;
		------------------------------------------------------------*/



     while (GetMessage (&msg, NULL, 0, 0))//當得到的消息並不是關閉窗口時,繼續進行
     {
          TranslateMessage (&msg) ;//將msg結構返還給Windows進行某些鍵盤消息的轉換
          DispatchMessage (&msg) ;//將msg結構再次返還給Windows
     }//這裏執行一段名爲消息循環的代碼,可以用於接受鍵盤輸入和鼠標輸入
     return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)//第二個參數是傳遞的消息
{
     HDC         hdc ;
     PAINTSTRUCT ps ;//該結構包含一些窗口過程用來對客戶區進行繪製的信息
     RECT        rect ;//一種矩形結構
     
     switch (message)
     {
     case WM_CREATE://即創造窗口
          return 0 ;
          
     case WM_PAINT://窗口重新繪製,例如窗口的尺寸改變時需要重新繪製
          hdc = BeginPaint (hwnd, &ps) ;//BeginPaint函數的第一個參數爲程序的窗口句柄,第二個參數爲指向PAINTSTRUCT結構的指針
                                        //當該函數調用時,如果客戶區的背景尚未擦出,Windows會對其擦除
		                                //所使用的畫刷是註冊窗口類的WNDCLASS結構中的hbrBackground字段中指定的

          GetClientRect (hwnd, &rect) ;//該函數第二個參數是指向類型爲RECT的舉行結構的指針
		                               //RECT結構有四個類型爲LONG的字段,名稱爲left,top,right,bottom,該函數會根據窗口尺寸對這四個字段進行設置
          
          DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,
                    DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;//繪製文本,第一個參數是由BeginPaint函數返回的設備環境句柄
		                                                     //第二個參數是所要繪製的文本,第三個參數設爲-1,表示該文本字符串以0結尾
		                                                     //第四個參數爲位參數,如DT_VCENTER是將字體垂直居中
          
          EndPaint (hwnd, &ps) ;//釋放環境句柄,以使其無效
          return 0 ;
          
     case WM_DESTROY://窗口的破壞
          PostQuitMessage (0) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;//DefWindowProc函數用於對所有窗口過程沒有處理的消息進行默認處理
	                                                       //如果缺少該函數,窗口的其他正常行爲(如結束程序)將無法進行
}//窗口過程對消息進行處理後,應返還0

實現效果,圖片適當的調了大小:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章