• windows学习记录----hello world与窗口创建


    1.第一个程序:Hello,world!

    1 #include<windows.h>
    2 
    3 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow )
    4 {
    5     MessageBox( NULL, TEXT("Hello,world!"), TEXT("MessageBox"), 0 );
    6
    7    return 0;
    8 }

    WinMain()函数
    WINAPI为WinMain函数的调用规则, 在WINDEF.H对"WINAPI"作出了如下宏定义:
    #define WINAPI __stdcall
    WinMain函数的调用规则为"__stdcall"方式, 对于"__stdcall"调用规则, 具体用法待查
     
     
    WinMain函数的参数:
    1.HINSTANCE hInstance:实例句柄
    2.HINSTANCE hPrevInstance:前一个的实例句柄,历史原因,已无实际意义,总为NULL。
    3.LPSTR lpCmdLine:PSTR:运行程序的命令行。PSTR来指向一个字符串的指针类型, szCmdLine, sz:表示以0结尾的字符串;
    目的是通过命令行方式运行程序并向主函数中传入参数, 应该就像给main函数传入参数一样。暂未遇到具体命令程序,待学习。 4.程序(窗口)最初如何被显示, 例如最小化?最大化?全屏?暂未遇到具体命令程序,待学习。
    MessageBox函数:
    
    int MessageBox(
      HWND hWnd,          // handle of owner window, 窗口的一个句柄
      LPCTSTR lpText,     // address of text in message box, 一个文本(字符串)的指针
      LPCTSTR lpCaption,  // address of title of message box, 标题字符串的指针
      UINT uType          // style of message box, 对话框的风格
    );
    
    MessageBox( NULL, TEXT("Hello,world!"), TEXT("MessageBox"), 0 );
    第一个参数窗口的句柄的实参为NULL, 意思为不属于任何窗口.
    第二个参数为对话框的内容, 
    第三个参数为对话框的标题, 但是这两个参数都使用了一个TEXT()的函数,
          当使用wchar_t类型的宽字符时, 使用"令牌粘贴",  使用TEXT宏时就避免了在字符串前面加上一个大写字母'L'了。
                      
    #define __T(x)      L ## x
    
    #define _TEXT(x)    __T(x)
    
    #define __TEXT(quote)  L##quote  
    
    #define TEXT(quote)  __TEXT(quote)
    第四个参数为对话框的风格, 一些以MB_开头的一些常量的组合, 可以使用OR(|)运算进行组合, 这些常量定义在WINUSER.H中, 例如常用的有:
    1>.对话框按钮类型:
    
        #define MB_OK                       0x00000000L            //仅有一个"确定"按钮
        #define MB_OKCANCEL                 0x00000001L            //"确定" + "取消"
        #define MB_ABORTRETRYIGNORE         0x00000002L            //"终止" + "重试" + "忽略"
        #define MB_YESNOCANCEL              0x00000003L            //"是" + "否" + "取消"
        #define MB_YESNO                    0x00000004L            //"是" + "否"
        #define MB_RETRYCANCEL              0x00000005L            //"重试" + "取消"
    
     
    2>.对话框中的图标类型:  
    #define MB_ICONHAND                 0x00000010L            //一个红X的错误/停止图标
    #define MB_ICONQUESTION 0x00000020L //一个问号的询问图标
    #define MB_ICONEXCLAMATION 0x00000030L //一个黄色感叹号的警告图标
    #define MB_ICONASTERISK 0x00000040L //一个带有i的信息提示图标 同时, 在这些图标中有的还可以用其他名称代替, 这些别名在WINUSER.H的定义如下: #define MB_ICONWARNING MB_ICONEXCLAMATION //警告
    #define MB_ICONERROR MB_ICONHAND //错误
    #define MB_ICONINFORMATION MB_ICONASTERISK //信息
    #define MB_ICONSTOP MB_ICONHAND //停止

      2.创建自己的窗口

     

     1 #include <windows.h>
     2 
     3 LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ) ;        //声明用来处理消息的函
     4 
     5 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow )
     6 {
     7     static TCHAR szAppName[] = TEXT("MyWindow") ;
     8     HWND hwnd ;
     9     MSG msg ;
    10     WNDCLASS wndclass ;        //声明一个窗口类对象
    11 
    12     //以下为窗口类对象wndclass的属性
    13     wndclass.style = CS_HREDRAW | CS_VREDRAW ;                         //窗口样式
    14     wndclass.lpszClassName = szAppName ;                               //窗口类名
    15     wndclass.lpszMenuName = NULL ;                                     //窗口菜单:无
    16     wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH) ;    //窗口背景颜色
    17     wndclass.lpfnWndProc = WndProc ;                                   //窗口处理函数
    18     wndclass.cbWndExtra = 0 ;                                          //窗口实例扩展:无
    19     wndclass.cbClsExtra = 0 ;                                          //窗口类扩展:无
    20     wndclass.hInstance = hInstance ;                                   //窗口实例句柄
    21     wndclass.hIcon = LoadIcon( NULL, IDI_APPLICATION ) ;               //窗口最小化图标:使用缺省图标
    22     wndclass.hCursor = LoadCursor( NULL, IDC_ARROW ) ;                 //窗口采用箭头光标
    23 
    24     if( !RegisterClass( &wndclass ) )
    25     {    //注册窗口类, 如果注册失败弹出错误提示
    26         MessageBox( NULL, TEXT("窗口注册失败!"), TEXT("错误"), MB_OK | MB_ICONERROR ) ;
    27         return 0 ;
    28     }
    29 
    30     hwnd = CreateWindow(                   //创建窗口
    31                 szAppName,                 //窗口类名
    32                 TEXT("我的窗口"),           //窗口标题
    33                 WS_OVERLAPPEDWINDOW,       //窗口的风格
    34                 CW_USEDEFAULT,             //窗口初始显示位置x:使用缺省值
    35                 CW_USEDEFAULT,             //窗口初始显示位置y:使用缺省值
    36                 CW_USEDEFAULT,             //窗口的宽度:使用缺省值
    37                 CW_USEDEFAULT,             //窗口的高度:使用缺省值
    38                 NULL,                      //父窗口:无
    39                 NULL,                      //子菜单:无
    40                 hInstance,                 //该窗口应用程序的实例句柄 
    41                 NULL                       //
    42             ) ;
    43 
    44     ShowWindow( hwnd, iCmdShow ) ;        //显示窗口
    45     UpdateWindow( hwnd ) ;                //更新窗口
    46 
    47     while( GetMessage( &msg, NULL, 0, 0 ) )        //从消息队列中获取消息
    48     {
    49         TranslateMessage( &msg ) ;                 //将虚拟键消息转换为字符消息
    50         DispatchMessage( &msg ) ;                  //分发到回调函数(过程函数)
    51     }
    52     return msg.wParam ;
    53 }
    54 
    55 LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
    56 {
    57     HDC hdc ;                //设备环境句柄
    58     PAINTSTRUCT ps ;         //绘制结构
    59     RECT rect;               //矩形结构
    60 
    61     switch( message )        //处理得到的消息
    62     {
    63     case WM_CREATE:          //窗口创建完成时发来的消息
    64         MessageBox( hwnd, TEXT("窗口已创建完成!"), TEXT("我的窗口"), MB_OK | MB_ICONINFORMATION ) ;
    65         return 0;
    66 
    67     case WM_PAINT:           //处理窗口区域无效时发来的消息
    68         hdc = BeginPaint( hwnd, &ps ) ;
    69         GetClientRect( hwnd, &rect ) ;
    70         DrawText( hdc, TEXT( "Hello, 这是我自己的窗口!" ), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER ) ;
    71         EndPaint( hwnd, &ps ) ;
    72         return 0 ;
    73 
    74     case WM_LBUTTONDOWN:     //处理鼠标左键被按下的消息
    75         MessageBox( hwnd, TEXT("鼠标左键被按下。"), TEXT("单击"), MB_OK | MB_ICONINFORMATION ) ;
    76         return 0;
    77 
    78     case WM_DESTROY:         //处理窗口关闭时的消息
    79         MessageBox( hwnd, TEXT("关闭程序!"), TEXT("结束"), MB_OK | MB_ICONINFORMATION ) ;
    80         PostQuitMessage( 0 ) ;
    81         return 0;
    82     }
    83     return DefWindowProc( hwnd, message, wParam, lParam ) ;        //DefWindowProc处理我们自定义的消息处理函数没有处理到的消息
    84 }

    (1)窗口类对象wndclass的属性

    wndclass.style = CS_HREDRAW | CS_VREDRAW ;                         //窗口样式
    wndclass.lpszClassName = szAppName ;                               //窗口类名
    wndclass.lpszMenuName = NULL ;                                     //窗口菜单:无
    wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH) ;    //窗口背景颜色
    wndclass.lpfnWndProc = WndProc ;                                   //窗口消息处理函数
    wndclass.cbWndExtra = 0 ;                                          //窗口实例扩展:无
    wndclass.cbClsExtra = 0 ;                                          //窗口类扩展:无
    wndclass.hInstance = hInstance ;                                   //窗口实例句柄
    wndclass.hIcon = LoadIcon( NULL, IDI_APPLICATION ) ;               //窗口最小化图标:使用缺省图标
    wndclass.hCursor = LoadCursor( NULL, IDC_ARROW ) ;                 //窗口采用箭头光标
    

      

    1>. wndclass.style = CS_HREDRAW | CS_VREDRAW ; 
      style属性决定着窗口的风格, 可以通过C语言的或运算组合出不同风格类型的窗口, 在WINUSER.H头文件中定义着这些标识符以及其值, 所有的前缀为CS_的标识符如下:
     * Class styles
    #define CS_VREDRAW          0x0001
    #define CS_HREDRAW          0x0002
    #define CS_DBLCLKS          0x0008
    #define CS_OWNDC            0x0020
    #define CS_CLASSDC          0x0040
    #define CS_PARENTDC         0x0080
    #define CS_NOCLOSE          0x0200
    #define CS_SAVEBITS         0x0800
    #define CS_BYTEALIGNCLIENT  0x1000
    #define CS_BYTEALIGNWINDOW  0x2000
    #define CS_GLOBALCLASS      0x4000
    #define CS_IME              0x00010000
    2>. wndclass.lpszClassName = szAppName ;
      赋予窗口一个名称, 可以使用ASCII版本的字符串也可以使用Unicode版本的字符串, 需要注意的是, 这里的窗口名称并不是指窗口标题。
    3>. wndclass.lpszMenuName = NULL ; 
      指定窗口类的菜单, 由于我们这个窗口没有使用菜单, 所以为NULL,
    4>. wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH) ;
      窗口的背景颜色, 这里使用的是以白色作为填充, 填充白色这是常见的做法, 如果你愿意, 也可以填充为其他的一些样式, 这里是一些样式的标识符:
    #define WHITE_BRUSH         0
    #define LTGRAY_BRUSH        1
    #define GRAY_BRUSH          2
    #define DKGRAY_BRUSH        3
    #define BLACK_BRUSH         4
    #define NULL_BRUSH          5
    #define HOLLOW_BRUSH        NULL_BRUSH
    #define WHITE_PEN           6
    #define BLACK_PEN           7
    #define NULL_PEN            8
    #define OEM_FIXED_FONT      10
    #define ANSI_FIXED_FONT     11
    #define ANSI_VAR_FONT       12
    #define SYSTEM_FONT         13
    #define DEVICE_DEFAULT_FONT 14
    #define DEFAULT_PALETTE     15
    #define SYSTEM_FIXED_FONT   16
    5>. wndclass.lpfnWndProc = WndProc ; 
      将窗口的消息处理函数设置为我们自定义的WndProc函数。
    6>. wndclass.cbWndExtra = 0 ; 
    7>. wndclass.cbClsExtra = 0 ;
      这两个属性用来维护结构中预留的一些额外空间, 程序可以根据需要要使用这些额外空间, 通过匈牙利命名的cbClsExtra、cbWndExtra中的cb可以知道, 这些成员表示一个"字节数", 由于我们这个窗口没有使用到额外空间, 所以将这个两个属性赋值为0;
    8>. wndclass.hInstance = hInstance ;
      表示应用程序的实例句柄,  hInstance的来源是WinMain的一个参数;
    9>. wndclass.hIcon = LoadIcon( NULL, IDI_APPLICATION ) ;
      加载一个位图作为程序标题栏最左侧的小图标, 我们这里加载了一个系统的默认图标, 后面的学习这将会学习到如何从磁盘加载我们自定义的图标.
    10>. wndclass.hCursor = LoadCursor( NULL, IDC_ARROW ) ; 
      与LoadIcon类似, 加载鼠标的指针位图;
    

      

     (2)注册窗口
        if( !RegisterClass( &wndclass ) )
        {    //注册窗口类, 如果注册失败弹出错误提示
            MessageBox( NULL, TEXT("窗口注册失败!"), TEXT("错误"), MB_OK | MB_ICONERROR ) ;
            return 0 ;
        }
    

      

      (3)创建窗口
     
     hwnd = CreateWindow(                   //创建窗口
                    szAppName,                 //窗口类名
                    TEXT("我的窗口"),           //窗口标题
                    WS_OVERLAPPEDWINDOW,       //窗口的风格
                    CW_USEDEFAULT,             //窗口初始显示位置x:使用缺省值
                    CW_USEDEFAULT,             //窗口初始显示位置y:使用缺省值
                    CW_USEDEFAULT,             //窗口的宽度:使用缺省值
                    CW_USEDEFAULT,             //窗口的高度:使用缺省值
                    NULL,                      //父窗口:无
                    NULL,                      //子菜单:无
                    hInstance,                 //该窗口应用程序的实例句柄 
                    NULL                       //
                ) ;
    

      

    1>.参数一: LPCTSTR  lpClassName
      参数LPCTSTR lpClassName,为窗口的名称, 我们需要传入的参数就是刚才我们在窗口类注册的窗口类名称, 这样使用CreateWindow建立的窗口就能与注册的窗口进行关联。 
    2>. 参数三: DWORD dwStyle
      参数三为窗口的样式, 示例中创建的是一个普通的层叠窗口样式, WS_OVERLAPPEDWINDOW, 打开WINUSER.H头文件, 对于WS_OVERLAPPEDWINDOW是这样定义的:
    #define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED     | 
                                 WS_CAPTION        | 
                                 WS_SYSMENU        | 
                                 WS_THICKFRAME     | 
                                 WS_MINIMIZEBOX    | 
                                 WS_MAXIMIZEBOX)
    
    可以看出, WS_OVERLAPPEDWINDOW样式实际上是通过一些标识符通过或的组合, 此外我们还可以通过组合设计我们自己的样式, 这些标识符在WINUSER.H的定义如下:
    #define WS_OVERLAPPED       0x00000000L            //产生一个层叠的窗口。一个层叠的窗口有一个标题条和一个边框。与WS_TILED风格相同。
    #define WS_POPUP            0x80000000L            //创建一个弹出式窗口。该风格不能与WS_CHLD风格同时使用。
    #define WS_CHILD            0x40000000L            //创建一个子窗口。这个风格不能与WS_POPUP风格合用。
    #define WS_MINIMIZE         0x20000000L            //创建一个初始状态为最小化的窗口。仅与WS_OVERLAPPED风格一起使用。
    #define WS_VISIBLE          0x10000000L            //创建一个最初可见的窗口。
    #define WS_DISABLED         0x08000000L            //创建一个初始状态为禁止的窗口。
    #define WS_CLIPSIBLINGS     0x04000000L            //排除子窗口之间的相对区域。
    #define WS_CLIPCHILDREN     0x02000000L            //创建一个初始状态为禁止的子窗口。一个禁止状态的窗口不能接受来自用户的输入信息。
    #define WS_MAXIMIZE         0x01000000L            //创建一个初始状态为最大化状态的窗口。 
    #define WS_CAPTION          0x00C00000L            //创建一个有标题框的窗口(包括WS_BODER风格)。
    #define WS_BORDER           0x00800000L            //创建一个单边框的窗口。 
    #define WS_DLGFRAME         0x00400000L            //创建一个带对话框边框风格的窗口。这种风格的窗口不能带标题条。
    #define WS_VSCROLL          0x00200000L            //创建一个有垂直滚动条的窗口。 
    #define WS_HSCROLL          0x00100000L            //创建一个有水平滚动条的窗口。 
    #define WS_SYSMENU          0x00080000L            //创建一个在标题条上带有窗口菜单的窗口,必须同时设定WS_CAPTION风格。
    #define WS_THICKFRAME       0x00040000L            //创建一个具有可调边框的窗口,与WS_SIZEBOX风格相同。
    #define WS_GROUP            0x00020000L            //指定一组控制的第一个控制。
    #define WS_TABSTOP          0x00010000L            //创建一个控制,这个控制在用户按下Tab键时可以获得键盘焦点。按下Tab键后使键盘焦点转移到下一具有WS_TABSTOP风格的控制。
    #define WS_MINIMIZEBOX      0x00020000L            //创建一个具有最小化按钮的窗口。
    #define WS_MAXIMIZEBOX      0x00010000L            //创建一个具有最大化按钮的窗口。
    #define WS_TILED            WS_OVERLAPPED          //产生一个层叠的窗口。一个层叠的窗口有一个标题和一个边框。与WS_OVERLAPPED风格相同。
    #define WS_ICONIC           WS_MINIMIZE            //创建一个初始状态为最小化的窗口。仅与WS_OVERLAPPED风格一起使用。
    #define WS_SIZEBOX          WS_THICKFRAME          //创建一个具有厚边框的窗口,可以通过厚边框来改变窗口大小。
    #define WS_TILEDWINDOW      WS_OVERLAPPEDWINDOW    //创建一个具有WS_OVERLAPPED,WS_CAPTION,WS_SYSMENU,WS_THICKFRAME,WS_MINIMIZEBOX和WS_MAXIMIZEBOX风格的重叠式窗口。
    

      (4)窗口的显示、更新

        ShowWindow( hwnd, iCmdShow ) ;        //显示窗口
        UpdateWindow( hwnd ) ;                //更新窗口
    

      

    ShowWindow函数的原型如下:
    BOOL ShowWindow( HWND hWnd, int iCmdShow );
    参数一为刚才通过CreateWindow函数窗口出的窗口句柄, 参数二为窗口的显示方式, 由WinMain函数的int iCmdShow接收该值, 常用的显示方式有:
    SW_HIDE                        //隐藏窗口并激活其他窗口;
    SW_MAXIMIZE                    //最大化;
    SW_MINIMIZE                    //最小化指定的窗口并且激活在Z序中的下一个顶层窗口;
    SW_RESTORE                     //激活并显示窗口。如果窗口最小化或最大化,则系统将窗口恢复到原来的尺寸和位置;
    SW_SHOW                        //在窗口原来的位置以原来的尺寸激活和显示窗口;
    SW_SHOWMAXIMIZED               //激活窗口并将其最大化;
    SW_SHOWMINIMIZED               //激活窗口并将其最小化;
    SW_SHOWMINNOACTIVE             //窗口最小化,激活窗口仍然维持激活状态;
    SW_SHOWNA                      //以窗口原来的状态显示窗口。激活窗口仍然维持激活状态;
    SW_SHOWNOACTIVATE              //以窗口最近一次的大小和状态显示窗口。激活窗口仍然维持激活状态;  
    SW_SHOWNORMAL                  //激活并显示一个窗口。如果窗口被最小化或最大化,系统将其恢复到原来的尺寸和大小;
    UpdateWindow函数的原型如下: BOOL UpdateWindow( HWND hWnd ); 该函数只有一个参数, 参数为需要更新的窗口句柄; 函数调用成功返回值为非0, 调用失败时返回值为0。

      (5)消息的转换、分发

     while( GetMessage( &msg, NULL, 0, 0 ) )        //从消息队列中获取消息
        {
            TranslateMessage( &msg ) ;                 //将虚拟键消息转换为字符消息
            DispatchMessage( &msg ) ;                  //分发到回调函数(过程函数)
        }
        return msg.wParam ;
    }
    

      (6)消息处理函数

    LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
    {
        HDC hdc ;                //设备环境句柄
        PAINTSTRUCT ps ;         //绘制结构
        RECT rect;               //矩形结构
    
        switch( message )        //处理得到的消息
        {
        case WM_CREATE:          //窗口创建完成时发来的消息
            MessageBox( hwnd, TEXT("窗口已创建完成!"), TEXT("我的窗口"), MB_OK | MB_ICONINFORMATION ) ;
            return 0;
    
        case WM_PAINT:           //处理窗口区域无效时发来的消息
            hdc = BeginPaint( hwnd, &ps ) ;
            GetClientRect( hwnd, &rect ) ;
            DrawText( hdc, TEXT( "Hello, 这是我自己的窗口!" ), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER ) ;
            EndPaint( hwnd, &ps ) ;
            return 0 ;
    
        case WM_LBUTTONDOWN:     //处理鼠标左键被按下的消息
            MessageBox( hwnd, TEXT("鼠标左键被按下。"), TEXT("单击"), MB_OK | MB_ICONINFORMATION ) ;
            return 0;
    
        case WM_DESTROY:         //处理窗口关闭时的消息
            MessageBox( hwnd, TEXT("关闭程序!"), TEXT("结束"), MB_OK | MB_ICONINFORMATION ) ;
            PostQuitMessage( 0 ) ;
            return 0;
        }
        return DefWindowProc( hwnd, message, wParam, lParam ) ;        //DefWindowProc处理我们自定义的消息处理函数没有处理到的消息
    }
    

      

     
  • 相关阅读:
    委托和事件
    解决kalilinux:“下列签名无效: KEYEXPIRED 1425567400"
    【c# 学习笔记】委托的使用
    【c# 学习笔记】c#委托是什么
    【c# 学习笔记】面向对象编程的应用
    【c# 学习笔记】接口与抽象类
    【C# 开发技巧】番外篇故事-我是一个线程
    【物联网硬件安全】二、固件分析-固件逆向
    【物联网硬件安全】二、固件分析-固件提取
    【物联网硬件安全】一、硬件分析-电路分析
  • 原文地址:https://www.cnblogs.com/yanjunfeng/p/7482139.html
Copyright © 2020-2023  润新知