BUG: MFC - Changing the BorderStyle Stock Property of An ActiveX Control Changes the Z-Order (306539)



The information in this article applies to:

  • Microsoft Visual C++ .NET (2002)
  • Microsoft Visual C++ .NET (2003)

This article was previously published under Q306539

SYMPTOMS

When a Microsoft Foundation Classes (MFC) ActiveX Control's BorderStyle stock property is changed at runtime, this changes the Z-order of the ActiveX control to the topmost window.

CAUSE

When an MFC ActiveX control's BorderStyle stock property is changed at runtime, the function _AfxToggleBorderStyle is called. This function calls SetWindowLong and then calls SetWindowPos, but does not set the SWP_NOZORDER flag. The ActiveX control is therefore incorrectly moved to the top of the Z-order.

RESOLUTION

To work around this problem, you can save the Z-order position before you set the BorderStyle in the ActiveX Control. Next, restore the Z-order position after you set the BorderStyle. The following is an example:
void CMyEditCtrl::SetBorderStyle(short sBorderStyle) 
{
    HWND hwndParent = 0;
    HWND hwndPrev = 0;
    if (m_pInPlaceSite != NULL)
    {
         m_pInPlaceSite->GetWindow(&hwndParent);
         if (hwndParent)
               hwndPrev = ::GetNextDlgTabItem(hwndParent, m_hWnd, TRUE);
    }
    COleControl::SetBorderStyle(sBorderStyle);
    if (hwndPrev && ::IsWindow(hwndPrev))
          ::SetWindowPos(m_hWnd, hwndPrev, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);

}
				

STATUS

Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.

MORE INFORMATION

Steps to Reproduce Behavior

  1. Create a new MFC ActiveX Control project. Name the ActiveX control, MyEdit. View the ActiveX Control Wizard's Control Settings. In the Create control based on dropdown list select EDIT and then click Finish.
  2. In Class View, expand MyEditLib, right-click the interface and then click Add Property. Select Get/Set methods, and for Property Name, type BorderStyle. (At this point you may have to click Get/Set methods again). Click Finish.
  3. In the CMyEditCtrl::SetBorderStyle method, add a line to set the BorderStyle as follows:
    COleControl::SetBorderStyle(newVal);
    					
  4. Find the dispatch map in CMyEditCtrl.cpp. Make sure that the line containing DISP_PROPERTY_EX is the first one listed in the dispatch map. Build the control.
  5. Add a new MFC application project to the solution. For Application Type select Dialog Based Application and name the application MyDialog.
  6. Place a button control on the dialog box for MyDialog. Change the caption to AddBorder. (The Resource View is not displayed by default. To display it, from the View menu, click Resource View.)
  7. Click Tools and then click Customize Toolbox. In the list of COM components, search for MyEdit control click it to put a check beside it. Click OK. Now you can add MyEdit control to the dialog box from the toolbox.
  8. Right-click MyEdit control and add a variable named m_MyEdit.
  9. Double-click the AddBorder button control to add a handler. In the handler, add the following code:
    m_MyEdit.SetBorderStyle(1);	
    					

  10. Build the solution. In the Solution Explorer, right-click MyDialog and select Set as startup project, and then execute it. Use the Spy++ utility (SPYXX.exe) (see "References" for information on Spy++) to examine the Z-order of the controls before the button is pressed and after it is pressed. You will see that before the button is pressed, the Z-order is:
    • OK button
    • Cancel button
    • AddBorder button
    • MyEdit button

    After you click Add Border button, the Z-order is changed to:

    • MyEdit button
    • OK button
    • Cancel button
    • AddBorder button

REFERENCES

For more information, visit the following Microsoft Web site: For more general information about Visual C++ .NET, visit the following Microsoft Usenet newsgroup and Microsoft Web site:

Modification Type:MinorLast Reviewed:5/28/2003
Keywords:kbbug kbNewsgroupLink kbpending KB306539