2011-12-06 14 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?谢谢你。 –