如何正确发送 CMFCMenuButton 选择的 ID 到消息映射?
how to correctly send CMFCMenuButton selected ID to the message map?
首先让我描述一下我有什么:
场景: CMFCMenuButton
,加载一个 CMenu
,在对话框中
测试: 点击一个菜单项
结果: 消息映射将获得 CMFCMenuButton
的 ID 而不是菜单的 ID
如何获取实际点击的菜单ID:使用CMFCMenuButton::m_nMenuResult
思路是我要有菜单项和此对话框中的按钮,并且会有与菜单项共享 ID 的按钮。
因此,在我为菜单按钮创建的处理程序中,我可以获得 m_nMenuResult
并将其发送到对话框或做任何我想做的事,但这似乎不是 CMFCMenuButton
应该如何工作的。正确的做法是什么?
代码
下面是一个关于如何重现此代码的示例。
我也将 ON_COMMAND_RANGE
与 IDC_MFCMENUBUTTON1
一起使用,只是为了重用 OnMenu 函数的代码
void CRepositionDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_MFCMENUBUTTON1, m_cmfcMenuButton);
}
BEGIN_MESSAGE_MAP(CRepositionDlg, CDialog)
ON_COMMAND_RANGE(IDC_MFCMENUBUTTON1,IDC_MFCMENUBUTTON1,OnMenu)
ON_COMMAND_RANGE(IDC_MENU1, IDC_MENU11, OnMenu)
END_MESSAGE_MAP()
// CRepositionDlg message handlers
afx_msg void CRepositionDlg::OnMenu(UINT nID)
{
CString csMessage;
csMessage.Format(L"OnMenu(%d)",nID);
AfxMessageBox(csMessage);
if(nID == IDC_MFCMENUBUTTON1)
{
OnMenu(m_cmfcMenuButton.m_nMenuResult);
}
}
BOOL CRepositionDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
CMenu* pMenu = new CMenu;
pMenu->CreatePopupMenu();
for(int i = IDC_MENU1; i <= IDC_MENU11; i++)
{
CString csMenu;
csMenu.Format(L"menu %d",i);
pMenu->AppendMenuW(MF_STRING,i,csMenu);
}
m_cmfcMenuButton.m_hMenu = pMenu->GetSafeHmenu();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
如果您为菜单按钮编写 BN_CLICKED 的处理程序,如果单击按钮,它将为 m_nMenuResult 响应 0,或者,m_nMenuResult 将包含所选菜单项的 ID。如果这不是您想要的,我认为您是在反对按钮的工作方式。您唯一的其他选择是创建您自己的 class 来表示菜单按钮并添加您想要的行为。
首先让我描述一下我有什么:
场景: CMFCMenuButton
,加载一个 CMenu
,在对话框中
测试: 点击一个菜单项
结果: 消息映射将获得 CMFCMenuButton
的 ID 而不是菜单的 ID
如何获取实际点击的菜单ID:使用CMFCMenuButton::m_nMenuResult
思路是我要有菜单项和此对话框中的按钮,并且会有与菜单项共享 ID 的按钮。
因此,在我为菜单按钮创建的处理程序中,我可以获得 m_nMenuResult
并将其发送到对话框或做任何我想做的事,但这似乎不是 CMFCMenuButton
应该如何工作的。正确的做法是什么?
代码
下面是一个关于如何重现此代码的示例。我也将
ON_COMMAND_RANGE
与 IDC_MFCMENUBUTTON1
一起使用,只是为了重用 OnMenu 函数的代码
void CRepositionDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_MFCMENUBUTTON1, m_cmfcMenuButton);
}
BEGIN_MESSAGE_MAP(CRepositionDlg, CDialog)
ON_COMMAND_RANGE(IDC_MFCMENUBUTTON1,IDC_MFCMENUBUTTON1,OnMenu)
ON_COMMAND_RANGE(IDC_MENU1, IDC_MENU11, OnMenu)
END_MESSAGE_MAP()
// CRepositionDlg message handlers
afx_msg void CRepositionDlg::OnMenu(UINT nID)
{
CString csMessage;
csMessage.Format(L"OnMenu(%d)",nID);
AfxMessageBox(csMessage);
if(nID == IDC_MFCMENUBUTTON1)
{
OnMenu(m_cmfcMenuButton.m_nMenuResult);
}
}
BOOL CRepositionDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
CMenu* pMenu = new CMenu;
pMenu->CreatePopupMenu();
for(int i = IDC_MENU1; i <= IDC_MENU11; i++)
{
CString csMenu;
csMenu.Format(L"menu %d",i);
pMenu->AppendMenuW(MF_STRING,i,csMenu);
}
m_cmfcMenuButton.m_hMenu = pMenu->GetSafeHmenu();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
如果您为菜单按钮编写 BN_CLICKED 的处理程序,如果单击按钮,它将为 m_nMenuResult 响应 0,或者,m_nMenuResult 将包含所选菜单项的 ID。如果这不是您想要的,我认为您是在反对按钮的工作方式。您唯一的其他选择是创建您自己的 class 来表示菜单按钮并添加您想要的行为。