WM_NEXTDLGCTL message and OnKeyPress

原文地址:http://blog.sina.com.cn/s/blog_47df3bea0101bddf.html
说明:原文是Delphi语言写的,我这里改成C++语言,意思不改变。

在MSDN:https://msdn.microsoft.com/en-us/library/ms645432(VS.85).aspx
Parameters
wParam
If lParam is TRUE, this parameter identifies the control that receives the focus. If lParam is FALSE, this parameter indicates whether the next or previous control with the WS_TABSTOP style receives the focus. If wParam is zero, the next control receives the focus; otherwise, the previous control with the WS_TABSTOP style receives the focus.
wParam
如果lParam为TRUE,则此参数表明获得焦点的控件。 如果lParam为FALSE,则此参数指示具有WS_TABSTOP样式的下一个或上一个控件是否获得焦点。 如果wParam为零,则下一个控件获得焦点; 其他情况,上一个拥有WS_TABSTOP风格的控件会收到焦点。

lParam
The low-order word indicates how the system uses wParam. If the low-order word is TRUE, wParam is a handle associated with the control that receives the focus; otherwise, wParam is a flag that indicates whether the next or previous control with the WS_TABSTOP style receives the focus.
lParam
低位字表示系统如何使用wParam。 如果低位字是TRUE,则wParam是一个与接收焦点的控件相关的句柄; 否则,wParam是一个标志,它表示下一个或上一个WS_TABSTOP风格的控件是否接收到焦点。

Do not use the SendMessage function to send a WM_NEXTDLGCTL message if your application will concurrently process other messages that set the focus. Use the PostMessage function instead.
如果应用程序将同时处理其他设置焦点的消息,则不要使用SendMessage函数发送WM_NEXTDLGCTL消息。 使用PostMessage函数。

好了,让我们一起看一段代码:
void __fastcall TForm1::Edit1KeyPress(TObject *Sender, System::WideChar &Key)
{
if(Key == 13){
Perform(WM_NEXTDLGCTL, 0, 0);
}
}
看代码时,看见最普通的一段代码,相信大家都看见过,但是大家对这段代码真正了解多少呢,现在详细分析下。
1、TEdit的OnKeyPress事件:当按下键盘上一个ASCII码键时将触发该事件。注意:非ASCII码键不能触发该事件。

(哪些是非ASCII码键,自己不是很了解,从网上找到一些内容。
http://ascii.911cha.com/
TEdit的OnKeyPress事件:当按下键盘上一个任何键时将触发该事件。

2、通过一的内容知道,Enter键的ASCII码为13。

3、Perform(WM_NEXTDLGCTL,0,0) 就是将焦点切换到下一个控件

上面的代码的意思就是你触发Enter键或者Tab键时,焦点切换到下一个控件。
加入窗体上有很多控件,难道每个控件的OnKeyPress事件中都写入此代码,那样实在是太麻烦,现在又简单的方法。(来源:http://blog.sina.com.cn/s/blog_4c0fc2c0010008y2.html
先将窗体的KeyPreview属性设为True。然后在FormKeyPress事件中加入以下代码:

void __fastcall TForm1::FormKeyPress(TObject *Sender, System::WideChar &Key)
{
if(Key == 13)
{
Key = 0; //吃掉回车键
//方法1
PostMessageA(this->Handle,WM_NEXTDLGCTL,0,0);
//方法2
//Perform(WM_NEXTDLGCTL, 0, 0);
}
}
这个方法对于大多数控件都适用,但不适用于TButton控件,因为对于按钮,回车键等于按下了按钮,不触发FormKeyPress事件。
方法确实已经非常简单,但如果要在每一个窗口都重复写以上内容,还是有些繁。怎样将其改写成一个自定义过程,然后在每一个窗口中调用此过程?
答:要改写成一个自定义过程,可以这样:
void __fastcall TForm1::MyKeyPress(TObject *Sender, System::WideChar &Key)
{
if(Key == 13)
{
Key = 0;
//方法1
PostMessageA(this->Handle,WM_NEXTDLGCTL,0,0);
//方法2
//Perform(WM_NEXTDLGCTL, 0, 0);
}
}
void __fastcall TForm1::FormKeyPress(TObject *Sender, System::WideChar &Key)
{
MyKeyPress(Sender,Key);
}
但是这样还有有些控件不适用,具体访问上面的网址,就不在此列出。

把焦点设给下一个控件,那如何把焦点设到上一个控件呢。
同样也是先将窗体的KeyPreview属性设为True。然后在FormKeyDown事件中加入以下代码:
void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
if(Key == VK_UP)
{
Perform(WM_NEXTDLGCTL, 1, 0);
}
else if(Key == VK_DOWN)
{
Perform(WM_NEXTDLGCTL, 0, 0);
}
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值