FIX: Border of Modeless CPropertySheet Is Not 3D in Windows NT

Last reviewed: September 19, 1997
Article ID: Q147206
4.00 WINDOWS NT kbprg kbbuglist kbfixlist

The information in this article applies to:

  • The Microsoft Foundation Classes (MFC) included with: Microsoft Visual C++, 32-bit Edition, 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 <afxpriv.h> 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 <afxpriv.h>

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 reference words: 4.00 border CPropertySheet modeless Property
Sheet vcbuglist400 vcfixlist410
KBCategory: kbprg kbbuglist kbfixlist
KBSubcategory: MfcUI
Keywords : MfcUI kbbuglist kbfixlist kbprg
Technology : kbMfc
Version : 4.00
Platform : NT WINDOWS
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.

Last reviewed: September 19, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.