C語言Windows程序開發—CreateWindow函數介紹【第03天】

(一)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 }
View Code

運行結果:

代碼說明:

(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函數的功用

 專門用於建立窗口控件,方便程序擴展,同時可以縮減回調函數的代碼行數。

相關文章
相關標籤/搜索