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 程序开发:创建一个应用程序窗口


  • 相关阅读:
    Android 按键消息处理Android 按键消息处理
    objcopy
    SQLite多线程读写实践及常见问题总结
    android动画坐标定义
    Android动画效果translate、scale、alpha、rotate
    Android公共库(缓存 下拉ListView 下载管理Pro 静默安装 root运行 Java公共类)
    Flatten Binary Tree to Linked List
    Distinct Subsequences
    Populating Next Right Pointers in Each Node II
    Populating Next Right Pointers in Each Node
  • 原文地址:https://www.cnblogs.com/linuxAndMcu/p/12075434.html
Copyright © 2011-2022 走看看