0


0

私はwin32ラッパークラスを書いています。主にwin32プログラミングについて学ぶためです。 Cスタイルのコールバックの問題を回避するために、次のメソッドはSetWindowLong / GetWindowLongを使用してポインタを保存/取得し、実際のwinprocに渡します。

LRESULT CALLBACK WinClass :: WindowProc(HWND hwnd、UINT msg、WPARAM wParam、LPARAM lParam){//ウィンドウの作成時に、WindowProcはLPCREATESTRUCTとしてlParamを受け取る:: SetWindowLong(hwnd、GWL_USERDATA、reinterpret_cast(reinterpret_cast(lParam) - > lpCreateParams));

//ポインタを取得するWinClass * wnd = reinterpret_cast(:: GetWindowLongPtr(hwnd、GWL_USERDATA));

//(wnd)return wnd-> WndProc(hwnd、msg、wParam、lParam); //実際のwinproc関数を呼び出す。 //デフォルトはDefWindowProcメッセージハンドラ関数。return :: DefWindowProc(hwnd、msg、wParam、lParam); }

Winclassは、CreateWindowExによって作成されたメインウィンドウをラップするクラスです。 同じWindowProc関数は、モーダルダイアログをラップするMDlgClassの一部です。 私はこのような対話を呼んでいます

DialogBox(GetModuleHandle(NULL)、MAKEINTRESOURCE(id)、hwnd、DialogProc);

hWndParentとしてNULLを渡すと、ダイアログはモードレスダイアログとして問題なく動作しますが、hwnd、メインウィンドウへのハンドルをhWndParentとして渡すと、ダイアログはモーダルダイアログとして正しく動作します。 しかし、私がダイアログを閉じるとき、それはメインの親ウィンドウに制御を戻しませんか? Visual Studioでデバッグすると、WinMainのメッセージポンプにハングしていることがわかります。

私はポインタをマッピングするためにハッシュマップを使うことを考えました、しかし私はむしろGetWindowLongなどを使ってそれをしたいです これは可能ですか? ダイアログポインタをDWL_USERに格納しようとしましたが、役に立ちません。

どんな助けでも評価されるでしょう、私はまだWin32のまわりで私の頭を得ています。

編集:私はEndDialogを使用してダイアログを破壊しています

編集:私はメインウィンドウのGWL_USERDATA領域にポインタを格納しています。これはウィンドウでは使用されず、ウィンドウが最初に作成されたときにWinClass

WindowProcで変更するだけです。 ダイアログクラスをインスタンス化しない場合、アプリケーションはWindowProcおよびWM_COMMANDを介して処理されたメニューコマンドに応答するため、ポインタが正しくアクセスされていることがわかります。

4 Answer


5


WindowProcをDialogProcとして使用することはできません。 ウィンドウプロシージャは、メッセージを処理しないときにDefWindowProcを呼び出し、処理するときに意味のある結果を返します。 ダイアログプロシージャは、メッセージを処理しない場合はFALSEを返し、実行する場合はTRUEを返します(ただし、 `+ WM_INITDIALOG `を処理する場合を除く)。 ` DWL_MSGRESULT +`に配置されます。

モーダルダイアログボックス関数DialogBoxを呼び出すと、スレッド内のすべてのウィンドウにメッセージがディスパッチされるため、ダイアログが閉じられたとき(EndDialogを使用して)、ダイアログボックスはダイアログを閉じます手続きが戻るはずです。

ダイアログボックスをラップするクラスを作成するとき、通常の方法は、 'this’ポインターをDialogBoxParam関数の1つに渡すことです。これは、 `+ WM_INITDIALOG +`メッセージから直接抽出できます。


0


どうやって窓を閉めますか。 `+ DestroyWindow +`を使用していますか? 子ウィンドウがライブの間は、親ウィンドウは無効になります。


0


あなたはlpCreateParamsへのポインタを保存しています。 関連付けられているメモリブロックが解放されているか、そうでなければ破壊されている可能性がありますか?


0


//static method
BOOL CALLBACK WinClass :: DlgProc(HWND hwnd、UINT msg、WPARAM wParam、LPARAM lParam){//この*ポインタをGWL_USERDATAに格納する限り;); m_hWnd = hWnd; //私はあなたが本当にhwndを回し続けたくないのではないかと思います}

WinClass * wnd = reinterpret_cast(:: GetWindowLongPtr(hwnd、GWL_USERDATA)); if(wnd)wnd-> DlgProcImpl(umsg、wParam、lParam)を返します。 FALSEを返します。 }

BOOL WinClass :: DlgProcImpl(UINT uMsg、WPARAM wParam、LPARAM lParam){switch(uMsg){//あなたのコードはここに入ります

FALSEを返します。 }

FALSEを返します。 }

INT_PTR WinClass:DoModalDialog(HINSTANCE hInst、HWND hwndParent、LPCTSTRテンプレート) }