PRB: Controls in Toolbars Refuse to Give the Focus to ViewsID: Q134763
|
In an MFC application, controls added to a toolbar may prevent the input focus from returning to the active view. For example, when a user clicks a combo box or edit control in a toolbar and then clicks a view, the control retains the input focus. This happens for any CControlBar-derived class containing a control that can accept the input focus. This behavior does not exist for views derived from CFormView or CEditView.
When MFC reactivates an already active view, it does not set the input focus to the view. As a result, any control in the toolbar which has the input focus retains the focus.
int CMyView::OnMouseActivate(CWnd* pDesktopWnd,
UINT nHitTest, UINT message)
{
// Call the base class to get a return value
int nResult = CView::OnMouseActivate(pDesktopWnd,
nHitTest, message);
if (nResult == MA_ACTIVATE || nResult == MA_ACTIVATEANDEAT)
{
OnActivateView(TRUE, this, this);
}
return nResult;
}
int CMyMDIChildWnd::OnMouseActivate(CWnd* pDesktopWnd,
UINT nHitTest, UINT message)
{
// Call the base class FIRST to get a return value for later
int nResult = CMDIChildWnd::OnMouseActivate(pDesktopWnd,
nHitTest, message);
// Correct for focus not being set in
// CMDIChildWnd::OnMouseActivate()
SetFocus();
return nResult;
}
To handle the case of choosing the already-checked item for the MDI child
window from the application's Window menu, override OnCommand() for your
CMainFrame class. Call the base class implementation first, and save the
result. Then determine that the menu item ID you are passed is for an MDI
child window, that it is your own MDI child, which should be active, and
that you are of the runtime class CView. If all of that is true, then call
SetFocus, and return the value you saved from your call to the base class.
The following code, adapted from the MFC source for
CMDIFrameWnd::OnCommand(), demonstrates how to do this:
BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam)
{
// Call the base class FIRST to get a return value for later
BOOL bRet = CMDIFrameWnd::OnCommand(wParam, lParam);
ASSERT(AFX_IDM_FIRST_MDICHILD == 0xFF00);
// If the correct part of lParam is NULL, this message was sent
// because a menu item was chosen with the mouse or the keyboard
if (LOWORD(lParam) == NULL &&
(LOWORD(wParam) & 0xf000) == 0xf000)
{
ASSERT_VALID(MDIGetActive(NULL));
// Do this ONLY for a CView-derived class
if ((GetFocus()->GetParentFrame() != MDIGetActive(NULL)) &&
(MDIGetActive(NULL)->GetActiveView()->
IsKindOf(RUNTIME_CLASS(CView))))
{
SetFocus();
}
}
return bRet;
}
This behavior is by design.
For information on how to add a control, such as an edit or combo box, to a toolbar, please see the CTRLBARS sample application shipped with Microsoft Visual C++.
Additional query words: 1.50 1.51 1.52 2.50 2.51 2.52
Keywords : kb16bitonly
Version :
Platform :
Issue type :
Last Reviewed: July 30, 1999