来自 win32 事件挂钩的 c++ 回调

c++ callback from win32 event hook

我正在尝试为 window 创建和管理编写自己的样板文件 code/library-stuff。我想要实现的是,程序员能够调用带有 lambda 参数的函数,然后该函数将在 window 关闭时执行。 (就像 JavaScript JQuery 使程序员能够添加事件处理程序的方式一样。)我试图创建的结构类似于:

我已经在互联网上搜索了一段时间,但我找不到执行最后一步的任何方法。当然,我可以向事件添加一个挂钩,但是这个挂钩必须是静态的,或者必须是没有捕获的 lambda,所以没有办法与 window 对象通信?我想这意味着这是一个愚蠢的想法,但有没有办法仍然以一种体面的方式实施它?

正如 Hans 指出的那样,使用地图为每个 window 句柄获取 window 效果很好。我有一个带有 window 处理程序和 windows:

的(静态)地图
map<HWND, Window *> Window::handlerWindows;

可以通过静态 getter 获取 window 的处理程序:

Window *Window::getWindow(HWND handler) {
    return handlerWindows[handler];
}

window 过程使用此方法为 window 句柄获取 window,使其处理事件:

LRESULT CALLBACK windowProcedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    Window *window = Window::getWindow(hwnd);
    switch (msg) {
        case WM_CLOSE:
            window->handle(msg);
...

要添加处理程序,需要在事件常量旁边提供 lambda,例如:

window->bind(WM_CLOSE, [&run](){
    run = false;
    return true;
});

这会将处理程序添加到事件处理程序列表中:

map<DWORD, vector<function<bool()>>> eventHandlers;

void Window::bind(DWORD event, function<bool ()> handler) {
    eventHandlers[event].push_back(handler);
}

然后事件处理为:

void Window::handle(DWORD event) {
    vector<function<bool ()>> handlers = eventHandlers[event];
    for_each(handlers.begin(), handlers.end(), [](function<bool ()> handler){
        handler();
    });
}

这个效果很好。