如何更简便地创建类虚函数及调用宏?附Controller类示例
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_HANDLERif your pattern requires it (e.g., returnDefWindowProcresults). - Overriding handlers in subclasses works exactly like with manual virtual functions—no extra steps needed.
内容的提问来源于stack exchange,提问作者ciyaso

