MFC:如何在 CTabView 选项卡中为 CRichEditView 实现上下文菜单?
MFC: How do you implement a context menu for CRichEditView in a CTabView tab?
我有一个 CTabView
,其中一个选项卡是 CRichEditView
。富文本被添加到控件并显示正常。如果我 select CRichEditView
中的文本,工具栏编辑项工作正常(例如,复制突出显示,如果我单击它,它会复制到剪贴板)。但是,我发现如果我 select 编辑文本并右键单击,则不会像 CEditView
那样带有 CRichEditView
的上下文菜单。在互联网上搜索,我找到了 CRichEditView::GetContextMenu()
的实现来尝试使用。它首先有一个断言失败,因为 CDocument
不是富文本类型,所以为了测试,我删除了它(在下面注释掉)并得到以下结果:
HMENU CMyRichView::GetContextMenu(WORD seltyp, LPOLEOBJECT lpoleobj, CHARRANGE* lpchrg)
{
// TODO: Add your specialized code here and/or call the base class
/*
CRichEditCntrItem* pItem = GetSelectedItem();
if (pItem == NULL || !pItem->IsInPlaceActive())*/
{
CMenu menuText;
menuText.LoadMenu(IDR_CONTEXT_EDIT_MENU);
CMenu* pMenuPopup = menuText.GetSubMenu(0);
menuText.RemoveMenu(0, MF_BYPOSITION);
return pMenuPopup->Detach();
}
}
其中 IDR_CONTEXT_EDIT_MENU
是:
IDR_CONTEXT_EDIT_MENU MENU
BEGIN
POPUP "edit"
BEGIN
MENUITEM "&Copy\tCtrl+C", ID_EDIT_COPY
END
END
现在,当我右键单击时,我会看到上下文菜单。但是,当我选择 "copy" 时,没有任何反应。所以我映射了 ID_EDIT_COPY
这样我就可以设置一个断点来查看它是否被调用了。
void CMyRichView::OnEditCopy()
{
// TODO: Add your command handler code here
ASSERT_VALID(this);
GetRichEditCtrl().Copy();
}
不是使用上下文项,而是使用工具栏。
我错过了什么和做错了什么?
TIA!!
如果消息发送到 CTabView
,则添加 CTabView::OnEditCopy
处理程序。
否则,您可以覆盖 PreTranslateMessage
,如下所示,这将确保消息发送到 CMyRichEditView::OnEditCopy
。
BOOL CMyRichEditView::PreTranslateMessage(MSG *msg)
{
if(msg->message == WM_CONTEXTMENU || msg->message == WM_RBUTTONDOWN)
{
CMenu menu;
menu.LoadMenu(IDR_CONTEXT_EDIT_MENU);
int c = menu.GetMenuItemCount();
CMenu* popup = menu.GetSubMenu(0);
popup->TrackPopupMenu(0, msg->pt.x, msg->pt.y, this, NULL);
return TRUE;
}
return CRichEditView::PreTranslateMessage(msg);
}
我有一个 CTabView
,其中一个选项卡是 CRichEditView
。富文本被添加到控件并显示正常。如果我 select CRichEditView
中的文本,工具栏编辑项工作正常(例如,复制突出显示,如果我单击它,它会复制到剪贴板)。但是,我发现如果我 select 编辑文本并右键单击,则不会像 CEditView
那样带有 CRichEditView
的上下文菜单。在互联网上搜索,我找到了 CRichEditView::GetContextMenu()
的实现来尝试使用。它首先有一个断言失败,因为 CDocument
不是富文本类型,所以为了测试,我删除了它(在下面注释掉)并得到以下结果:
HMENU CMyRichView::GetContextMenu(WORD seltyp, LPOLEOBJECT lpoleobj, CHARRANGE* lpchrg)
{
// TODO: Add your specialized code here and/or call the base class
/*
CRichEditCntrItem* pItem = GetSelectedItem();
if (pItem == NULL || !pItem->IsInPlaceActive())*/
{
CMenu menuText;
menuText.LoadMenu(IDR_CONTEXT_EDIT_MENU);
CMenu* pMenuPopup = menuText.GetSubMenu(0);
menuText.RemoveMenu(0, MF_BYPOSITION);
return pMenuPopup->Detach();
}
}
其中 IDR_CONTEXT_EDIT_MENU
是:
IDR_CONTEXT_EDIT_MENU MENU
BEGIN
POPUP "edit"
BEGIN
MENUITEM "&Copy\tCtrl+C", ID_EDIT_COPY
END
END
现在,当我右键单击时,我会看到上下文菜单。但是,当我选择 "copy" 时,没有任何反应。所以我映射了 ID_EDIT_COPY
这样我就可以设置一个断点来查看它是否被调用了。
void CMyRichView::OnEditCopy()
{
// TODO: Add your command handler code here
ASSERT_VALID(this);
GetRichEditCtrl().Copy();
}
不是使用上下文项,而是使用工具栏。
我错过了什么和做错了什么?
TIA!!
如果消息发送到 CTabView
,则添加 CTabView::OnEditCopy
处理程序。
否则,您可以覆盖 PreTranslateMessage
,如下所示,这将确保消息发送到 CMyRichEditView::OnEditCopy
。
BOOL CMyRichEditView::PreTranslateMessage(MSG *msg)
{
if(msg->message == WM_CONTEXTMENU || msg->message == WM_RBUTTONDOWN)
{
CMenu menu;
menu.LoadMenu(IDR_CONTEXT_EDIT_MENU);
int c = menu.GetMenuItemCount();
CMenu* popup = menu.GetSubMenu(0);
popup->TrackPopupMenu(0, msg->pt.x, msg->pt.y, this, NULL);
return TRUE;
}
return CRichEditView::PreTranslateMessage(msg);
}