• 关于如何为FormView中的Richedit/Edit添加右键菜单,并响应CTRL+C等快捷键


    反复碰到这个问题,查资料很困难,索性整理一下放在这里,供朋友们借鉴。  
    faq-it.org/apache/===========================================================================  
    微软很恶心,竟然无法很方便的为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  
     
     
    ---------------------------------------------------------------  
    楼上的也仅仅是支持右键菜单的响应,补充,如何响应快捷键,把消息往下传递:  
     
    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);  
    }  
     
    上面所有的代码,只能对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);  
    }  
     
  • 相关阅读:
    php增加自动刷新当前页面
    liunx环境下安装mysql5.7及以上版本
    mysql的主从级联复制的配置
    windowns常用命令
    liunx之使用(mount)挂载技术
    在burpsuite中为什么不能选中设置好的代理?
    c++中向任意目录下写文件
    Hbase——JavaAPI操作笔记
    每周总结(6)(补)
    每周总结(5)
  • 原文地址:https://www.cnblogs.com/cy163/p/533057.html
Copyright © 2020-2023  润新知