DOCUMENT:Q147206 06-MAY-2001 [visualc] TITLE :FIX: Border of Modeless CPropertySheet Is Not 3D in Windows NT PRODUCT :Microsoft C Compiler PROD/VER:winnt:4.0 OPER/SYS: KEYWORDS:kbDlg kbMFC KbUIDesign kbVC400bug kbVC410fix kbGrpDSMFCATL ====================================================================== ------------------------------------------------------------------------------- The information in this article applies to: - The Microsoft Foundation Classes (MFC), included with: - Microsoft Visual C++, 32-bit Editions, version 4.0 ------------------------------------------------------------------------------- SYMPTOMS ======== If you create a modeless CPropertySheet under Windows NT, its outer border will not be a 3D border. A modal CPropertySheet will have a 3D border. Both modal and modeless CPropertySheets have a 3D border under Windows 95. CAUSE ===== MFC sets up a callback function for modeless CPropertySheets called AfxPropSheetCallback(). This function checks for PSCB_PRECREATE, which is a message that is received before a property sheet is created. In this handler, MFC takes out the DS_MODALFRAME style. Ctl3d32.dll is used by Windows NT to paint 3D borders for controls and windows. For a dialog box to have a 3D border, CTL3D requires a style of DS_MODALFRAME. RESOLUTION ========== 1. Derive a class from CPropertySheet (CMySheet) and override its Create(). Comment the call to CWnd::Create() that the ClassWizard puts in. 2. Copy code from CPropertySheet::Create() in DLGPROP.CPP (as shown below) into CMySheet::Create(), and change the parameters it takes accordingly. 3. Change this line: m_psh.dwFlags |= (PSH_MODELESS|PSH_USECALLBACK); to: m_psh.dwFlags |= PSH_MODELESS; The callback function isn't set so that PSCB_PRECREATE is not handled, and the DS_MODALFRAME style is not removed. 4. Comment out this line: m_psh.pfnCallback = AfxPropSheetCallback; 5. Include in MySheet.h. 6. In MySheet.h, change the MySheet.Create to take the corresponding parameters: BOOL Create(CWnd* pParentWnd = NULL, DWORD dwStyle = WS_SYSMENU | WS_POPUP | WS_CAPTION | DS_MODALFRAME | WS_VISIBLE, DWORD dwExStyle = WS_EX_DLGMODALFRAME ); STATUS ====== Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. This problem was corrected in Visual C++, 32-bit Edition, version 4.1. MORE INFORMATION ================ Sample Code ----------- // in MySheet.h #include BOOL Create(CWnd* pParentWnd = NULL, DWORD dwStyle = WS_SYSMENU | WS_POPUP | WS_CAPTION | DS_MODALFRAME | WS_VISIBLE, DWORD dwExStyle = WS_EX_DLGMODALFRAME ); // In MySheet.cpp // CMySheet is derived from CPropertySheet BOOL CMySheet::Create(CWnd* pParentWnd, DWORD dwStyle, DWORD dwExStyle) { _AFX_THREAD_STATE* pState = AfxGetThreadState(); pState->m_dwPropStyle = dwStyle; pState->m_dwPropExStyle = dwExStyle; ASSERT_VALID(this); ASSERT(m_hWnd == NULL); // WS_SYSMENU must not be set if a property sheet is created as a child if (dwStyle & WS_CHILD) dwStyle &= ~WS_SYSMENU; // finish building PROPSHEETHEADER structure BuildPropPageArray(); m_bModeless = TRUE; // original line specifies a callback function // m_psh.dwFlags |= (PSH_MODELESS|PSH_USECALLBACK); // new line does not specify a callback function m_psh.dwFlags |= PSH_MODELESS; // m_psh.pfnCallback = AfxPropSheetCallback; m_psh.hwndParent = pParentWnd->GetSafeHwnd(); // hook the window creation process AfxHookWindowCreate(this); HWND hWnd = (HWND)PropertySheet(&m_psh); // clean up on failure, otherwise return TRUE if (!AfxUnhookWindowCreate()) PostNcDestroy(); // cleanup if Create fails if (hWnd == NULL || hWnd == (HWND)-1) return FALSE; ASSERT(hWnd == m_hWnd); return TRUE; } /* Compile options needed: default */ Additional query words: 4.00 border CPropertySheet modeless Property Sheet vcfixlist410 ====================================================================== Keywords : kbDlg kbMFC KbUIDesign kbVC400bug kbVC410fix kbGrpDSMFCATL Technology : kbAudDeveloper kbMFC Version : winnt:4.0 Issue type : kbbug Solution Type : kbfix ============================================================================= THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY. Copyright Microsoft Corporation 2001.