Figure 4 CEditMenuHandler
EditMenu.h // MSDN — November 2000
// If this code works, it was written by Paul DiLascia.
// Compiles with Visual C++ 6.0, runs on Windows 98 and probably Windows NT
#include "menuinit.h"
// CEditMenuHandler duplicates the edit control context menu
// in a way that can be extended.
//
// To use it:
// - Call Install when your edit control is created/subclassed.
// - Call OnEditCommand to handle any command in the range
// ID_EDIT_FIRST to ID_EDIT_LAST.
// - Call OnUpdateEditCommand to handle any UPDATE_COMMAND_UI in the
// range ID_EDIT_FIRST to ID_EDIT_LAST.
//
class CEditMenuHandler : public CPopupMenuInitHandler {
public:
CEditMenuHandler();
~CEditMenuHandler();
BOOL Install(CWnd* pWnd, UINT nIDMenu);
void Remove() { Unhook(); }
// call these to handle/update cut, copy, paste etc.
virtual BOOL OnEditCommand(UINT nID);
virtual BOOL OnUpdateEditCommand(CCmdUI* pCmdUI);
protected:
UINT m_nIDMenu;
virtual LRESULT WindowProc(UINT msg, WPARAM wp, LPARAM lp);
virtual BOOL OnContextMenu(CPoint pt);
};
#define ID_EDIT_FIRST ID_EDIT_CLEAR
#define ID_EDIT_LAST ID_EDIT_REDO
EditMenu.cpp // MSDN — November 2000
// If this code works, it was written by Paul DiLascia.
// Compiles with Visual C++ 6.0, runs on Windows 98 and probably Windows NT
#include "StdAfx.h"
#include "EditMenu.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CEditMenuHandler::CEditMenuHandler()
{
}
CEditMenuHandler::~CEditMenuHandler()
{
}
// Install edit menu handler. You must supply a menu ID of a menu that
// has Cut, Copy, Paste, etc.
//
BOOL CEditMenuHandler::Install(CWnd* pWnd, UINT nIDMenu)
{
m_nIDMenu = nIDMenu;
return !HookWindow(pWnd);
}
// Generic menu item update: enable/disable standard menu items based
// on whether text is selected, something to paste, etc. You must call
// this to update the edit commands when you get an MFC
// ON_UPDATE_COMMAND_UI notification for an edit command.
//
BOOL CEditMenuHandler::OnUpdateEditCommand(CCmdUI* pCmdUI)
{
CEdit* pEditWnd = DYNAMIC_DOWNCAST(CEdit,CWnd::FromHandle(m_hWnd));
if (pEditWnd) {
UINT nID = pCmdUI->m_nID;
switch (nID) {
case ID_EDIT_CUT:
case ID_EDIT_COPY:
case ID_EDIT_CLEAR:
int beg,end;
pEditWnd->GetSel(beg,end);
pCmdUI->Enable(beg<end);
return TRUE;
case ID_EDIT_UNDO:
pCmdUI->Enable(pEditWnd->CanUndo());
return TRUE;
case ID_EDIT_PASTE:
pCmdUI->Enable(::IsClipboardFormatAvailable(CF_TEXT));
return TRUE;
case ID_EDIT_SELECT_ALL:
pCmdUI->Enable(pEditWnd->GetWindowTextLength()>0);
return TRUE;
}
}
return FALSE; // not handled
}
// Handle standard edit command: perform cut, copy, paste, etc. You
// must call when you get an edit command (ON_COMMAND notification).
//
BOOL CEditMenuHandler::OnEditCommand(UINT nID)
{
CEdit* pEditWnd = DYNAMIC_DOWNCAST(CEdit,CWnd::FromHandle(m_hWnd));
if (pEditWnd) {
switch (nID) {
case ID_EDIT_UNDO:
pEditWnd->Undo();
return TRUE;
case ID_EDIT_CUT:
pEditWnd->Cut();
return TRUE;
case ID_EDIT_COPY:
pEditWnd->Copy();
return TRUE;
case ID_EDIT_PASTE:
pEditWnd->Paste();
return TRUE;
case ID_EDIT_CLEAR:
pEditWnd->Clear();
return TRUE;
case ID_EDIT_SELECT_ALL:
pEditWnd->SetSel(0,-1);
return TRUE;
}
}
return FALSE; // not handled
}
// Internal WindowProc intercepts WM_CONTEXTMENU.
//
LRESULT CEditMenuHandler::WindowProc(UINT msg, WPARAM wp, LPARAM lp)
{
if (msg==WM_CONTEXTMENU) {
return OnContextMenu((CPoint)lp);
}
return CPopupMenuInitHandler::WindowProc(msg, wp, lp);
}
//////////////////
// Display context menu. Override to do something different.
//
BOOL CEditMenuHandler::OnContextMenu(CPoint pt)
{
CMenu editMenu;
VERIFY(editMenu.LoadMenu(m_nIDMenu));
CMenu* pSubMenu = editMenu.GetSubMenu(0);
pSubMenu->TrackPopupMenu(0,pt.x,pt.y,CWnd::FromHandle(m_hWnd));
return TRUE; // handled
}