2

我在一些项目上使用 C 并使用 Win32API,使用不同的语言或任何其他库,如 MFC、GTK、QT .. 等,不是一种选择。

我正在寻找一种处理 Windows 消息/信号/事件的好方法,例如:

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    switch(msg) {
        case WM_CLOSE:
            DestroyWindow(hwnd);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        case WM_COMMAND:
            switch(wparam) {
                case ID_OK_BUTTON:
                    DoSomething(hwnd);
                    break;
                case ID_FOO_BUTTON:
                    DoFoo(hwnd);
                    break;
                /*
                ....
                It's only getting more complex
                ....
                */
                case ID_BAR_BUTTON:
                    DoBar(hwnd);
                    break;
                case ID_EXIT_BUTTON:
                    SendMessage(hwnd, WM_CLOSE, wparam, lparam);
                    break;
                case ID_OPEN_BUTTON:
                    OpenFile(hwnd);
                    break;
            }
            break;
        default:
            return DefWindowProc(hwnd, msg, wparam, lparam);
    }
    return 0;
}

这部分只会变得越来越复杂和丑陋。您是否知道任何简化它的方法,也许就像我在许多 GUI 库中经常看到的那样:

some_magic(some_object, message, callback);

任何简单的建议都会有很大帮助。

4

1 回答 1

6

MFC、ATL、WTL 使用映射概念以开发人员友好的方式定义消息到成员的映射。宏隐藏消息/命令/通知代码的比较,并且在满足标准时调用相应的成员函数。

我希望这能解释它是如何工作的。一组MAP_ENTRY线条应该看起来不那么难看。

#define MAP_ENTRY(message, callback) if(msg == message) return callback(wnd, msg, wparam, lparam);
// ...
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
  MAP_ENTRY(WM_INITDIALOG, OnInitDialog)
  MAP_ENTRY(WM_DESTROY, OnDestroy)
  MAP_ENTRY(WM_TIMER, OnTimer)
  return DefWindowProc(hwnd, msg, wparam, lparam);
}
LRESULT OnInitDialog(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
  // ...
}
LRESULT OnDestroy(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
  // ...
}
LRESULT OnTimer(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
  // ...
}
于 2012-10-06T19:39:00.750 回答