FIX: Apply Button on an ATL Control's Property Page Is Disabled (184820)



The information in this article applies to:

  • The Microsoft Active Template Library (ATL) 2.0, when used with:
    • Microsoft Visual C++, 32-bit Enterprise Edition 4.2b
    • Microsoft Visual C++, 32-bit Professional Edition 4.2b
    • Microsoft Visual C++, 32-bit Enterprise Edition 5.0
    • Microsoft Visual C++, 32-bit Professional Edition 5.0
  • The Microsoft Active Template Library (ATL) 2.1, when used with:
    • Microsoft Visual C++, 32-bit Enterprise Edition 4.2b
    • Microsoft Visual C++, 32-bit Professional Edition 4.2b
    • Microsoft Visual C++, 32-bit Enterprise Edition 5.0
    • Microsoft Visual C++, 32-bit Professional Edition 5.0

This article was previously published under Q184820

SYMPTOMS

When embedding an ATL ActiveX control inside a container application written in Visual Basic (VB), the Apply button on the control's property page is never activated even though the property page's dirty flag is set [that is, calling SetDirty(TRUE)] to enable the button.

CAUSE

Below is the SetDirty() function copied from the Atlctl.h file:
   void SetDirty(BOOL bDirty)
   {
      T* pT = static_cast<T*>(this);
      if (!pT->m_bDirty && bDirty)
         pT->m_pPageSite->OnStatusChange(
            PROPPAGESTATUS_DIRTY | PROPPAGESTATUS_VALIDATE);
      pT->m_bDirty = bDirty;
   }
				
When OnStatusChange() is called, Visual Basic in turn calls IsPageDirty(), which returns S_OK if m_bDirty is set to TRUE; otherwise, S_FALSE.

However, as shown above, m_bDirty is not set until OnStatusChanged() returns.

RESOLUTION

Please note that m_bDirty must be set before OnStatusChanged() is called in SetDirty().

STATUS

Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. This problem was corrected ATL version 3.0, which shipped with Visual C++ version 6.0 for Windows.

MORE INFORMATION

The following are two workarounds:

  1. Add an additional call to OnStatusChanged() right after SetDirty() is called. Using the ATL Polygon sample code, the change is shown below:
          LRESULT OnSidesChange(WORD wNotify, WORD wID, HWND hWnd, BOOL&
             bHandled)
          {
             SetDirty(TRUE);
             m_pPageSite->OnStatusChange(
                PROPPAGESTATUS_DIRTY | PROPPAGESTATUS_VALIDATE);
             return 0;
          }
    							
  2. Change the SetDirty() function in Atlctl.h to the following:
          void SetDirty(BOOL bDirty)
          {
             T* pT = static_cast<T*>(this);
             if (pT->m_bDirty != bDirty)
             {
                pT-.m_bDirty = bDirty;
                if (bDirty)
                   pT->m_pPageSite->OnStatusChange(
                      PROPPAGESTATUS_DIRTY | PROPPAGESTATUS_VALIDATE);
             }
          }
    							

Steps to Reproduce Behavior

  1. Place an ATL Polygon control on a Visual Basic Form.
  2. Display the Polygon control's Property Pages dialog box by selecting the (Custom) property from Visual Basic's Properties window.

    NOTE: The Apply button on the Property Pages window is initially disabled.
  3. Enter an integer value in the Sides edit box.

    NOTE: The Apply button remains disabled.
(c) Microsoft Corporation 1998, All Rights Reserved. Contributions by Yeong- Kah Tam, Microsoft Corporation

Modification Type:MajorLast Reviewed:12/8/2003
Keywords:kbATL300fix kbBug kbContainer kbCtrl kbfix kbPropSheet kbVC600fix KB184820