如何定制对话框中的回车键

andand8

andand8

2016-01-29 11:50

如何定制对话框中的回车键,如何定制对话框中的回车键

如何定制对话框中的回车键

作者/赵湘宁

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/cyuyanjiaocheng/)
本文例子代码

    基于对话框的程序中,每次按下回车键时,程序都退出。去掉按钮的 BS_DEFPUSHBUTTON 属性并重写OnOK函数也没用。那么如何定制回车键的行为呢?这个问题很easy,但是要说明白,却要费点时间。 
    这个问题在Windows的开发中由来已久,对于初学者来说,这是个恼人的问题,幸运的是,人们找到了多种解决这个问题的方案。本文将告诉你定制回车键行为的方法。 
    如果你想要disable回车键,最简单的方法是重载OnOK函数,这固然是个不坏的主意,但如果你重载OnOK,让它什么事情也不干,那麽当用户用鼠标按下回车键想真正做些什么的时候怎么办呢?你可以改变回车键的ID,如:ID_MY_OK,并写一个调用EndDialog的处理器,这个方法虽然也能行得通,但显得有点不专业。 
    另外一种方法是disable回车键的“默认”属性。这也是本文开始所提出的方法,之所以没有成功,是因为仅仅uncheck 回车键的 BS_DEFPUSHBUTTON 属性是不够的,你可以利用Spy++仔细地观察控制和实验就能发现回车键仍然我行我素发送退出消息。
    问题出在哪呢?你必须区分OK键和回车键,你可以写一个OnOK处理器调用GetCurrentMessage函数获取最后发送的消息,应该是WM_COMMAND,再检查WPARAM的低位字(low-order word)看看命令来自何处。 
    要解决问题,必须搞清楚背后所发生的一切,在Spy++中可以看到,当用户按下回车键时,Windows发送一个特殊的WM_GETDEFID消息来获得缺省的命令ID,Windows再将它作为WM_COMMAND发送。所以,你要做的就是重载WM_GETDEFID消息,在有关Windows的文档中是这样描述WM_GETDEFID返回值的:“如果有缺省得按钮,则返回值的高位字包含DC_HASDEFID,低位字包含控制的标识符。否则,返回值是零。”
根据这段描述,假设如果没有缺省得按钮,则返回值应该是零。如果想要disable缺省得ID,必须在高位字中返回DC_HASDEFID。
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)    ON_MESSAGE(DM_GETDEFID, OnGetDefID)    ...END_MESSAGE_MAP()LRESULT CMyDlg::OnGetDefID(WPARAM wp, LPARAM lp) {    return MAKELONG(0,DC_HASDEFID); } 
    因为MFC没有对应DM_GETDEFID的宏,你必须使用通用的ON_MASSAGE宏。这样用户可以随意按回车键,但什么事都不会发生。上面的做法是解决了按回车键程序退出的问题。但是又产生了另外一个问题:如果想要回车键做些事情怎么办呢?有一些人曾经问过如何将回车键映射到TAB键,既按下回车键就象按下TAB键一样-也就是说输入焦点移动到下一个对话框控制。这需要做一些工作才行,但最简单的方式是使用加速键。许多程序员试图用OnChar,我会对他们说:No,no,no! OnChar是一个低级趣味的东西,你应该想方设法避免它,更糟的还有WM_KEYDOWN,WM_KEYUP之类的东西。谁能处理这些东西?OnChar可以用来限制允许输入编辑框的字符,如:数字,字母等。如果想要将一个键映射到一个命令,加速键才是最好的方法。
    在本文的例子为VK_RETURN创建了一个加速键,将它映射到命令ID_MY_ENTER,并写一个命令处理器来做你想做的事情。
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)     ON_COMMAND(ID_MY_ENTER, OnMyEnter)    ......END_MESSAGE_MAP() void CMyDlg::OnMyEnter() {    NextInTabOrder(); } 
  下图是本文例子的对话框和代码,代码中的NextInTabOrder是实际起作用的函数。它使用GetNextDlgTabItem来获得Tab顺序的下一个控制焦点。


while (GetMessage(...)) {     TranslateMessage(...);    DispatchMessage(...); } 
    在这里细节不是重要的,重要的是消息并不到达程序的流程,你必须请求消息。这是一种人为的非抢先式多任务方法,这种方法通过每一个任务精诚协作来仿造多任务环境,随着增加的功能越来越多,有人想到了加速键表的主意,这个表用来映射按键和命令IDs。为了实现这个目的,他们发明了一个叫TranslateAccelerator的函数。现在这个消息泵变成了如下的样子:
while (GetMessage(...)) {     if (TranslateAccelerator(hAccel...)) {         // handled, continue looping         } else {         TranslateMessage(...);         DispatchMessage(...);     } } 

展开更多 50%)
分享

猜你喜欢

如何定制对话框中的回车键

C语言教程 C语言函数
如何定制对话框中的回车键

VC程序中定制对话框中的回车键

编程语言 网络编程
VC程序中定制对话框中的回车键

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

再谈 CFileDialog 对话框的定制

C语言教程 C语言函数
再谈 CFileDialog 对话框的定制

一个定制CFileDialog对话框的实例

C语言教程 C语言函数
一个定制CFileDialog对话框的实例

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

如何改变Excel2010中回车键的功能

电脑入门
如何改变Excel2010中回车键的功能

关于对话框

编程语言 网络编程
关于对话框

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

鼠标周围的文字宣传

鼠标周围的文字宣传

创建非矩形窗口的简单方法

创建非矩形窗口的简单方法
下拉加载更多内容 ↓