Introduction
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.
The
Source Files
The Header file
Collapse
Copy Code
#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
#endif
class CMenuEdit : public CEdit
{
public:
CMenuEdit() {};
protected:
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
DECLARE_MESSAGE_MAP()
};
#endif
The Source file
Collapse
Copy Code
#include "stdafx.h"
#include "MenuEdit.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#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
BEGIN_MESSAGE_MAP(CMenuEdit, CEdit)
ON_WM_CONTEXTMENU()
END_MESSAGE_MAP()
void CMenuEdit::OnContextMenu(CWnd* pWnd, CPoint point)
{
SetFocus();
CMenu menu;
menu.CreatePopupMenu();
BOOL bReadOnly = GetStyle() & ES_READONLY;
DWORD flags = CanUndo() && !bReadOnly ? 0 : MF_GRAYED;
menu.InsertMenu(0, MF_BYPOSITION | flags, EM_UNDO,
MES_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,
MES_COPY);
flags = (flags == MF_GRAYED || bReadOnly) ? MF_GRAYED : 0;
menu.InsertMenu(2, MF_BYPOSITION | flags, WM_CUT,
MES_CUT);
menu.InsertMenu(4, MF_BYPOSITION | flags, WM_CLEAR,
MES_DELETE);
flags = IsClipboardFormatAvailable(CF_TEXT) &&
!bReadOnly ? 0 : MF_GRAYED;
menu.InsertMenu(4, MF_BYPOSITION | flags, WM_PASTE,
MES_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,
MES_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);
default:
return CEdit::OnCommand(wParam, lParam);
}
}