当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 定制编辑框的上下文菜单

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

VC++ 中的 定制编辑框的上下文菜单


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 82 ::
收藏到网摘: n/a

定制编辑框的上下文菜单

文/赵湘宁

本文例子代码
    上下文菜单的应用在基于Windows的应用程序中使用得越来越广泛。本文针对WM_INITMENUPOPUP消息的处理机制谈谈如何在编辑框控制的上下文菜单上添加自己的菜单项。
    刚开始的时候常常碰到一个问题,就是在编辑框上单击鼠标右键时,程序并不产生WM_INITMENUPOPUP消息,原因我也说不清楚,也没有找到说明这个问题的具体文档资料。每当我子类化编辑框控制向标准的上下文菜单添加自己的菜单项时(如图二),

      图二

总是要碰到上面这样的问题。那么到底该如何使用WM_INITMENUPOPUP处理机制实现自己的上下文菜单呢?
    通常的方法是为编辑框控制实现WM_INITMENUPOPUP的消息处理,但前面说过,编辑框控制不发送WM_INITMENUPOPUP。编辑控制一定是以空的HWND句柄或者TPM_NONOTIFY调用TrackPopupMenu,TPM_NONOTIFY的作用是要菜单不发送通知。也有可能——只是猜测——Windows(r)通过降低消息的通行量来改善性能。很难再回忆起当年Windows1.0和 Windows 2.0 运行在640kb/8MHZ的机器上的情形!(那时候编辑框控制有上下文菜单吗?谁还记得?)。
    不管怎么说,如果想要添加自己的菜单项到编辑框控制的上下文菜单。如何做呢?唉,是不是除了自己发明外就别无选择了呢?天无绝人之路,本文将为你提供一个小类:CEitMenuHandler,有了它的话,一切都搞掂。你只要使用它就行了。为了显示这个类的用法,我用以前的一个例子程序,将其中的编译框控制修改了一下,在它的上下文菜单中写进了三种文件类型的菜单项,见图三。

      图三

    使用CeitMenuHandler类有三件事情要做(如果要把设计菜单本身算在内的话,那就有四件事情要做):


第一,实例化处理器。
class CMyEdit : public CEdit {
protected:
CEditMenuHandler m_editMenuHandler;
virtual void PreSubclassWindow();
};

第二,必须安装第一部创建的处理器。你可以在OnCreate做,但如果编辑框控制是在对话框中,则在PreSubclassWindow中安装,因为你不是正常地创建对话框控制:而是要进行子类化工作。安装完处理器,还得传递一个上下文菜单的ID:
void CMyEdit::PreSubclassWindow()
{
//IDR EDITMENU 是我的上下文菜单
m_editMenuHandler.Install(this, IDR_EDITMENU);
}

    到了这一步,处理器已经安装并且已经准备就绪,只需要调用两个函数。OnUpdateEditCommand 更新菜单项;OnEditCommand 处理命令。

// CMyEdit 消息映射
ON_COMMAND_RANGE(ID_EDIT_FIRST, 
ID_EDIT_LAST, OnEditCommand)
ON_UPDATE_COMMAND_UI_RANGE(ID_EDIT_FIRST,
ID_EDIT_LAST, OnUpdateEditCommand)

void CMyEdit::OnUpdateEditCommand(CCmdUI* pCmdUI)
{
m_editMenuHandler.OnUpdateEditCommand(pCmdUI));
}
void CMyEdit::OnEditCommand(UINT nID)
{
m_editMenuHandler.OnEditCommand(nID);
}

    CEitMenuHandler把什么事情都做了,处理剪切、复制、粘贴和其它操作。根据是文档选中还是剪切板有内容等来使能或置灰(enables/disables)相应的菜单项。如果命令被处理,处理器函数返回TRUE;否则返回FALSE,如果你愿意,你可以处理其它编辑命令。例如,CMyEdit有单独的处理器处理TXT,BMP和JPG命令。

// CMyEdit中的消息映射
ON_COMMAND(ID_FILETYPE_TXT, OnFiletypeTXT)
void CMyEdit::OnFiletypeTXT()
{
SetWindowText(_T("txt"));
SetSel(0,-1);
}

    CMyEdit将编辑命令传给CEitMenuHandler并自己处理剩下的事情。更新菜单项时也一样。一切都进行得很顺利。
    其实,CEitMenuHandler的实现是有相当多的事情要做的