(一)CreateWindow函數的參數介紹:windows
1 HWND CreateWindow( 2 LPCTSTR lpClassName, //Windows窗口中預約義的控件結構體,包括:BUTTON(按鈕),EDIT(文本框),LISTBOX(列表),MDICLIENT(子窗口),SCROLLBAR(滾動條),RICHEDIT(富文本),STATIC(靜態控件); 3 LPCTSTR lpWindowName, //窗口控件中顯示的內容,即Caption屬性; 4 DWORD dwStyle, //控件樣式,包括:WS_CHILD | WS_VISIBLE | WS_BORDER,還能夠根據具體控件類型添加相應樣式 5 int x, //窗口或控件左上角(X,Y)的X座標 6 int y, //窗口或控件左上角(X,Y)的Y座標 7 int nWidth, //窗口或控件的寬度 8 int nHeight, //窗口或控件的高度 9 HWND hWndParent, //父窗口句柄 10 HMENU hMenu, //菜單或者子窗口或控件的ID 11 HANDLE hInstance, //實例 12 PVOID lpParam // 13 );
函數調用示例:ide
(1)建立窗口函數
1 /* 建立窗口 */ 2 hwnd = CreateWindow ( szAppName, TEXT ("輸出字符串演示"), 3 WS_OVERLAPPEDWINDOW, 4 CW_USEDEFAULT, CW_USEDEFAULT, 5 CW_USEDEFAULT, CW_USEDEFAULT, 6 NULL, NULL, hInstance, NULL ) ;
第1個參數:szAppName是字符串變量,如TEXT ("MyWindow"),表示爲程序名稱;字體
第2個參數:窗口標題名稱;ui
第3個參數:窗口樣式;spa
第4個參數:窗口左上角(X,Y)的X座標,CW_USEDEFAULT表示使用缺省值;code
第5個參數:窗口左上角(X,Y)的Y座標,CW_USEDEFAULT表示使用缺省值;blog
第6個參數:窗口寬度,CW_USEDEFAULT表示使用缺省值;隊列
第7個參數:窗口高度,CW_USEDEFAULT表示使用缺省值;字符串
第8個參數:若是有父窗口,則是父窗口句柄,NULL表示沒有父窗口;
第9個參數:若是有菜單,則是菜單的ID,NULL表示沒有菜單;
第10個參數:執行實例代碼;
第11個參數:
(2)建立控件
1 /* 建立編輯區 */ 2 hwndChild[ID_EDITBOX] = CreateWindow( TEXT("edit"), NULL, 3 WS_CHILD | WS_VISIBLE | WS_BORDER | 4 ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL, 5 0, 0, 0, 0, 6 hwnd, (HMENU)ID_EDITBOX, hInst, NULL ) ;
第1個參數:建立控件所屬的預約義控件結構體,TEXT ("edit")表示建立文本框,若是是TEXT("button"),則表示建立按鈕;
第2個參數:控件的標題名稱,在建立文本框時,該參數不爲空(如TEXT(「UserName」)),則建立成功後會在文本框中顯示UserName;
第3個參數:在建立控件或子窗口時,必須樣式WS_CHILD | WS_VISIBLE和該控件具備的特有樣式,ES_LEFT表示文本框中內容左對齊;
第4~7個參數:控件的左上角(X,Y)座標,寬度與高度,能夠在回調函數的WM_SIZE中經過MoveWindow函數進行調整;
第8個參數:父窗口句柄,表示控件文本框所在的窗口句柄;
第9個參數:控件ID,並強制轉換爲HMENU類型;
第10個參數:執行實例代碼
第11個參數:
經過對比建立窗口或子窗口(或控件)時CreateWindow函數的參數賦值,發現:
第1個參數在建立控件時尤其重要,其做用是聲明正在建立控件的預約義控件結構體;
第4~7個參數是來限定窗口或控件的尺寸;
第8個參數都表示其父窗口句柄,如果控件,則是控件所在窗口的句柄;
第10個參數都是執行實例代碼,可是子窗口(或控件)的執行實例代碼hInst = ((LPCREATESTRUCT) lParam) -> hInstance;
(二)CreateWindow函數實例應用
1 /* 建立Login窗口*/ 2 #include <windows.h> 3 #include <stdio.h> 4 5 #define ID_UserName 1000 6 #define ID_Password 1001 7 #define ID_btnLogin 1002 8 9 /* 聲明回調函數 */ 10 LRESULT CALLBACK WndProc ( HWND, UINT, WPARAM, LPARAM ) ; 11 12 /* 聲明建立窗口控件 */ 13 int CreateChildWindow ( HWND, HWND *, LPARAM ) ; 14 15 /* 主函數 */ 16 int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow ) 17 { 18 static TCHAR szAppName [] = TEXT ("Demo") ; 19 HWND hwnd ; 20 MSG msg ; 21 WNDCLASS wndclass ; 22 23 wndclass.style = CS_HREDRAW | CS_VREDRAW ; //窗口樣式 24 wndclass.lpfnWndProc = WndProc ; //窗口的回調函數 25 wndclass.hInstance = hInstance ; //窗口實例句柄 26 wndclass.cbClsExtra = 0 ; //窗口結構體擴展:無 27 wndclass.cbWndExtra = 0 ; //窗口實例擴展:無 28 wndclass.hbrBackground = ( HBRUSH ) GetStockObject ( WHITE_BRUSH ) ; //窗口背景 29 wndclass.hIcon = LoadIcon ( NULL, IDI_APPLICATION ) ; //窗口圖標 30 wndclass.hCursor = LoadCursor ( NULL, IDC_ARROW ) ; //窗口中的鼠標樣式 31 wndclass.lpszClassName = szAppName ; //窗口結構體名稱 32 wndclass.lpszMenuName = NULL ; //主菜單名稱:無 33 34 /* 註冊窗口結構體 */ 35 if ( !RegisterClass ( &wndclass ) ) 36 { 37 MessageBox ( NULL, TEXT ("沒法註冊窗口結構體!"), TEXT ("錯誤"), MB_OK | MB_ICONERROR) ; 38 return 0 ; 39 } 40 41 /* 建立Login窗口 */ 42 hwnd = CreateWindow ( szAppName, TEXT ("登陸"), 43 WS_OVERLAPPEDWINDOW, 44 CW_USEDEFAULT, CW_USEDEFAULT, 45 400, 300, 46 NULL, NULL, hInstance, NULL ) ; 47 48 /* 顯示與更新窗口 */ 49 ShowWindow ( hwnd, iCmdShow ) ; 50 UpdateWindow ( hwnd ) ; 51 52 /* 從消息隊列中獲取消息 */ 53 while ( GetMessage ( &msg, NULL, 0, 0 ) ) 54 { 55 TranslateMessage ( &msg ) ; //將虛擬鍵消息轉換爲字符消息 56 DispatchMessage ( &msg ) ; //將消息傳遞給回調函數處理 57 } 58 59 return msg.wParam ; 60 } 61 62 /* 回調函數 */ 63 LRESULT CALLBACK WndProc (HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam ) 64 { 65 static HWND hChild [2] ; 66 HDC hdc ; 67 PAINTSTRUCT ps ; 68 RECT rect ; 69 70 static int cxChar, cyChar ; 71 72 switch ( umsg ) 73 { 74 case WM_CREATE : //處理窗口建立成功後發來的消息 75 /* 建立窗口控件 */ 76 CreateChildWindow ( hwnd, hChild, lParam ) ; 77 78 cxChar = LOWORD (GetDialogBaseUnits ()); //得到窗口中內定字體字元寬度(低字組) 79 cyChar = HIWORD (GetDialogBaseUnits ()); //或得窗口中內定字體字元高度(高字組) 80 return 0 ; 81 82 case WM_SIZE : //處理窗口尺寸發生改變後發來的消息 83 GetClientRect ( hwnd, &rect ) ; 84 MoveWindow ( hChild [ ID_UserName ], rect.left + cxChar * 12, 110, cxChar * 24, cyChar * 5 / 4, TRUE ) ; 85 MoveWindow ( hChild [ ID_Password ], rect.left + cxChar * 12, 160, cxChar * 24, cyChar * 5 / 4, TRUE ) ; 86 MoveWindow ( hChild [ ID_btnLogin ], rect.left + cxChar * 12, 210, cxChar * 12, cyChar * 7 / 4, TRUE ) ; 87 return 0 ; 88 89 case WM_PAINT : //處理窗口產生無效區域時發來的消息 90 GetClientRect ( hwnd, &rect ) ; 91 hdc = BeginPaint ( hwnd, &ps ) ; 92 TextOut ( hdc, rect.left + cxChar * 12, 95, TEXT ("UserName:"), lstrlen ( TEXT ("UserName:") ) ) ; 93 TextOut ( hdc, rect.left + cxChar * 12, 145, TEXT ("Password:"), lstrlen ( TEXT ("Password:") ) ) ; 94 EndPaint ( hwnd, &ps ) ; 95 return 0 ; 96 97 case WM_DESTROY : //處理窗口關閉時發來的消息 98 PostQuitMessage (0) ; 99 return 0 ; 100 } 101 102 return DefWindowProc ( hwnd, umsg, wParam, lParam ) ; 103 } 104 105 /* 建立控件 */ 106 int CreateChildWindow ( HWND hwnd, HWND * hChild, LPARAM lParam ) 107 { 108 HINSTANCE hInst = ( ( LPCREATESTRUCT ) lParam ) -> hInstance ; 109 110 /* 建立UserName文本框 */ 111 hChild [ ID_UserName ] = CreateWindow ( TEXT ("edit"), NULL, 112 WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT, 113 0, 0, 0 , 0, 114 hwnd, ( HMENU ) ID_UserName, hInst, NULL ) ; 115 116 /* 建立Password文本框 */ 117 hChild [ ID_Password ] = CreateWindow ( TEXT ("edit"), NULL, 118 WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT, 119 0, 0, 0, 0, 120 hwnd, ( HMENU ) ID_Password, hInst, NULL ) ; 121 122 /* 建立Login按鈕 */ 123 hChild [ ID_btnLogin ] = CreateWindow ( TEXT ("button"), TEXT ("Login"), 124 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_CENTER, 125 0, 0, 0, 0, 126 hwnd, ( HMENU ) ID_btnLogin, hInst, NULL ) ; 127 128 return 0 ; 129 }
運行結果:
代碼說明:
(1)WndProc回調函數中的消息處理
<1>WM_SIZE消息處理
1 case WM_SIZE : //處理窗口尺寸發生改變後發來的消息 2 GetClientRect ( hwnd, &rect ) ; 3 MoveWindow ( hChild [ ID_UserName ], rect.left + cxChar * 12, 110, cxChar * 24, cyChar * 5 / 4, TRUE ) ; 4 MoveWindow ( hChild [ ID_Password ], rect.left + cxChar * 12, 160, cxChar * 24, cyChar * 5 / 4, TRUE ) ; 5 MoveWindow ( hChild [ ID_btnLogin ], rect.left + cxChar * 12, 210, cxChar * 12, cyChar * 7 / 4, TRUE ) ; 6 return 0 ;
GetClientRect函數獲取登陸窗口的矩形區域,即登陸窗口中除去標題欄的矩形區域,MoveWindow函數調整控件的尺寸(即CreateWindow函數中的第4~7個參數);
<2>WM_PAINT消息處理
1 case WM_PAINT : //處理窗口產生無效區域時發來的消息 2 GetClientRect ( hwnd, &rect ) ; 3 hdc = BeginPaint ( hwnd, &ps ) ; 4 TextOut ( hdc, rect.left + cxChar * 12, 95, TEXT ("UserName:"), lstrlen ( TEXT ("UserName:") ) ) ; 5 TextOut ( hdc, rect.left + cxChar * 12, 145, TEXT ("Password:"), lstrlen ( TEXT ("Password:") ) ) ; 6 EndPaint ( hwnd, &ps ) ; 7 return 0 ;
BeginPaint函數與EndPaint函數必須成對出現,BeginPaint函數表示開始繪製窗口,同時使整個顯示區域變爲有效,更新顯示區域的內容,例如在窗口中用TextOut函數輸出內容。
(2)自定義CreateChildWindow函數
1 /* 建立控件 */ 2 int CreateChildWindow ( HWND hwnd, HWND * hChild, LPARAM lParam ) 3 { 4 HINSTANCE hInst = ( ( LPCREATESTRUCT ) lParam ) -> hInstance ; 5 6 /* 建立UserName文本框 */ 7 hChild [ ID_UserName ] = CreateWindow ( TEXT ("edit"), NULL, 8 WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT, 9 0, 0, 0 , 0, 10 hwnd, ( HMENU ) ID_UserName, hInst, NULL ) ; 11 12 /* 建立Password文本框 */ 13 hChild [ ID_Password ] = CreateWindow ( TEXT ("edit"), NULL, 14 WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT, 15 0, 0, 0, 0, 16 hwnd, ( HMENU ) ID_Password, hInst, NULL ) ; 17 18 /* 建立Login按鈕 */ 19 hChild [ ID_btnLogin ] = CreateWindow ( TEXT ("button"), TEXT ("Login"), 20 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_CENTER, 21 0, 0, 0, 0, 22 hwnd, ( HMENU ) ID_btnLogin, hInst, NULL ) ; 23 24 return 0 ; 25 }
<1>CreateChildWindow函數的參數介紹
1 int CreateChildWindow ( 2 HWND hwnd, //父窗口句柄 3 HWND * hChild, //子窗口或控件句柄 4 LPARAM lParam //lParam參數的低字組包含顯示區域寬度,高字組包含顯示區域高度 5 );
<2>CreateChildWindow函數的功用
專門用於建立窗口控件,方便程序擴展,同時可以縮減回調函數的代碼行數。