MFC 在RichEdit里创建右键菜单

一、简介

最近做了一个程序,里面的RichEdit控件需要添加一个右键菜单,包括复制、粘贴等功能。但MFC自带的RichEdit没有右键菜单,而且无法使用主对话框的WM_RBUTTONUP消息(在控件内右击不会发送给父窗口),我又不想派生一个类。经过查阅资料和自己摸索,我发现RichEdit也给了一个接口,那就是EN_MSGFILTER事件。
EN_MSGFILTER事件
vs上的说明很清楚,允许筛选控件中的鼠标和键盘消息,也就是说,控件接收到鼠标和键盘消息后,会通知父窗口,我们创建一个响应函数。VS自动生成的代码如下:

MSGFILTER* pMsgFilter = reinterpret_cast<MSGFILTER*>(pNMHDR);
	// TODO:  控件将不发送此通知,除非您重写
	// CDialogEx::OnInitDialog() 函数,以将 EM_SETEVENTMASK 消息发送
	// 到该控件,同时将 ENM_KEYEVENTS 或 ENM_MOUSEEVENTS 标志
	//“或”运算到 lParam 掩码中。

	// TODO:  在此添加控件通知处理程序代码

	*pResult = 0;

这里要注意里面的注释,提示我们要在OnInitDialog中添加代码发送消息。代码如下:

	m_RichEdit.SetEventMask(m_RichEdit.GetEventMask() | ENM_MOUSEEVENTS);

这样,我们就可以在OnEnMsgfilterText函数里创建菜单了。代码如下:

void CXXXDlg::OnEnMsgfilterText(NMHDR* pNMHDR, LRESULT* pResult)
{
    
    
	MSGFILTER* pMsgFilter = reinterpret_cast<MSGFILTER*>(pNMHDR);
	// TODO:  控件将不发送此通知,除非您重写
	// CDialogEx::OnInitDialog() 函数,以将 EM_SETEVENTMASK 消息发送
	// 到该控件,同时将 ENM_KEYEVENTS 或 ENM_MOUSEEVENTS 标志
	//“或”运算到 lParam 掩码中。

	if (pMsgFilter->msg == WM_RBUTTONUP)
	{
    
    
		CPoint point(LOWORD(pMsgFilter->lParam), HIWORD(pMsgFilter->lParam));
		ClientToScreen(&point);
		CMenu popMenu;
		popMenu.LoadMenu(IDR_MENU2);
		CMenu* pPopup;
		pPopup = popMenu.GetSubMenu(0);
		pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
		pPopup->Detach();
		popMenu.DestroyMenu();
	}
	*pResult = 0;
}

这个函数第一个参数的具体说明,可以点击此处查看,也谢谢这位博主的分享。
VS自动生成的代码中有一句MSGFILTER* pMsgFilter = reinterpret_cast<MSGFILTER*>(pNMHDR);无非是告诉我们用这个结构体指针。其中最重要的成员是msg,它就是控件发送给父窗口收到的消息。如果收到右键松开的消息,就可以创建菜单了。创建菜单的方法请大家自行搜索。

三、程序截图

程序截图

猜你喜欢

转载自blog.csdn.net/qq_54121864/article/details/114034832
今日推荐