Click here to Skip to main content
12,823,439 members (46,451 online)
Click here to Skip to main content
Add your own
alternative version


49 bookmarked
Posted 12 Apr 2001

How to modify a CEdit context menu

, 16 Sep 2001 CPOL
Rate this:
Please Sign up or sign in to vote.
A simple way to let your CEdit derived class have a modifiable context menu


Have you ever wanted to modify the context menu of an edit control? You would start by overriding the OnInitMenuPopup() function only to find that the edit control does not post a WM_INITMENUPOPUP message, so your function is never called. Well, here is a simple CEdit derived class that you can use.

The CMenuEdit class

The CMenuEdit class does its job with just two functions, OnContextMenu() and OnCommand().

The OnContextMenu() function gets called when a user right-clicks on the edit control. In our override, we create a new popup menu that exactly duplicates the default context menu, and we call TrackPopupMenu() on that menu. By doing this, a WM_INITMENUPOPUP message is posted, which can then be handled in a class derived from CMenuEdit.

The OnCommand() function handles commands generated when a user selects an item from the menu. If the command is not generated by our menu, it is passed onto CEdit::OnCommand().

You can either derive your edit class from CMenuEdit or include these two functions in your class.


September 17, 2001 - Now handles read-only edit controls

The Source Files

The Header file

// MenuEdit.h : header file
// Written by PJ Arends

#if !defined(AFX_MENUEDIT_H__8EA53611_FD2B_11D4_B625_D04FA07D2222__INCLUDED_)
#define AFX_MENUEDIT_H__8EA53611_FD2B_11D4_B625_D04FA07D2222__INCLUDED_

#if _MSC_VER > 1000
#pragma once

class CMenuEdit : public CEdit
    CMenuEdit() {};

    virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
    afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);



The Source file

// MenuEdit.cpp : implementation file
// Written by PJ Arends

#include "stdafx.h"
#include "MenuEdit.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;

#define MES_UNDO        _T("&Undo")
#define MES_CUT         _T("Cu&t")
#define MES_COPY        _T("&Copy")
#define MES_PASTE       _T("&Paste")
#define MES_DELETE      _T("&Delete")
#define MES_SELECTALL   _T("Select &All")
#define ME_SELECTALL    WM_USER + 0x7000


void CMenuEdit::OnContextMenu(CWnd* pWnd, CPoint point)
    CMenu menu;
    BOOL bReadOnly = GetStyle() & ES_READONLY;
    DWORD flags = CanUndo() && !bReadOnly ? 0 : MF_GRAYED;
    menu.InsertMenu(0, MF_BYPOSITION | flags, EM_UNDO,

    menu.InsertMenu(1, MF_BYPOSITION | MF_SEPARATOR);

    DWORD sel = GetSel();
    flags = LOWORD(sel) == HIWORD(sel) ? MF_GRAYED : 0;
    menu.InsertMenu(2, MF_BYPOSITION | flags, WM_COPY,

    flags = (flags == MF_GRAYED || bReadOnly) ? MF_GRAYED : 0;
    menu.InsertMenu(2, MF_BYPOSITION | flags, WM_CUT,
    menu.InsertMenu(4, MF_BYPOSITION | flags, WM_CLEAR,

    flags = IsClipboardFormatAvailable(CF_TEXT) &&
        !bReadOnly ? 0 : MF_GRAYED;
    menu.InsertMenu(4, MF_BYPOSITION | flags, WM_PASTE,

    menu.InsertMenu(6, MF_BYPOSITION | MF_SEPARATOR);

    int len = GetWindowTextLength();
    flags = (!len || (LOWORD(sel) == 0 && HIWORD(sel) ==
        len)) ? MF_GRAYED : 0;
    menu.InsertMenu(7, MF_BYPOSITION | flags, ME_SELECTALL,

    menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON |
        TPM_RIGHTBUTTON, point.x, point.y, this);

BOOL CMenuEdit::OnCommand(WPARAM wParam, LPARAM lParam)
    switch (LOWORD(wParam))
    case EM_UNDO:
    case WM_CUT:
    case WM_COPY:
    case WM_CLEAR:
    case WM_PASTE:
        return SendMessage(LOWORD(wParam));
    case ME_SELECTALL:
        return SendMessage (EM_SETSEL, 0, -1);
        return CEdit::OnCommand(wParam, lParam);


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

PJ Arends
Canada Canada
No Biography provided

You may also be interested in...

Comments and Discussions

GeneralRe: Way to avoid overriding OnCommand Pin
Crnjan22-Oct-04 3:30
memberCrnjan22-Oct-04 3:30 
GeneralRe: Way to avoid overriding OnCommand Pin
Paul S. Vickery22-Oct-04 3:52
memberPaul S. Vickery22-Oct-04 3:52 
GeneralThere are some bits missing Pin
Paul S. Vickery9-Aug-02 1:28
memberPaul S. Vickery9-Aug-02 1:28 
GeneralRe: There are some bits missing Pin
PJ Arends9-Aug-02 6:47
memberPJ Arends9-Aug-02 6:47 
GeneralRe: There are some bits missing Pin
Paul S. Vickery9-Aug-02 7:06
memberPaul S. Vickery9-Aug-02 7:06 
QuestionQuestion? Pin
Dejan Petrovic27-Sep-01 20:44
memberDejan Petrovic27-Sep-01 20:44 
AnswerRe: Question? Pin
PJ Arends28-Sep-01 7:08
memberPJ Arends28-Sep-01 7:08 
GeneralRe: Question? Pin
zsh21-Oct-08 5:10
memberzsh21-Oct-08 5:10 
You can get the menu context handle with the WM_ENTERIDLE message like that:

void CMenuEdit::OnEnterIdle(UINT nWhy, CWnd* pWho) 
    CEdit::OnEnterIdle(nWhy, pWho);
    if (nWhy == MSGF_MENU)
        MENUBARINFO mbi;

        memset(&mbi, 0, sizeof(MENUBARINFO));
        mbi.cbSize = sizeof(MENUBARINFO);
        GetMenuBarInfo(pWho->m_hWnd, OBJID_CLIENT, 0, &mbi);
        if (GetMenuState(mbi.hMenu, 1001, MF_BYCOMMAND) == -1)
            AppendMenu(mbi.hMenu, MF_STRING, 1001, "New item");

GeneralRe: Question? Pin
llothar2-Jul-10 23:53
memberllothar2-Jul-10 23:53 
QuestionHow to use this if I create dialog with ClassWizard? Pin
Gordy29-May-01 20:47
memberGordy29-May-01 20:47 
AnswerRe: How to use this if I create dialog with ClassWizard? Pin
James R. Twine13-Sep-01 21:08
memberJames R. Twine13-Sep-01 21:08 
Generalcouldn't read it Pin
Anonymous16-Apr-01 22:15
memberAnonymous16-Apr-01 22:15 
Generalin different windows basic menu looks different :-( Pin
Yury Goltsman15-Apr-01 5:47
memberYury Goltsman15-Apr-01 5:47 
GeneralRe: in different windows basic menu looks different :-( Pin
PJ Arends15-Apr-01 8:29
memberPJ Arends15-Apr-01 8:29 
GeneralRe: in different windows basic menu looks different :-( Pin
Anonymous29-Apr-04 7:44
sussAnonymous29-Apr-04 7:44 
GeneralRe: in different windows basic menu looks different :-( Pin
PJ Arends29-Apr-04 9:53
memberPJ Arends29-Apr-04 9:53 

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

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

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170308.1 | Last Updated 17 Sep 2001
Article Copyright 2001 by PJ Arends
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid