PropSheet: モードレスプロパティシートの終了方法(閉じ方)
PROPSHEETHEADER 構造体の dwFlags メンバに PSH_MODELESS を指定した場合、プロパティページはモードレスダイアログ(オーナーウィンドウが無効化されない)で作成され、PropertySheet 関数はそのウィンドウハンドルを返します(戻り値は元々 INT_PTR 型なので、型キャストしてください)。
このウィンドウの扱いと閉じ方について、MSDN ライブラリの「PropertySheet」関数の説明に以下の記述があります。
For a modeless property sheet, your message loop should use PSM_ISDIALOGMESSAGE to pass messages to the property sheet dialog box. Your message loop should use PSM_GETCURRENTPAGEHWND to determine when to destroy the dialog box. When the user clicks the OK or Cancel button, PSM_GETCURRENTPAGEHWND returns NULL. You can then use the DestroyWindow function to destroy the dialog box.
適当訳: モードレスプロパティシートでは、アプリケーションのメッセージループ内で、プロパティシートに PSM_ISDIALOGMESSAGE を送ってください。また、PSM_GETCURRENTPAGEHWND を送ってプロパティシートを終了するタイミングをチェックしてください。プロパティシートで OK やキャンセルボタンが押されると PSM_GETCURRENTPAGEHWND から NULL が返るので、そのタイミングで DestroyWindow を呼び出すことが出来ます。
※ PSM_ISDIALOGMESSAGE は、lParam に LPMSG 型の引数を取るメッセージで、IsDialogMessage の代わりとなります。これを送らないと、プロパティシート内でキー操作が出来なくなります。
ということで、モードレスプロパティシートを適切に終了するには、以下のようなコードになります。
// g_hPropSheet はモードレスプロパティシートのハンドルを保持するグローバル変数 HWND g_hPropSheet; // メッセージループ MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { // プロパティシートがメッセージ処理をするかどうかチェック if (!g_hPropSheet || !SendMessage(g_hPropSheet, PSM_ISDIALOGMESSAGE, 0, (LPARAM)(LPMSG) &msg)) { // 通常のメッセージ処理を行う TranslateMessage(&msg); DispatchMessage(&msg); } // プロパティシートを閉じるべきかどうかチェック if (g_hPropSheet && !SendMessage(g_hPropSheet, PSM_GETCURRENTPAGEHWND, 0, 0)) { // プロパティシートを終了する DestroyWindow(g_hPropSheet); g_hPropSheet = NULL; } }