PRB: VBX Controls Automatically Disabled in MFC Dialog Bar

Last reviewed: July 22, 1997
Article ID: Q119766
1.00 1.50 WINDOWS kbprg kbprb

The information in this article applies to:

   The Microsoft Foundation Classes (MFC), included with:
    - Microsoft Visual C++ for Windows, versions 1.0 and 1.5

SYMPTOMS

After adding VBX controls to an MFC dialog bar object, they are automatically disabled when the program is executed.

CAUSE

Many VBX controls are implemented by subclassing the standard Windows button class. MFC CDialogBar objects automatically disable button controls which do not implement a WM_COMMAND or ON_UPDATE_COMMAND_UI message handler.

This is by design, but since ClassWizard does not provide support for adding these handlers for VBX controls, it can sometimes be undesirable.

RESOLUTION

There are two methods which can be used to work around this problem.

Method #1:

This solution requires you to manually add an ON_COMMAND_UPDATE_UI handler for each VBX control that subclasses the standard Windows button class. This handler will simply enable the control whenever it is called.

As mentioned above, ClassWizard does not provide support for adding ON_UPDATE_COMMAND_UI handlers for VBX controls. It only allows you to create VBX event notification functions.

Note: The ON_UPDATE_COMMAND_UI handler, in case of a CDialogBar would be added to the parent of CDialogBar, which usually is the CMainFrame class created by AppWizard.

To manually add an ON_UPDATE_COMMAND_UI handler, follow these steps:

  1. In the header (.h) file for the parent, go to the section marked with the special //{{AFX_MSG comments. Outside this block, add a handler prototype for each VBX that subclasses the standard Windows button class. For two VBX controls, the results should be similar to the following:

    // Generated message map functions
    
protected:
     //{{AFX_MSG(CMainFrame)
     ...
     //}}AFX_MSG
     afx_msg void OnUpdateVBXControl1(CCmdUI* pCmdUI);
     afx_msg void OnUpdateVBXControl2(CCmdUI* pCmdUI);

  • In the implementation (.cpp) file for the parent, go to the message map section and add entries for each ON_UPDATE_COMMAND_UI handler. The results should look like this:

    BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)

         //{{AFX_MSG_MAP(CMainFrame)
         ...
         //}}AFX_MSG_MAP
         ON_UPDATE_COMMAND_UI(IDC_VBXCONTROL1, OnUpdateVBXControl1)
         ON_UPDATE_COMMAND_UI(IDC_VBXCONTROL2, OnUpdateVBXControl2)
    
    END_MESSAGE_MAP()

       In this example, IDC_VBXCONTROL1 and IDC_VBXCONTROL2 are the resource
       identifiers for the two VBX controls.
    
    

  • In the implementation (.cpp) file for the parent, write the functions which will handle updating the UI for these controls. The functions should look like:

    void CMainFrame::OnUpdateVBXControl1(CCmdUI* pCmdUI)
    
    {
         pCmdUI->Enable(TRUE);
    
    }

    void CMainFrame::OnUpdateVBXControl2(CCmdUI* pCmdUI)
    
    {
         pCmdUI->Enable(TRUE);
    
    }

    1. Rebuild the project. You should now see that the VBX controls are enabled.

    Method #2:

    This solution is much easier to implement, although it has the drawback of preventing automatic disabling of non-VBX button controls on a dialog bar. Thus, no button control will ever be disabled even if it doesn't implement a WM_COMMAND or ON_UPDATE_COMMAND_UI handler.

    The CControlBar class defines the OnUpdateCmdUI() pure virtual function, which is overridden in the CDialogBar class to call CWnd::UpdateDialogControls. This function is presented below:

    void CDialogBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL
    
    bDisableIfNoHndler) {
         UpdateDialogControls(pTarget, bDisableIfNoHndler);
    
    }

    This is the function which is responsible for automatically disabling button controls on a dialog bar.

    You can prevent this function from being called by deriving a class from CDialogBar and overriding this function so that it resembles the following:

    void CMyDerivedDialogBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL
    
    bDisableIfNoHndler) {
         UpdateDialogControls(pTarget, FALSE);
    
    }

    MORE INFORMATION

    To reproduce the problem add a VBX control to the dialog bar in the CTRLBARS sample included as a MFC sample with Visual C++. To add the VBX do the following:

    1. Edit the .rc file for the sample (ctrlbars.rc) using AppStudio.

    2. Edit the IDD_VIEWSELECT dialog resource.

    3. Add a Command3D button on to the dialog bar. If the Command3D control is not in the AppStudio control palette, the threed.vbx file needs to be installed in AppStudio. For more information on adding VBX controls to AppStudio, please refer to the section "To add a VBX control to the AppStudio control palette" in the AppStudio User's Guide.

    4. Add EnableVBX() to CCtrlbarsApp::InitInstance() in ctrlbars.cpp.

    Build and run the sample. The Command3D button shows up on the dialog bar but is disabled. After adding the workarounds mentioned above, the button is enabled.

    REFERENCES

    Technical Note 31: Control Bars, under MFC Technotes included with Visual C++.


  • Additional reference words: 1.00 1.50 2.00 2.50 disabled gray grey dialog
    bar
    KBCategory: kbprg kbprb
    KBSubcategory: MfcVBX
    Keywords : kb16bitonly
    Technology : kbMfc


    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: July 22, 1997
    © 1998 Microsoft Corporation. All rights reserved. Terms of Use.