KnowledgeBase Archive

An Archive of Early Microsoft KnowledgeBase Articles

View on GitHub

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

Article: Q147206
Product(s): Microsoft C Compiler
Version(s): winnt:4.0
Operating System(s): 
Keyword(s): kbDlg kbMFC KbUIDesign kbVC400bug kbVC410fix kbGrpDSMFCATL
Last Modified: 06-MAY-2001

-------------------------------------------------------------------------------
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 <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 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 1986-2002.