zoukankan      html  css  js  c++  java
  • 4.注册窗口类和创建窗口

    1.注册窗口类函数

      (1)RegisterClass/RegisterClassEx

        ATOM RegisterClass(CONST WNDCLASS *lpWndClass);

        ATOM RegisterClassEx(CONST WNDCLASSEX *lpwcx);

        注册成功后,返回一个非0数字标识,失败返回0。

      (2)窗口类的风格

        CS_GLOBALCLASS - 应用程序全局窗口类

        CS_BYTEALIGNCLIENT - 窗口客户区的水平位置8整倍数据对齐

        CS_BYTEALIGNWINDOW - 窗口的水平位置8整倍数据对齐

        CS_HREDRAW - 当窗口水平变化时,窗口重新绘制

        CS_VREDRAW - 当窗口垂直变化时,窗口重新绘制

        CS_CLASSDC - 该类型的窗口,都是有同一个绘图(DC)设备

        CS_PARENTDC - 该类型的窗口,使用它的父窗口的绘图(DC)设备

        CS_OWNDC - 该类型的窗口,每个窗口都是用自己的绘图(DC)设备

        CS_SAVEBITS - 允许窗口保存成图(位图),提高窗口的绘图效率,但是耗费内存资源

        CS_DBLCLKS - 允许窗口接收鼠标双击

        CS_NOCLOSE - 窗口没有关闭按钮

    下面是简单的示例代码:

    #include "stdafx.h"
    
    
    HINSTANCE g_hInstance = 0;
    
    void AppReg()
    {
        //注册窗口类
        WNDCLASSEX wce = { 0 };
    
        wce.cbSize        = sizeof(wce);               //大小
        wce.cbClsExtra    = 0;                         //窗口类附加数据buffer的大小
        wce.cbWndExtra    = 0;                         //窗口的附加数据buffer的大小
        wce.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);  //背景为白色
        wce.hCursor       = NULL;                      //默认光标
        wce.hIcon         = NULL;                      //默认大图标
        wce.hIconSm       = NULL;                      //默认小图标
        wce.hInstance     = g_hInstance;               //当前程序实例句柄
        wce.lpfnWndProc   = DefWindowProc;             //系统默认窗口处理函数
        wce.lpszClassName = "Main";                    //窗口类名
        wce.lpszMenuName  = NULL;                      //窗口菜单
        wce.style         = CS_HREDRAW | CS_VREDRAW;   //窗口风格
    
        //将以上赋值写入操作系统
        ATOM nAtom = RegisterClassEx(&wce);
    
        if (nAtom == 0)
        {
            MessageBox(NULL, "注册失败", "Info", MB_OK);
            return;
        }
    
        HWND hWnd = CreateWindow("Main", "Window", WS_OVERLAPPEDWINDOW,
                                 100, 100, 500, 500, NULL, NULL, g_hInstance, NULL);
        ShowWindow(hWnd, SW_SHOW);
        UpdateWindow(hWnd);
    
        MSG uMsg = { 0 };
        while (GetMessage(&uMsg, NULL, 0, 0))
        {
            TranslateMessage(&uMsg);
            DispatchMessage(&uMsg);
        }
    }
    
    
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       cCmdShow)
    {
        g_hInstance = hInstance;
        AppReg();
        return 0;
    }
    View Code

    2.创建窗口

      (1)创建窗口函数CreateWindow/CreateWindowEx

        CreateWindowEx(

          DWORD      dwExStyle,          //窗口的扩展风格,CreateWindow没有这个参数

          LPCTSTR     lpClassName,      //窗口类名

          LPCTSTR     lpWindowName,  //窗口标题栏名

          DWORD      dwStyle,             //窗口基本风格

          int               x,                     //窗口左上角横坐标

          int               y,                      //窗口左上角纵坐标

          int               nWidth,             //窗口宽度

          int               nHeight,            //窗口高度

          HWND          hWndParent,     //窗口的父窗口句柄

          HMENU         hMenu,             //窗口菜单句柄

          HINSTANCE   hInstance,        //应用程序实例句柄

          LPVOID         lpParam           //窗口创建时附加参数

        );创建成功返回窗口句柄

      (2)子窗口的创建

        创建子窗口时要设置父窗口句柄和WS_CHILD | WS_VISIBLE风格。

      (3)内部执行过程

        CreateWindow用其中两个参数用来确定窗口,CreateWindow("Main", ..., g_hInstance, ...),即窗口类名和当前程序实例句柄。  

        a.系统根据传入的窗口类名称,在应用程序局部窗口类中查找,如果找到执行b,否则执行c。

        b.比较局部窗口类与创建窗口时传入的HINSTANCE变量。如果发现相等,创建和注册的窗口在同一模块,创建窗口返回。否则执行c。

        c.在应用程序全局窗口类中查找,如果找到,执行d,否则执行e。

        d.使用找到的窗口类的信息,创建窗口返回。

        e.在系统窗口类中查找,如果找到,创建窗口,否则窗口创建失败。

        若创建窗口成功,那么CreateWindow就申请内存,将传入的参数写入到内存中,返回这块内存的句柄。

      下面我们看一个比较完整的例子:

      创建了两个子窗口,并解决前面的遗留问题(关闭窗口后,进程并没有退出)

      相关代码: 

    #include "stdafx.h"
    
    HINSTANCE g_hInstance = 0;  //接收当前程序实例句柄
    
    //窗口处理函数
    //CALLBACK即回调,我们定义函数我们不调用,操作系统调用,仅限windows系统
    LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        switch (msg)
        {
        case WM_DESTROY:
            PostQuitMessage(0);  //能够使GetMessage返回0
            break;
        }
        return DefWindowProc(hWnd, msg, wParam, lParam);
    }
    //注册窗口类
    BOOL Register(LPSTR lpClassName, WNDPROC wndProc)
    {
        WNDCLASSEX wce = { 0 };
    
        wce.cbSize        = sizeof(wce);
        wce.cbClsExtra    = 0;
        wce.cbClsExtra    = 0;
        wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        wce.hCursor       = NULL;
        wce.hIcon         = NULL;
        wce.hIconSm       = NULL;
        wce.hInstance     = g_hInstance;
        wce.lpfnWndProc   = wndProc;
        wce.lpszClassName = lpClassName;
        wce.lpszMenuName  = NULL;
        wce.style         = CS_HREDRAW | CS_VREDRAW;
       
        ATOM nAtom = RegisterClassEx(&wce);
        if (0 == nAtom)
        {
            return FALSE;
        }
        return TRUE;
    }
    //创建主窗口
    HWND CreateMainWindow(LPSTR lpClassName, LPSTR lpWndName)
    {
        HWND hWnd = CreateWindowEx(0, lpClassName, lpWndName, WS_OVERLAPPEDWINDOW, 
                                   CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                                   NULL, NULL, g_hInstance, NULL);
        return hWnd;
    }
    //创建子窗口
    HWND CreateChildWindow(LPSTR lpClassName, LPSTR lpWndName, HWND hParent)
    {
        HWND hChild = CreateWindowEx(0, lpClassName, lpWndName, WS_CHILD | WS_VISIBLE | WS_OVERLAPPEDWINDOW,
                                     100, 100, 200, 200, hParent, NULL, g_hInstance, NULL);
        return hChild;
    }
    //显示窗口
    void Display(HWND hWnd)
    {
        ShowWindow(hWnd, SW_SHOW);
        UpdateWindow(hWnd);
    }
    //消息循环
    void Message()
    {
        MSG nMsg = { 0 };
        while (GetMessage(&nMsg, NULL, 0, 0))
        {
            TranslateMessage(&nMsg);
            DispatchMessage(&nMsg);
        }
    }
    //APIENTRY也是回调函数,APIENTRY和CALLBACK一样,都是__stdcall的别名
    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
    {
        g_hInstance = hInstance;
        BOOL nBool = Register("Main", WndProc);
        if (nBool == FALSE)
        {
            MessageBox(NULL, "注册失败", "Info", MB_OK);
        }
        HWND hWnd = CreateMainWindow("Main", "window");    
        Display(hWnd);
    
        BOOL nChild = Register("Child", DefWindowProc);
        if (nChild == FALSE)
        {
            MessageBox(NULL, "注册失败", "Info", MB_OK);
        }
        HWND hChild1 = CreateChildWindow("Child", "c1", hWnd);
        HWND hChild2 = CreateChildWindow("Child", "c2", hWnd);
        MoveWindow(hChild1, 300, 100, 200, 200, TRUE);
        MoveWindow(hChild2, 500, 100, 200, 200, TRUE);
        Display(hChild1);
        Display(hChild2);
    
        Message();
    
        return 0;
    }
    View Code

      运行结果为:

      

  • 相关阅读:
    PostgreSQL 安装和使用
    动态sql
    知识储备
    java空和非空判断
    我的第一篇博客
    正式工作:PreparedStatement 参与的
    mysql part2DML(数据操作语言)
    DCL(权限 ,用户)
    DQL(数据查询语言)
    准备工作:Eclipse 导入 mysql连接java 的jar包
  • 原文地址:https://www.cnblogs.com/csqtech/p/5573809.html
Copyright © 2011-2022 走看看