PRB: VBX Controls Automatically Disabled in MFC Dialog Bar
ID: Q119766
|
The information in this article applies to:
-
The Microsoft Foundation Classes (MFC), included with:
-
Microsoft Visual C++ for Windows, 16-bit edition, versions 1.0, 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:
- 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);
}
- 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:
- Edit the .rc file for the sample (ctrlbars.rc) using AppStudio.
- Edit the IDD_VIEWSELECT dialog resource.
- 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.
- 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 query words:
1.00 1.50 2.00 2.50 disabled gray grey dialog bar
Keywords : kb16bitonly
Version :
Platform :
Issue type :
Last Reviewed: July 22, 1999