c++ - Wndproc 处理事件代码少

标签 c++ windows c++11

我想知道是否有一种方法可以缩短这段代码,是否有办法制作一个 #define 来缩短我在消息开关中执行 if 语句的方式。 我检查我是否已经设置了一个函数,如果有我就调用它 这只是我的 wndproc 的一部分,它要大得多

LRESULT Base::WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
    {
        switch (uMsg)
        {
        case WM_CREATE:
        {
            if (this->onCreate != NULL)
            {
                if (onCreate(hwnd, (LPCREATESTRUCT)lParam))
                    return 1;
            }
        }break;

        case WM_DESTROY:
        {
            if (onDestroy != NULL)
            {
                if (onDestroy(hwnd))
                    return 1;
            }
            this->Destroy();
        }break;

        case WM_SIZE:
        {
            if (onSize != NULL)
            {
                if (onSize(hwnd, wParam, lParam))
                    return 1;
            }
        }break;

        case WM_CLOSE:
        {
            if (onClose != NULL)
            {
                if (onClose(hwnd))
                    return 1;
            }
        }break;

        default:
        {

        }break;

        }

        return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
    }

这样定义的指针

LRESULT(*onCreate) (HWND, LPCREATESTRUCT);

然后我像这样添加它们

LRESULT onCreate(HWND, LPCREATESTRUCT)
{

    return true;
}

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR pCmdLine, int nCmdShow)
{
    Window mainWindow;
    mainWindow.onCreate = onCreate;

    return 0;
}

最佳答案

使用 <WindowsX.h> 中定义的 message-cracker macros 。这实际上不会使代码运行得更快,也不会真正导致代码行的净损失,但它肯定会使代码更易于阅读,这是重要的部分.没有人愿意查看 1000 行的 switch 语句。此外,这些宏从 WPARAM 和 LPARAM 中提取每条消息的参数,从而增强可读性、减少错误并简化您​​必须记住的内容。

宏非常简单,一点也不高科技(它们起源于 16 位 Windows 时代):

#define HANDLE_MSG(hwnd, message, fn)    \
    case (message): return HANDLE_##message((hwnd), (wParam), (lParam), (fn))

但是它们是为所有最常见的消息预定义的(如果您发现需要它们,您可以为它们省略的两三个消息添加您自己的),因此您不必处理丑陋。您只会得到漂亮、可读的代码:

#include <Windows.h>
#include <WindowsX.h>  // for the message cracker macros

...

void Base::OnClose(HWND hWnd)
{
   // ...
}

BOOL Base::OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct)
{
    // ...
   
   return TRUE;
}

void Base::OnDestroy(HWND hWnd)
{
    // ...
}

void Base::OnSize(HWND hWnd, UINT state, int cx, int cy)
{
    // ...
}

LRESULT Base::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
   switch(uMsg)
   {
      HANDLE_MSG(hWnd, WM_CLOSE,   OnClose);
      HANDLE_MSG(hWnd, WM_CREATE,  OnCreate);
      HANDLE_MSG(hWnd, WM_DESTROY, OnDestroy);
      HANDLE_MSG(hWnd, WM_SIZE,    OnSize);
      // TODO: Add more message crackers here to handle additional messages.
      
      default:
         return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
}

头文件还包含显示处理函数签名的注释。但是看看 Hernán Di Pietro's Message Cracker Wizard 让你的生活更轻松。它列出了所有消息,允许您将它们过滤到您要查找的消息,并且会自动将模板代码复制到剪贴板!

关于c++ - Wndproc 处理事件代码少,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37879874/

相关文章:

c++ - cin.getline 在 for 循环中搞砸了

c++ - 平面平铺成不规则大小的矩形

c++ - 我正在从 C 迁移到 C++,但我没有创建类

mysql - Windows 批处理文件 - 连接到远程 MySQL 数据库保存结果文本输出

c++ - 如何typedef模板函数指针?

c++ auto 不命名类型

c++ - 在展开过程中抛出——为什么这个例子有效?

windows - 作为服务运行的 PowerShell 脚本行为异常

windows - 无法在 Windows 10 LTSC 上安装 winget-cli

c++ - 模板化助手函数调用具有特定功能的特定模板化子项