2011-12-06 12 views
0

我使用以下設置創建模式屬性表:無法使用PropSheet創建一個居中的屬性表對話框

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代替,並調用CenterWindow方法傳遞給PropSheetProc的HWND:

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似乎沒有效果。那麼我做錯了什麼?有很多方法可以解決這個問題,但爲什麼它首先被打破?

回答

1

重載CPropertySheet的InitialUpdate(),並將CenterWindow()調用放在那裏。這發生在窗口繪製在屏幕上之前,但在創建之後,所以它的hwnd將是有效的。沒有什麼壞的。該對話框必須被創建爲具有有效的HWND。另外,如果你使用資源編輯器,你可以將它的屬性設置爲居中,並且它會達到相同的結果。爲什麼你重載WinProc的propertysheet? MFC使用消息映射的全部原因是消除了甚至需要接觸WinProc的需求。

如果在SDK風格的應用程序::屬性表的Winproc傳

手柄WM_CREATE使用原始的勝利API。 LPARAM中的LPCREATE結構將包含來自create調用的有效HWND。只要確保你將適當的參數傳遞迴WndProcDefault(),否則窗口創建將失敗。

+0

這是一個很好的答案,但我通過修改PSCB_PRECREATE處理程序中的代碼來解決WS_VISIBLE樣式,從而解決了這個問題。然後我可以在我的閒暇時間使用CenterWindow(hwnd)和ShowWindow(hwnd,SW_SHOW)。我不認爲你可以用屬性表捕獲WM_CREATE?謝謝你。 –