2012-01-02 10 views
4

シンプルなゲームエンジンの作成に取り組んでおり、Windowsコンソールイベントの処理に問題があります。具体的には、カスタムデータをコールバックハンドラに渡す方法を理解できません。Windowsコンソールコントロールハンドラにデータを渡す

私が最初に私のコールバック関数を指定するには、このコードを呼び出す:

bool WINAPI WindowsSystemManager::ConsoleControlHandler(DWORD controlType){ 
    if(controlType == CTRL_CLOSE_EVENT){ 
     MessageBox(NULL, L"Close Event Captured", L"Close Event Captured", NULL); 
    } 
    return true; 
} 

すべてが正常に動作します - 私はをクリックしたとき:

SetConsoleCtrlHandler((PHANDLER_ROUTINE)WindowsSystemManager::ConsoleControlHandler, true); 

私の静的メンバーのコールバック関数は次のように定義され閉じるボタンを押すと、このMessageBoxがポップアップします。問題は、このタイプのシャットダウン(および他のクリーンアップ)でロギングバッファをログファイルにフラッシュするコードを呼び出す必要があり、LoggerインスタンスはWindowsSystemManagerのメンバです。

SetWindowLongPtrとGetWindowLongPtrを使用して、カスタムデータをウィンドウハンドルに渡すのと同様の問題を扱っていますが、コンソールコントロールハンドラーでこのようなことを行う方法に関する情報はありません。何かご意見は?

編集:この機能はMSaltersの提案に基づいて動作しています。コンソール制御ハンドラのための最終的なコードはここにある:私はWindowsSystemManagerコンストラクタでこのカスタムデータポインタ設定

bool WINAPI WindowsSystemManager::ConsoleControlHandler(DWORD controlType){ 
    BerserkEngine* engine = (BerserkEngine*)GetWindowLongPtr(GetConsoleWindow(), GWLP_USERDATA); 
    if(controlType == CTRL_CLOSE_EVENT){ 
     engine->~BerserkEngine(); 
     PostQuitMessage(0); 
    } 
    return true; 
} 

SetWindowLongPtr(GetConsoleWindow(), GWL_USERDATA, (LONG_PTR)this->engine); 
+0

この関数を使用して、プログラムのどこからでもCTRL_CLOSE_EVENTを捕まえましたか?私が今追いかけている質問を参照してくださいhttp://stackoverflow.com/questions/40464545/custom-event-listener-in-c?noredirect=1#comment68199812_40464545 –

答えて

2

は、私はあなたがこれを必要とするだろう、なぜわかりません。複数のウィンドウを持つことができますが、コンソールは1つだけです。

しかし、GetConsoleWindowSetWindowLongPtrと呼ばれるコンソールHWNDを提供します。それほどきれいではありません(あなたが管理していないウィンドウでこれを行うことは想定されていません)が、うまくいくかもしれません。

+0

おそらく私は十分にはっきりしていませんでした - ウィンドウは1つだけです。私ができる必要があるのは、コンソールコントロールハンドラ内からLoggerインスタンスにアクセスすることだけです。私があなたがコンソールウィンドウのハンドルを取得することができなかったので、あなたが概説した方法はうまくいくはずです。しかし、私が管理していない窓でそれをしてはならないということはどういう意味ですか? – berserkguard

+0

コンソールは1つだけなので、おそらく1つのLoggerしか持たないでしょう。代わりにシングルトンにして、それを渡す必要はありません。 'SetWindowLongPtr'に関しては、' GWLP_USERDATA'に対して 'sizeof(LONG_PTR)'バイトしか利用できず、それらのバイトはウィンドウクラス作成者(すなわちCSRSS)のために予約されています。 – MSalters

+0

うーん、私はそれをシングルトンにすることに目を向けるだろう、それはもっと意味があるだろう。しかし、今のところすべてがうまくいきます - 私はCSRSSを調べます!ありがとう – berserkguard

関連する問題