windows 应用程序窗口的创建

很多人都认为windows 程序设计很难,会有一种闻声丧胆的感觉,我个人认为那只不过是一种错觉,那是因为你没有深入的去了解windows 程序设计,只要你坚持了,深入了解了,你将发现windows 程序设计是很有意思的,也不是许多人所说的那般神秘,你会慢慢喜欢上她。


 
    要创建一个windows 应用程序并不是那么困难,一般步骤如下:

一、创建一个windows 窗口类,并初始化要创建窗口的一些信息
    设置要创建窗口的属性,定义在WNDCLASSEX结构中
    typedef struct_WNDCLASSEX
    {
            UNIT cbSize;                            //WNDCLASSEX  结构的大小
            UNIT style;                              //从这个窗口派生的窗口具有的风格
            WNDPROC lpfnWndProc;            //即 window procedure,窗口消息处理函数指针
            int cbClsExtra;                      //指定紧跟在窗口类结构后的附加字节数
            int cbWndExtra;                      //指定紧跟在窗口事例后的附加字节数
            HANDLE hInstance;                  //本模块的实例句柄
            HICON hIcon;                            //窗口左上角的句柄
            HCURSOR  hCursor;                  //光标的句柄
            HBRUSH hbrBackground;          //背景画刷的句柄
            LPCTSTR lpszMenuName;          //菜单名
            LPCTSTR lpszClassName;        //该窗口类的名称
            HICON hIconSm;                        //小图标句柄
      }WNDCLASSEX;
这一步就是根据所要创建的窗口,设置WNDCLASSEX 结构
    事例如下:
      WNDCLASSEX MyWindow;
      MyWindow.cbSize                        =          sizeof(MyWindow);                      //结构的大小
      MyWindow.style                          =        CS_HREDRAW|CS_VREDRAW;          //指定如果窗口大小改变就重画
    MyWindow.lpfnWndProc         =       MainWndProc;                 //窗口函数指针
    MyWindow.cbClsExtra         =       0;                           //没有额外的类内存
    MyWindow.cbWndExtra         =       0;                           //没有额外的窗口内存
    MyWindow.hInstance           =       hInstance;                   //实例句柄
    MyWindow.hIcon               =       ::LoadIcon(NULL,IDI_APPLICATION);  //使用预定义的图标
    MyWindow.hCursor             =       ::LoadCursor(NULL,IDC_ARROW);       //使用预定义的光标
    MyWindow.hbrBackground       =       (HBRUSH)::GetStockObject(WHITE_BRUSH); //使用白色背景画刷
    MyWindow.lpszMenuName       =       NULL;                         //不指定菜单
      MyWindow.lpszClassName       =       szClassName;                 //窗口类的名称
    MyWindow.hIconSm             =       NULL;                         //没有类的小图标
       
    其中有一个窗口函数指针,在程序前应该先声明该窗口的消息处理函数
LRESULT CALLBACK MainWndProc(HWND,UINT,WPARAM,LPARAM);
当然在程序中,还要实现消息处理函数,使其能够处理相应的消息

二、设置好要创建的窗口的属性后,就可以注册要创建的窗口了
    注册窗口类用API 函数RegisterClassEx, 如果函数成功,返回值是唯一识别被注册类的一个原子;如果函数失败,返回值为0。
  函数原型:ATON RegisterClassEX(CONST WNDCLASSEX * Ipwcx);

    注册上面设置的窗口如下:
        ::RegisterClassEx(&MyWindow);

三、注册窗口后,接下来就是创建注册的窗口
    创建窗口用API 函数CreateWindowEx,创建窗口成功的话,该函数返回创建窗口的句柄,否则返回false
      函数原型:
                        HWND CreateWindowEx(
                                          DWORD      dwExStle,            //指定窗口的扩展风格
                                          LPCTSTR  IpClassName,      //指向一个空结束的字符串或整型数atom
                                          LPCTSTR  lpWindowName,    //指向一个指定窗口名的空结束的字符串指针
                                          DWORD      dwStyle,              //指定创建窗口的风格
                                          int          x,                          //初始化X坐标
                                          int          y,                            //初始化Y坐标
                                          int          nWidth,                //初始化窗口宽度
                                          int          nHeight,              //初始化窗口高度
                                          HWND        hWndParent,        //指定父窗口句柄,没有的话,为NULL
                                          HMENU      hMenu,                  //菜单句柄,或依据窗口风格指明一个子窗口标识
                                          HANDLE    hlnstance,          //与窗口相关联的模块事例的句柄
                                          LPVOID    lpParam                  //指向一个值的指针,该值传递给窗口 WM_CREATE消息
                                                                    );

    创建上面注册的窗口类如下:
              HWND m_hWnd  =  ::CreateWindowEx(
                        0,
                        szClassName,
                        "My first Window",
                        WS_OVERLAPPEDWINDOW,
                        200,
                        100,
                        600,
                        450,
                        NULL,
                        NULL,
                        hInstance,
                        NULL);

四、创建窗口成功的话,创建的窗口还没有显示出来,这些需要调用ShowWindow函数把窗口显示出来并更新窗口
      函数原型:BOOL ShowWindow(HWND hWnd,int nCmdShow);
      函数原型:BOOL UpdateWindow(HWND hWnd);
     
      显示上面创建的窗口:
        ::ShowWindow(m_hWnd,nCmdShow);
      接下来则是更新窗口
        ::UpdateWindow(m_hWnd);

至此,一个简单的window 应用程序窗口已经呈现在你的面前了

五、接下来就是让窗口可对不同的消息才去不同的操作

      达到这个目的,即让窗口进入无限的消息循环:

          MSG msg;
          while(::GetMessage(&msg,nCmdShow))
          {
                  //转化键盘消息
                  ::TranslateMessage(&msg);
                  //将消息发送相应的窗口函数
                  ::DispatchMessage(&msg);
          }

Windows 为每个线程维护了一个消息队列,每当有一个输入发生,Windows 就把用户的输入翻译成消息放在消息队列中。利用GetMessage函数可以从调用线程的消息队列中取出一个消息来填充MSG结构。

  ::GetMessae(&msg,NULL,0,0);
如果消息队列中没有消息(既没有用户输入),这个函数会一直等待下去,直到有消息进入消息队列为止。如果从消息队列中取得消息不是WM_QUIT,则返回 非零值,一个WM_QUIT消息会促使GetMessage函数返回0,从而结束消息循环。

msg是MSG结构类型的一个变量,这个结构定义了消息的所有属性。
          typedef struct tagMSG
          {
                  HWND        hwnd;                      //消息要发送的窗口句柄
                  UINT        message;                //消息标示符,一WM_开头的预定义值(意为window  message)
                  WPARAM    wParam;                  //消息的参数之一
                  LPARAM    lParam;                  //消息的参数之二
                  DWORD      time;              //消息放入消息队列的时间            
                  POINT      pt;                          //这是一个POINT结构,表示消息放入消息队列是的鼠标位置
            }MSG,*PMSG;





windows 应用程序简单窗口的创建实现代码

#include "stdafx.h"

// 窗口函数的消息处理函数原形声明
LRESULT  CALLBACK MainWProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
             int       nCmdShow)
{
    char szClassName[] = "MainWClass";   
    WNDCLASSEX wndclass;
   
    // 用描述主窗口的参数填充WNDCLASSEX结构
    wndclass.cbSize = sizeof(wndclass);                          // 结构的大小
    wndclass.style = CS_HREDRAW|CS_VREDRAW;                      // 指定如果大小改变就重画
    wndclass.lpfnWndProc = MainWProc;                            // 窗口函数指针
    wndclass.cbClsExtra = 0;                                     // 没有额外的类内存
    wndclass.cbWndExtra = 0;                                     // 没有额外的窗口内存
    wndclass.hInstance = hInstance;                              // 实例句柄
    wndclass.hIcon = ::LoadIcon(NULL,IDI_APPLICATION);           // 使用预定义图标
    wndclass.hCursor = ::LoadCursor(NULL,(LPSTR)IDC_ARROW);      // 使用预定义的光标
    wndclass.hbrBackground = (HBRUSH)
        ::GetStockObject(WHITE_BRUSH);                           // 使用白色背景画刷
    wndclass.lpszMenuName = NULL;                                // 不指定菜单
    wndclass.lpszClassName = szClassName ;                       // 窗口类的名称   
    wndclass.hIconSm = NULL;                                     // 没有类的小图标
   
    // 注册这个窗口类
    ::RegisterClassEx(&wndclass);
       
    // 创建主窗口
    HWND hwnd = ::CreateWindowEx(
        0,                      // dwExStyle,扩展样式   
        szClassName,            // lpClassName,类名           
        "贴心小闹钟",           // lpWindowName,标题       
        WS_OVERLAPPEDWINDOW,    // dwStyle,窗口风格   
        200,                    // X,初始 X 坐标       
        100,                    // Y,初始 Y 坐标       
        600,                    // nWidth,宽度           
        450,                    // nHeight,高度           
        NULL,                   // hWndParent,父窗口句柄           
        NULL,                   // hMenu,菜单句柄       
        hInstance,              // hlnstance,程序实例句柄       
        NULL) ;                 // lpParam,用户数据           

    if(hwnd == NULL)
    {
        ::MessageBox(NULL, "创建窗口出错!", "error", MB_OK);
        return -1;
    }

    // 显示窗口,刷新窗口客户区
    ::ShowWindow(hwnd, nCmdShow);
    ::UpdateWindow(hwnd);
   
    // 从消息堆中取出消息
    MSG msg;   
    while(::GetMessage(&msg, NULL, 0, 0))
    {
        // 转化键盘消息
        ::TranslateMessage(&msg);
        // 将消息发送到相应的窗口函数
        ::DispatchMessage(&msg);
    }

    // 当GetMessage返回0时程序结束
    return msg.wParam;
}


LRESULT CALLBACK MainWProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    char szText[] = "贴心小闹钟";
    switch (message)
    {        
    case WM_PAINT: // 窗口客户区需要重画
        {
            HDC hdc;
            PAINTSTRUCT ps;

            // 使无效的客户区变的有效,并取得设备环境句柄
            hdc = ::BeginPaint (hwnd, &ps) ;   
            // 显示文字
            ::TextOut(hdc, 250, 10, szText, strlen(szText));
            ::EndPaint(hwnd, &ps);
            return 0;
        }   
    case WM_DESTROY: // 正在销毁窗口

        // 向消息队列投递一个WM_QUIT消息,促使GetMessage函数返回0,结束消息循环
        ::PostQuitMessage(0) ;
        return 0 ;
    }

    // 将我们不处理的消息交给系统做默认处理
    return ::DefWindowProc(hwnd, message, wParam, lParam);
}

你可能感兴趣的:(windows,窗口,职场,应用程序,休闲)