zoukankan      html  css  js  c++  java
  • Win32 程序开发:创建一个应用程序窗口

    一、创建一个应用程序窗口

    代码如下:

    // 头文件
    #include <windows.h>
     
    // 全局变量
    WCHAR g_lpszClassName[] = L"CLASSNAME";
    WCHAR g_lpszWindowName[] = L"哈喽,新的征程";
     
    // 函数声明
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
     
    // 应用程序主函数
    INT APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, INT nCmdShow)
    {
        // 1.设计一个窗口类
        WNDCLASSEX wcex;
        wcex.cbSize = sizeof(WNDCLASSEX);
        wcex.style = CS_HREDRAW | CS_VREDRAW;        
        wcex.cbClsExtra = 0;    
        wcex.cbWndExtra = 0;
        wcex.hInstance = hInstance;
        wcex.lpfnWndProc = WndProc;
        wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        wcex.lpszMenuName = NULL;
        wcex.lpszClassName = g_lpszClassName;
        wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
     
        // 2.注册这个窗口类
        if (RegisterClassEx(&wcex) == ((ATOM)0))
        {
            MessageBox(NULL, L"注册窗口类失败!", L"错误", MB_YESNO | MB_ICONERROR);
            exit(-1);
        }
     
        // 3.创建窗口
        HWND hWnd = CreateWindowEx(NULL, g_lpszClassName, g_lpszWindowName, WS_OVERLAPPEDWINDOW, 10, 10, 800, 800, NULL, NULL, hInstance, NULL);
        if (hWnd == NULL)
        {
            MessageBox(NULL, L"创建窗口失败!", L"错误", MB_YESNO | MB_ICONERROR);
            exit(-1);
        }
     
        // 4.更新和显示窗口
        ShowWindow(hWnd, nCmdShow);
        UpdateWindow(hWnd);
     
        // 5.应用程序消息循环
        MSG msg = { 0 };
        BOOL bRet;
        // 调用 GetMessage 函数从调用线程的消息队列中取得一个消息
        while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
        {
            if (bRet != -1)
            {
                TranslateMessage(&msg); // 将虚拟键消息转换为字符消息
                DispatchMessage(&msg); // 将消息分发到窗口处理
            }
        }
     
        return msg.wParam;
    }
     
    // 应用程序消息处理回调函数
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {
        case WM_DESTROY:
            PostQuitMessage(0); // 程序退出
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam); // 默认的窗口处理程序
        }
        return 0;
    }
    

    二、程序分析

    1.首先设计一个窗口类。

    不懂可以看我的这篇文章:Win32 程序开发:窗口类结构体 WNDCLASS 和 WNDCLASSEX ,此处就不多赘述了。


    2.注册先前设计的窗口类。

    调用 RegisterClassEx 函数注册窗口。函数原型:

    // 返回值(ATOM,原子):成功返回注册的原子,失败返回 0。
    ATOM WINAPI RegisterClassExW(_In_ CONST WNDCLASSEXW *); // 参数:为我们设计的窗口类
    

    3.创建窗口。

    调用 CreateWindowEx 函数创建窗口。函数原型:

    // 返回值:创建成功返回创建的窗口句柄,失败返回NULL
    HWND WINAPI CreateWindowExW(
        _In_ DWORD dwExStyle, // 窗口扩展风格
        _In_opt_ LPCWSTR lpClassName, // 我们注册的窗口类的名称
        _In_opt_ LPCWSTR lpWindowName, // 窗口的名称(说白了就是窗口的标题)
        _In_ DWORD dwStyle, // 窗口创建的风格(跟dwExStyle不同)
        _In_ int X, // 窗口左上角的点位于屏幕的横坐标
        _In_ int Y, // 窗口左上角的点位于屏幕的纵坐标
        _In_ int nWidth, // 窗口的宽度
        _In_ int nHeight, // 窗口的高度
        _In_opt_ HWND hWndParent, // 窗口所有者的句柄
        _In_opt_ HMENU hMenu, // 菜单句柄
        _In_opt_ HINSTANCE hInstance, // 所在模块的实例句柄
        _In_opt_ LPVOID lpParam); // 在WM_CREATE中进行传递的参数
    

    4.更新和显示窗口。

    调用 ShowWindow 函数显示窗口。函数原型:

    // 返回值:成功返回非0,失败返回0
    BOOL WINAPI ShowWindow(
        _In_ HWND hWnd, // 显示的窗口句柄
        _In_ int nCmdShow); // 窗口显示的方式(全屏,最大化窗口,最小化窗口,······)
    

    调用 UpdateWindow 函数更新窗口。函数原型:

    // 返回值:成功返回非0,失败返回0
    BOOL WINAPI UpdateWindow(
        _In_ HWND hWnd); // 更新的窗口
    

    5.应用程序消息循环。

    调用 GetMessage 函数从调用线程的消息队列中取得一个消息。函数原型:

    // 返回值:获取错误返回-1,消息为WM_QUIT返回0,其他为非0
    BOOL WINAPI GetMessageW(
        _Out_ LPMSG lpMsg, // 接收从消息队列中获取的消息
        _In_opt_ HWND hWnd, // 接收消息的窗口句柄
        _In_ UINT wMsgFilterMin, // 指定被检测的最小消息值
        _In_ UINT wMsgFilterMax); // 指定被检测的最大消息值
    

    调用 TranslateMessage 函数将虚拟键消息转换为字符消息。函数原型:

    // 返回值:成功返回非0,失败返回0
    BOOL WINAPI TranslateMessage(
        _In_ CONST MSG *lpMsg); // 接收的消息
    

    调用 DispatchMessage 函数将消息分发到窗口处理。函数原型:

    // 返回值:窗口处理过程的返回值
    LRESULT WINAPI DispatchMessageW(
        _In_ CONST MSG *lpMsg); // 分发的消息
    

    示例中的使用:

    while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
    {
        if (bRet != -1)
    	{
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    

    while 循环的结束,当 GetMessage 获取到的消息为 WM_QUIT 窗口退出,则返回 0(false) 当 GetMessage 的返回值不为 -1(获取消息失败)的时候,进行虚拟键转换和分发消息。


    6.窗口消息处理过程。

    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {
        case WM_DESTROY:
            PostQuitMessage(0); // 程序退出
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam); // 默认的窗口处理程序
        }
     
        return 0;
    }
    

    参数:

    • hWnd:窗口处理过程的窗口句柄

    • message:消息ID

    • wParam:附加消息

    • lParam:附加消息


    参考:

    Win32 程序开发:创建一个应用程序窗口


  • 相关阅读:
    Python列表及元组操作
    Python内建函数
    Python字符串相关
    检测浏览器是否安装FLASH插件
    瀑布流源码
    addEventListener 简析
    半角占一个字符,全角占两个字符
    替换class名
    正则表达式 验证是否全是空格
    图片旋转
  • 原文地址:https://www.cnblogs.com/linuxAndMcu/p/12075434.html
Copyright © 2011-2022 走看看