Click here to Skip to main content
11,705,473 members (62,698 online)
Click here to Skip to main content

CRichEditCtrl and a popup menu

, 15 Feb 2002 181.4K 2.4K 46
Rate this:
Please Sign up or sign in to vote.
Providing a popup menu for the CRichEditCtrl
<!-- Download Links --> <!-- Add the rest of your HTML here -->

Introduction

Welcome Gentle reader. The purpose of this article is to demonstrate the method with which to display a popup menu from a CRicheditCtrl after the user has right clicked the mouse, but first a little history

Yea verily...in the beginning there was the magic of Windows 3.1 and lo it was good(ish). And so it came to pass that years went by seemingly without incident but lo behind the scenes hoards of Microsoft(tm) minions worked feverishly for an on time release of new magic...Windows 95.

As part of the common controls to extend the much revered CEdit class, CRicheditCtrl was introduced. And CEdit class had some good magic for when you right clicked on it, a wee context menu popped up so one could cut, paste and so on. Programmers looked on this and saw it was good (ish). But alas CRicheditCtrl had no direct method for displaying a context menu...and so it is not good, it is in fact a darn pain!

So gentle reader I thought it was about time to provide a quick article on how to display a context menu from a CRicheditCtrl after a right click of the mouse.

Alas though there seemed to be a hitch dear reader as, for reasons best known to themselves, MS decided it wasn't going to make it totally easy (i.e. a simple override) to catch the WM_RBUTTONDOWN event from a CRichEditCtrl. They chose instead to make it a a bit more complicated (and I'm sure there's a very good reason which I just haven't researched.)

To begin with create a simple dialog based application, we'll call ours PopupDemo. Add a menu resource ( let's call ours IDR_MENU1) also, in the main dialog add a CRichEditCtrl member, m_RichEdit with IDC_RICHEDIT. Don't Forget to add

AfxInitRichEdit();

in the application's Initinstance or the application will not work...

Next, use the class wizard to generate an OnInitDialog member function for PopupDemoDlg. Inside this put the following

BOOL CPopupDemoDlg::OnInitDialog() 
{ 
   m_RichEdit.SetEventMask(ENM_MOUSEEVENTS);
...

This tells the RichEditCtrl that we want all mouse events reflected to the main window. We do this so we can catch them in a WM_NOTIFY handler.

To catch these mouse events which are being reflected to CPopupDemoDlg, we need to trap the event on OnNotify to do this...

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;
//

instead of the usual;

//
NMHDR * pnmh = (LPNMHDR)lParam;
//

Then we examine the result and test for which actual windows message and which window we're dealing with.

if ((wParam == IDC_RICHEDIT) && (lpMsgFilter->nmhdr.code == EN_MSGFILTER)
    & (lpMsgFilter->msg == WM_RBUTTONDOWN))
So the final OnNotify handler looks something like...
BOOL CPopupDemoDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) 
{
MSGFILTER * lpMsgFilter = (MSGFILTER *)lParam; 
if ((wParam == IDC_RICHEDIT) && (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 :) 
     DWORD dwSelectionMade;                                       
     VERIFY(menu.LoadMenu(IDR_MENU1) );  
     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(); 
     // Exercise for the reader...deal with the user's choice here :)                                      
     }
 return CDialog::OnNotify(wParam, lParam, pResult);
}

However... dear reader - there is a sneaker, faster way to code a method for dealing with the same event. Just override PreTranslateMessage(MSG* pMsg) (again use the class wizard). Do something similar to the following (this is not in the download files)

//
BOOL CPopupDemoDlg::PreTranslateMessage(MSG* pMsg)
{ 
    if (pMsg->message ==WM_RBUTTONDOWN)
    {
        CWnd * pWnd = (CWnd*) GetDlgItem(IDC_RICHEDIT); 
        if (pWnd ==GetFocus())
        {
              CMenu menu;
              DWORD dwSelectionMade; VERIFY(menu.LoadMenu(IDR_MENU1));
              CMenu *pmenuPopup = menu.GetSubMenu(0);
              ASSERT(pmenuPopup != NULL);                                    
              dwSelectionMade = pmenuPopup->TrackPopupMenu( (TPM_LEFTALIGN|
                                                                TPM_LEFTBUTTON|
                                                                TPM_NONOTIFY|
                                                                TPM_RETURNCMD),
                                                                 pMsg->pt.x, 
                                                                 pMsg->pt.y, this
                                                          );  
              pmenuPopup->DestroyMenu();
             //excercise for the reader...deal with the selection the user has made here
             return TRUE;
               }
    }
    return CDialog::PreTranslateMessage(pMsg);
}
//

Yea - though there are probably other ways of doing this these, gentle reader, are what I have found to be two of the easiest ways of achieving the aim. And lo, it is good.

Here-in ends the lesson.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

bryce
Software Developer (Senior)
Australia Australia
No Biography provided

You may also be interested in...

Comments and Discussions

 
QuestionMy Vote of 1 Pin
llothar15-Nov-12 11:25
memberllothar15-Nov-12 11:25 
AnswerRe: My Vote of 1 Pin
bryce15-Nov-12 11:29
memberbryce15-Nov-12 11:29 
QuestionVoted for 5 Pin
k77725-Aug-11 12:07
memberk77725-Aug-11 12:07 
Generalthank you! Pin
amabelleq4-Dec-09 20:07
memberamabelleq4-Dec-09 20:07 
GeneralRe: thank you! Pin
bryce5-Dec-09 0:56
memberbryce5-Dec-09 0:56 
GeneralErrors during compilation Pin
martyix30-Mar-09 5:35
membermartyix30-Mar-09 5:35 
GeneralA serious error in release executable file Pin
chocm15-Oct-07 2:58
memberchocm15-Oct-07 2:58 
QuestionWhy not ON_COMMAND? Pin
chocm3-Aug-07 0:49
memberchocm3-Aug-07 0:49 
AnswerRe: Why not ON_COMMAND? Pin
KarstenK3-Aug-07 1:33
memberKarstenK3-Aug-07 1:33 
check out to what these macros are expanded. You got to understand it carefully.Suspicious | :suss:

Greetings from Germany

GeneralRe: Why not ON_COMMAND? Pin
chocm9-Aug-07 23:55
memberchocm9-Aug-07 23:55 
Generalanother implementation Pin
Marc Hoesen7-Dec-05 3:29
memberMarc Hoesen7-Dec-05 3:29 
GeneralRe: another implementation Pin
Marc Hoesen7-Dec-05 3:32
memberMarc Hoesen7-Dec-05 3:32 
GeneralInsert a control in a popup menu. Pin
Negrume4-Nov-04 6:12
memberNegrume4-Nov-04 6:12 
GeneralRe: WM_CONTEXTMENU instead of WM_RBUTTONUP Pin
Anonymous20-May-04 11:00
sussAnonymous20-May-04 11:00 
GeneralRe: WM_CONTEXTMENU instead of WM_RBUTTONUP Pin
hoiby31-Aug-04 8:03
memberhoiby31-Aug-04 8:03 
GeneralCommand Handlers Pin
billgower29-Oct-03 14:20
memberbillgower29-Oct-03 14:20 
GeneralAuto detect if control is rich edit - also C version of the code Pin
R. Walker2-Sep-03 14:54
memberR. Walker2-Sep-03 14:54 
QuestionHow do use CRichEditCtrl without MFC? Pin
Anonymous4-Jul-03 16:57
sussAnonymous4-Jul-03 16:57 
AnswerRe: CRichEditCtrl without MFC? Pin
billgatest25-Aug-03 19:19
memberbillgatest25-Aug-03 19:19 
GeneralProblem with Getting the WM_COMMAND msgs - fixed Pin
MetX15-May-03 18:37
memberMetX15-May-03 18:37 
GeneralOnNotify is more reliable Pin
Anonymous14-May-03 8:41
sussAnonymous14-May-03 8:41 
GeneralWM_CONTEXTMENU instead of WM_RBUTTONUP Pin
danmorin19-Mar-03 10:16
memberdanmorin19-Mar-03 10:16 
GeneralRe: WM_CONTEXTMENU instead of WM_RBUTTONUP Pin
Anonymous20-May-04 5:40
sussAnonymous20-May-04 5:40 
GeneralRe: WM_CONTEXTMENU instead of WM_RBUTTONUP Pin
danmorin20-May-04 6:26
memberdanmorin20-May-04 6:26 
GeneralShow or hide formatting marks Pin
wang200228-Feb-03 4:28
memberwang200228-Feb-03 4:28 
GeneralGreat article! Pin
V Jai5-Dec-02 11:03
memberV Jai5-Dec-02 11:03 
GeneralRe: Great article! Pin
bryce5-Dec-02 11:57
memberbryce5-Dec-02 11:57 
GeneralThanks. Pin
Anonymous25-Oct-02 20:46
sussAnonymous25-Oct-02 20:46 
GeneralProblem in mode Release Pin
Mr. Black13-May-02 23:26
memberMr. Black13-May-02 23:26 
GeneralRe: Problem in mode Release Pin
Anonymous5-Sep-02 19:41
sussAnonymous5-Sep-02 19:41 
GeneralIRichEditOleCallback::GetContextMenu Pin
Carl Berg16-Feb-02 14:54
memberCarl Berg16-Feb-02 14:54 
GeneralRe: IRichEditOleCallback::GetContextMenu Pin
bryce16-Feb-02 17:55
memberbryce16-Feb-02 17:55 
GeneralRe: IRichEditOleCallback::GetContextMenu Pin
Carl Berg18-Feb-02 5:06
memberCarl Berg18-Feb-02 5:06 
GeneralRe: IRichEditOleCallback::GetContextMenu Pin
dreamsfly11-Apr-02 2:39
memberdreamsfly11-Apr-02 2:39 
GeneralRe: IRichEditOleCallback::GetContextMenu Pin
Anonymous25-Feb-03 9:46
sussAnonymous25-Feb-03 9:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150819.1 | Last Updated 16 Feb 2002
Article Copyright 2002 by bryce
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid