You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何更简便地创建类虚函数及调用宏?附Controller类示例

Simplifying Virtual Message Handlers and Dispatch in C++ Classes

Absolutely—repeating virtual function declarations and manual switch-case entries for Windows messages is a common pain point, and macros (or streamlined patterns) can clean this up nicely. Let's walk through practical, readable solutions for both parts:

1. Simplifying Virtual Function Declarations

Instead of writing out the full virtual function signature every time, create a macro that generates the boilerplate for you. This keeps your class declaration concise and consistent.

Example Macro for Declarations:

#define DECLARE_WM_HANDLER(msg_name) \
    virtual int On##msg_name(WPARAM wParam, LPARAM lParam, bool& bHandled) { return 0; }

Using the Macro in Your Controller Class:

class Controller {
public:
    // Generate default virtual handlers with one line each
    DECLARE_WM_HANDLER(Close)
    DECLARE_WM_HANDLER(Destroy)
    DECLARE_WM_HANDLER(Paint)
    DECLARE_WM_HANDLER(Create) // Add this if you need OnCreate too

    // ... rest of your class implementation
};

This macro auto-generates the virtual function with your default return value of 0, matching your original code. Subclasses can still override these functions normally—just define int DerivedController::OnPaint(...) { /* custom logic */ } as you would with a manually declared virtual function.

2. Simplifying Message Dispatch (Switch-Case)

You can also eliminate repetitive case statements with a macro that maps Windows message constants directly to your handler functions.

Example Macro for Dispatch:

#define CASE_WM_HANDLER(msg_const, handler_func) \
    case msg_const: \
        lRes = handler_func(wParam, lParam, bHandled); \
        break;

Using the Macro in Your Message Handling Logic:

// Inside your window procedure or message processing method
int lRes = 0;
bool bHandled = false;

switch (uMsg) {
    CASE_WM_HANDLER(WM_CREATE, OnCreate)
    CASE_WM_HANDLER(WM_DESTROY, OnDestroy)
    CASE_WM_HANDLER(WM_PAINT, OnPaint)
    CASE_WM_HANDLER(WM_CLOSE, OnClose)

    // Add other messages here with a single line each
    default:
        bHandled = false;
        break;
}

Bonus: Keeping It Maintainable

If you want to reduce even more duplication, you could link declaration and dispatch macros together, or explore template-based message maps (though macros are more traditional in Win32 C++ codebases). Just remember: readability should always take priority over over-engineering macros—keep them simple enough that any developer on your team can quickly understand what they do.

Quick Tips:

  • Prefix your macro names (e.g., WM_ or your project initials) to avoid naming conflicts with other code.
  • Adjust the default return value in DECLARE_WM_HANDLER if your pattern requires it (e.g., return DefWindowProc results).
  • Overriding handlers in subclasses works exactly like with manual virtual functions—no extra steps needed.

内容的提问来源于stack exchange,提问作者ciyaso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:45:58