Я только что попробовал стандартный способ добавления CToolbar в диалог на новом CMFCToolBar. Но это не работает. Прежде чем я окунусь в новую реализацию, я хочу знать, возможно ли это на самом деле?
Можно ли добавить CMFCToolBar в диалог?
Ответы (3)
Я не уверен, что вы подразумеваете под «стандартным способом», но вы, безусловно, можете сделать это программно:
// In MyDlg.h
class CMyDlg : public CDialog
{
...
CMFCToolBar m_ToolBar;
...
};
// In MyDlg.cpp
BOOL CMyDlg::OnInitDialog()
{
...
if( m_ToolBar.Create( this, AFX_DEFAULT_TOOLBAR_STYLE, 100 ) )
{
m_ToolBar.SetPaneStyle( m_ToolBar.GetPaneStyle()
& ~(CBRS_GRIPPER | CBRS_SIZE_DYNAMIC | CBRS_BORDER_ANY) );
m_ToolBar.InsertButton( CMFCToolBarButton( ID_APP_ABOUT, -1, _T("About") ) );
m_ToolBar.InsertButton( CMFCToolBarButton( ID_APP_EXIT, -1, _T("Exit") ) );
CSize sizeToolBar = m_ToolBar.CalcFixedLayout( FALSE, TRUE );
m_ToolBar.SetWindowPos( NULL, 0, 0, sizeToolBar.cx, sizeToolBar.cy,
SWP_NOACTIVATE | SWP_NOZORDER );
}
...
}
OnInitDialog
выше работает хорошо, за исключением случаев, когда команда является только диалоговой командой.
Если нет приложения или обработчика мейнфрейма, кнопка отключается, и обработчик не вызывается. Обратите внимание, что приведенный выше код маршрутизируется правильно, потому что ID_APP_ABOUT
и ID_APP_EXIT
уже имеют обработчики CWinAppEx
.
Обходной путь, который не требует переопределения OnCmdMsg
, заключается в добавлении обработчика на уровне приложения или мейнфрейма. После этого панель инструментов остается активной и правильно находит путь к соответствующему обработчику диалога. Добавление простого обработчика void в CMainFrame
делает свое дело (пример кода ниже). Обработчик void не вызывается.
BOOL CMyDlg::OnInitDialog()
{
...
m_ToolBar.InsertButton( CMFCToolBarButton( **ID_DLG_COMMAND**, -1, _T("DlgCommand") ) );
...
}
//CMainFrame
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWndEx)
...
ON_COMMAND(**ID_DLG_COMMAND**, VoidHandler)
END_MESSAGE_MAP()
void CMainFrame::VoidHandler()
{
assert(0);
}
Если вам нужно иметь дело только с диалоговыми командами, хитрость заключается в том, чтобы установить для SetRouteCommandsViaFrame значение FALSE. Тогда владелец (обычно диалог) будет использоваться для команд вместо основного фрейма.