2016-11-12 11 views
0

ウィンドウの作成と管理のために私自身の定型コード/ライブラリを作成しようとしています。私が達成しようとしているのは、プログラマがlambdaパラメータを持つ関数を呼び出してウィンドウを閉じて実行できることです。私が作成しようとしています構造のようなものである(JavaScriptのjQueryのイベントハンドラを追加するために、プログラマを可能にする方法と同様。):win32イベントフックからのC++コールバック

  • 私は特定のウィンドウについての情報を保持している私のカスタムWindowクラスのオブジェクトwindowを持っています。
  • このオブジェクトは、ウィンドウのイベントフックをSetWinEventHook(...)に設定します。
  • プログラマはwindow.close(lambda)を呼び出し、ラムダ関数をウィンドウのクローズイベントハンドラリスト/ vectorに追加します。
  • closeイベントが発生すると、このフックはウィンドウのcloseイベントリストからコールバックを呼び出します。

私は今、インターウェブ上でしばらく探していますが、私は最後のステップを実行する方法を見つけることができませんでした。私はイベントにフックを追加できますが、このフックは静的でなければならない、またはキャプチャなしのラムダでなければならないので、ウィンドウオブジェクトと通信する方法はありませんか?私はこれが愚かなアイデアだと思いますが、これをまともな方法で実装する方法はありますか?

+1

SetWinEventHook()を1回だけ呼び出します。コールバックはウィンドウハンドルを提供します。したがって、静的な 'map 'が必要で、Windowオブジェクトを見つけることができます。 –

+0

私はそれについて完全にはっきりしていないかもしれませんが、実際にはSetWinEventHookを1回呼びます。マップについては、それは本当に素晴らしいアイデアです!あなたはそれから完全な答えをしてくださいできますか?私はそれを「私の質問に答えました」とマークすることができます。 ;) –

+0

「完了」にする方法がわかりません。自分の投稿に行ったことを表示して、それをあなたの質問を閉じるための答えとしてマークしてください。 –

答えて

1

Hans氏が指摘したように、地図を使用して各ウィンドウハンドルのウィンドウを取得すると効果的です。私は窓ハンドラや窓付き(スタティック)マップを持っている:

map<HWND, Window *> Window::handlerWindows; 

ウィンドウのハンドラは、静的ゲッター経由で取り込むことができます。

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

ウィンドウプロシージャは、ウィンドウを取得するには、このメソッドを使用していますウィンドウハンドルのために、それはイベント扱いにするために:

:ハンドラを追加するには

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

を、ラムダは同じように、イベントの定数と一緒に提供され

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(); 
    }); 
} 

これは非常によく動作します。

関連する問題