0

次の設定を使用して、モードレスプロパティシートを作成しています。

   PROPSHEETHEADER pshdr = { 0 };

   pshdr.dwSize = sizeof(PROPSHEETHEADER);
   pshdr.dwFlags = PSH_NOAPPLYNOW | PSH_PROPSHEETPAGE |
                   PSH_MODELESS | PSH_USECALLBACK;
   pshdr.pfnCallback = PropSheetProc;
   pshdr.hwndParent = mGlobalState->trayWin;
   pshdr.pszCaption = L"My Settings";
   pshdr.nPages = mPages.size();
   pshdr.ppsp = mWinPages;

PropSheetProcで、PSCB_PRECREATEメッセージをキャッチし、DS_CENTERスタイルを取得するようにダイアログテンプレートを変更します。

static int CALLBACK
PropSheetProc(HWND hwndDlg,  // IN
              UINT uMsg,     // IN
              LPARAM lParam) // IN
{
   // Before the dialog is created, bless it with the DS_CENTER style.
   if (uMsg == PSCB_PRECREATE) {
      DLGTEMPLATE *dlgTemplate = (DLGTEMPLATE *)lParam;
      _ASSERT(dlgTemplate);

      dlgTemplate->style |= DS_CENTER;
   }

   return 0;
}

ただし、これではダイアログを中央に配置できません。代わりにPSCB_INITIALIZEDをキャッチして、PropSheetProcに渡されたhwndでCenterWindowメソッドを呼び出そうとしました。

void
CenterWindow(HWND hwndWindow) // IN
{
   int nX, nY, nScreenWidth, nScreenHeight;
   RECT rectWindow;

   nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
   nScreenHeight = GetSystemMetrics(SM_CYSCREEN);

   GetWindowRect(hwndWindow, &rectWindow);

   nX = (nScreenWidth - (rectWindow.right - rectWindow.left)) / 2;
   nY = (nScreenHeight - (rectWindow.bottom - rectWindow.top)) / 2;

   SetWindowPos(hwndWindow, 0, nX, nY, 0, 0,
                SWP_NOZORDER | SWP_NOSIZE);
}

しかし、それもうまくいきません!

最後に、CenterWindow呼び出しをPropSheet呼び出しの直後に移動しました。

   mHwnd = (HWND)PropertySheet(&pshdr);
   CenterWindow(mHwnd);
   return mHwnd != NULL;

そして、これは機能しますが、負荷の高いシステムでは、ダイアログが最初の位置から最後の位置まで点滅しますが、これは最適ではありません。

PropSheetProcを使用してDLGTEMPLATE構造を変更することは、直感的に思えます。実際、他のウィンドウスタイルを適用できます。しかし、DS_CENTERは効果がないようです。だから私は何が間違っているのですか?この破損を回避する方法はたくさんありますが、そもそもなぜ破損しているのでしょうか。

4

1 に答える 1

1

CPropertySheetのInitialUpdate()をオーバーロードし、そこにCenterWindow()呼び出しを配置し​​ます。これは、ウィンドウが画面に描画される前に発生しますが、ウィンドウが作成された後なので、hwndは有効になります。壊れているものは何もありません。有効なHWNDを使用するには、ダイアログを作成する必要があります。または、リソースエディターを使用している場合は、プロパティを中央に設定すると、同じ結果が得られます。プロパティシートのWinProcをオーバーロードするのはなぜですか?MFCがメッセージマップを使用する理由は、WinProcに触れる必要さえなくなるためです。

SDKスタイルのアプリケーションでrawwinapiを使用している場合::

プロパティシートのWinProcでWM_CREATEを処理します。LPARAMのLPCREATE構造体には、create呼び出しからの有効なHWNDが含まれます。適切なパラメータをWndProcDefault()に戻すようにしてください。そうしないと、ウィンドウの作成が失敗します。

于 2011-12-06T22:44:35.123 に答える