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

VC++
关于win32 programming中的视口和窗口!
VC 下加载 JPG / JPEG / GIF / PNG 图片最简单的方法
个人VC串口通信经验及相关知识总结
VC++ 内存机理的个人理解:堆和栈
理解VC++里字符串类型的真正含义
VC++ 实现全屏
VC++ 6.0的小花招
VC++快捷键
VC中的一些调试技巧
由MessageBox透视Win API的调用
VC-文本框只能输入数字和小数 源文件
C 基础:C 类成员属性的一种简洁实现
vc中bool与BOOL的区别
C++和Java的区别
VC++6.0 下搭建 wxWidgets 开发环境
VC6做简易自动升级程序
VC++ 6.0的小花招
VC++程序调试
VC++ 捕捉摄像头视频
VC++的Unicode编程

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 69 ::
收藏到网摘: 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的实现是有相当多的事情要做的