• C语言Windows程序开发—CreateWindow函数介绍【第03天】


    (一)CreateWindow函数的参数介绍:

     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 ); 

    函数调用示例:

    (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个参数:窗口标题名称;

    第3个参数:窗口样式;

    第4个参数:窗口左上角(X,Y)的X坐标,CW_USEDEFAULT表示使用缺省值;

    第5个参数:窗口左上角(X,Y)的Y坐标,CW_USEDEFAULT表示使用缺省值;

    第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函数的功用

     专门用于创建窗口控件,方便程序扩展,同时能够缩减回调函数的代码行数。

  • 相关阅读:
    【Windows】netsh动态配置端口转发
    Python 脚本注册为Windows Service
    【Windows】Python脚本随机启动
    【MySQL】CSV 文件导入MySQL
    【Python】改变对象的字符串显示
    【Python】偏函数
    【Python】装饰器理解
    【Python】什么是闭包
    【Python】高阶函数介绍
    【Python】__all__ 暴露接口
  • 原文地址:https://www.cnblogs.com/petrol/p/9795401.html
Copyright © 2020-2023  润新知