1

PropertySheetAPI を使用すると、[OK] または [適用] ボタンが押されたときに (Windows XP 以降で) メッセージを受信できる を定義できますPropSheetProc。これにより、これらのボタンのいずれかがクリックされたときに処理を実行できます。

ただし、このハンドラーは、個々のプロパティ ページがそれぞれのダイアログ プロシージャを介して通知を受け取る前に呼び出されます。これらの通知が処理された後、できれば醜いハックなしでPSN_APPLY処理を行いたいです。どうすればいいですか?

背景:構成を単一の に保存しています。struct個々のページstructは、適用時にそれぞれの部分を変更します。struct次に、これらの値が書き込まれた後、各プロパティ ページからすべての設定を再適用するのではなく、すべての設定を一度に適用したいと考えています。

4

3 に答える 3

3

最終的に、PropSheetProcコールバックを使用してプロパティ シートのウィンドウ ハンドルをキャプチャし、次のようにサブクラス ウィンドウ プロシージャを接続しました。

// This is not officially defined, but the whole world uses it.
#define ID_APPLY_NOW 0x3021

WNDPROC origWinProc;

LRESULT CALLBACK MyWinProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
  // Call the original window procedure.
  LRESULT retVal = CallWindowProc(origWinProc, hwndDlg, msg, wParam, lParam);
  // Now, and only now, do our own stuff.
  switch (msg) {
    case WM_COMMAND:
      switch (LOWORD(wParam)) {
        case IDOK:
        case ID_APPLY_NOW:
          applyConfig();
          saveConfig();
          break;
      }
      break;
  }
  // Return the original winproc's result.
  return retVal;
}

int CALLBACK myPropSheetProc(HWND hwndDlg, UINT msg, LPARAM lParam) {
  switch (msg) {
    case PSCB_INITIALIZED:
      // Override the property sheet's window procedure with our own.
      origWinProc = (WNDPROC)SetWindowLongPtr(hwndDlg, GWLP_WNDPROC, (LONG_PTR)&MyWinProc);
      break;
  }
  return 0;
}

(はい、switch考慮すべきケースが 1 つしかない場合でもステートメントを使用します。私はそのように奇妙です。)

于 2009-10-01T20:38:47.870 に答える
0

ダイアログ ハンドラの内部から構造体を適用する必要はありません。そのため、モーダル プロパティ シートの場合は、次のような簡単なことを行うことができます。

// Display the property sheet.
PropertySheet(&theSheet);
// The peroperty sheets PSN_APPLY notification sets this bool to true in the struct.
if(theStruct.fApply)
  ApplyTheStruct(&theStruct);

または、「構造体」がページに入力された情報を収集するだけであるため、ユーザーがページを操作するときに構造体を変更しない理由がわかりません。ページごとのPSN_APPLYメッセージを無視し、PropSheetProc が呼び出されたときに構造体を適用します。または、通知が の場合は完全に破棄しPSN_CANCELます。

于 2009-10-01T08:09:31.100 に答える
0

IDOK、IDAPPLY、IDCANCEL の WM_COMMAND の BL_CLICKED メッセージを傍受できませんでしたか?

MFCを使用していますか?またはATL?

BM_CLICKEDを傍受できない時が来るとは思えませんが...

編集:うーん、その機能を介してプロパティページを使用したことはありません...それを読んだだけです。pfnCallback 関数を設定し、PSH_USECALLBACK フラグを設定しましたか?

各ページにはダイアログ プロシージャもあります。そこからもOK、キャンセル、申請を傍受できませんか?しかし、他のプランの方が適していると思います。

于 2009-09-30T20:50:50.647 に答える