关于如何为FormView中的Richedit添加右键菜单,并响应CTRL+C等快捷键 |
您所在的位置:网站首页 › python右键菜单 › 关于如何为FormView中的Richedit添加右键菜单,并响应CTRL+C等快捷键 |
反复碰到这个问题,查资料很困难,索性整理一下放在这里,供朋友们借鉴。
===========================================================================
微软很恶心,竟然无法很方便的为FormView或者Dialog上的RicheditCtrl添加右键菜单功能项.经过搜索资料和实际使用,需要用这样的方式才能实现:
注意事项 1.右键菜单中,不能出现系统命令,例如,ID_EDIT_UNDO/ID_EDIT_COPY/ID_EDIT_PASTE/ID_EDIT_CUT/ID_EDIT_SELALL等,否则,无法响应消息. 2.菜单项目,不能用OnCommand的方式进行消息处理,必须在Message Map中用ON_MESSAGE的方式,并且在头文件中实现定义好消息函数如OnMenuUndo. BEGIN_MESSAGE_MAP(CReferenceFormView, CFormView) //{{AFX_MSG_MAP(CReferenceFormView) ON_MESSAGE(ID_MENU_UNDO, OnMenuUndo) ON_MESSAGE(ID_MENU_CUT, OnMenuCut) ON_MESSAGE(ID_MENU_COPY, OnMenuCopy) ON_MESSAGE(ID_MENU_PASTE, OnMenuPaste) ON_MESSAGE(ID_MENU_CLEAR, OnMenuClear) ON_MESSAGE(ID_MENU_SELECT_ALL, OnMenuSelectAll) //}}AFX_MSG_MAP END_MESSAGE_MAP() 3.需要在FormView的OnInitialUpdate()函数或者Dialog的OnInitialDialog()函数中调用 m_ctrlRichEditReference.SetEventMask(ENM_MOUSEEVENTS); 表示RicheditCtrl的鼠标事件交由父窗体进行处理. 4.在父窗体(FormView或者Dialog)的OnNotify消息中做如下处理: BOOL CReferenceFormView::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) { // TODO: Add your specialized code here and/or call the base class 要点1: The RichEditCtrl sends the message "EN_MSGFILTER" to the parent, now to get at which message has been reflected (because it could be a left click or a mouse move) we need to examine the message filter, so we cast lParam to MSGFILTER * MSGFILTER * lpMsgFilter = (MSGFILTER *)lParam; 要点2: if ((wParam == IDC_RICHEDIT_REFERENCE) && (lpMsgFilter->nmhdr.code == EN_MSGFILTER) && (lpMsgFilter->msg == WM_RBUTTONDOWN)) { //if we get through here, we have trapped the right click event of the richeditctrl! CPoint point; ::GetCursorPos(&point); //where is the mouse? CMenu menu; //lets display out context menu :) UINT dwSelectionMade; VERIFY(menu.LoadMenu(IDR_MNU_REFERENCE4RE) ); CMenu *pmenuPopup = menu.GetSubMenu(0); ASSERT(pmenuPopup != NULL); dwSelectionMade = pmenuPopup->TrackPopupMenu( (TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_NONOTIFY|TPM_RETURNCMD), point.x, point.y, this ); pmenuPopup->DestroyMenu(); PostMessage(dwSelectionMade,0,0); } return CFormView::OnNotify(wParam, lParam, pResult); } 参考资料: http://lib.training.ru/Lib/ArticleDetail.aspx?ar=468&l=n&mi=17&mic=344 6 个解决方案 #1 SORRY!楼上的也仅仅是支持右键菜单的响应,不知道谁哪里有支持Ctr+C等快捷键的实现方法,请共享!!! #2 补充,如何响应快捷键,把消息往下传递: BOOL CFormViewRecordEditor::PreTranslateMessage(MSG* pMsg) { // TODO: Add your specialized code here and/or call the base class if ( pMsg->message == WM_KEYDOWN ) { switch( pMsg->wParam ) { case 0x41: //selete all case 0x46: //ctrl+f case 0x56: //Ctrl + V: case 0x58: // cut case 0x43: // copy case 0x5A: //undo case 0x59: //redo if ( ( GetKeyState( VK_CONTROL ) & 0x80 ) ) { m_ctlRichEditFullText.SendMessage(pMsg->message, pMsg->wParam, pMsg->lParam); return TRUE; } break; } }//End: if ( pMsg->message ); return CFormView::PreTranslateMessage(pMsg); } #3 花了几乎一天的时间,反复试验了好多种方法,才得到结果。 #4 Welcome #5 上面所有的代码,只能对Formview或者PropertyPage上的RicheditCtrl起到效果,对于出现在上述父窗体中的Edit,要想响应快捷键,则需要使用如下代码处理:BOOL CPPFieldEditNormal::PreTranslateMessage(MSG* pMsg) { // TODO: Add your specialized code here and/or call the base class if ( pMsg->message == WM_KEYDOWN ) { switch( pMsg->wParam ) { case 0x41: //selete all case 0x46: //ctrl+f case 0x56: //Ctrl + V: case 0x58: // cut case 0x43: // copy case 0x5A: //undo case 0x59: //redo if ( ( GetKeyState( VK_CONTROL ) & 0x80 ) && (m_ctlEditFieldValue.m_hWnd == GetFocus()->m_hWnd)) { //m_ctlEditFieldValue.SendMessage(pMsg->message, pMsg->wParam, pMsg->lParam);//这种方式不能正确响应 //::PostMessage(m_ctlEditFieldValue.m_hWnd, pMsg->message, pMsg->wParam, pMsg->lParam);//这种方式不能正确响应 //m_ctlEditFieldValue.SendMessage(WM_COMMAND,(WPARAM)ID_EDIT_PASTE,(LPARAM)0);//这种方式不能正确响应 ::PostMessage(m_ctlEditFieldValue.m_hWnd, WM_PASTE,(WPARAM)0,(LPARAM)0);//这种方式可以正确响应!! } return TRUE; } break; } }//End: if ( pMsg->message ); return CPropertyPage::PreTranslateMessage(pMsg); } #6 感谢楼主,非常有用!! |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |