怎样使TButton控件获得输入焦点时击回车键能引发OnKeyDown事件而不是OnClick事件(300分)

  • 主题发起人 主题发起人 zw70
  • 开始时间 开始时间
Z

zw70

Unregistered / Unconfirmed
GUEST, unregistred user!
TButton与TEdit同属TWinControl控件,当TEdit倥件获得输入焦点时,击回车
键将引发OnKeyDown事件,而TButton控件获得输入焦点时击回车键
将引发OnClick事件,请问在不修改本身的情况下怎样才能使击回车键
引发OnKeyDown事件,如若必须修改控件本身该如何修改呢?
 
SendMessage
 
简单的方法:
在BUTTON的ONCLICK 事件里写
if getfocus()= button1.handle then Exit;
这样就屏蔽掉了ONCLICK事件

在BUTTON的 ONKEYDOWN事件里写
IF KEY=13 THEN
BEGIN
//完成你的回车事件
END;
 
在OnKeyUp中可以。
 
上述所提内容只能通过修改控件本身来实现。因为在TBUTTON的PRIVATE段中有一个方法
procedure TButton.CMDialogKey(var Message: TCMDialogKey);
begin
with Message do
if (((CharCode = VK_RETURN) and FActive) or
((CharCode = VK_ESCAPE) and FCancel)) and
(KeyDataToShiftState(Message.KeyData) = []) and CanFocus then
begin
Click;
Result := 1;
end else
inherited;
end;
把其中的Result := 1;修改为 Result := 0;
并在工程菜单中ADD FILE TO PROJECT选项中
加入delphi/source/vcl/stdctrls.pas
重新编译即可。


 
在上述的例子中你只要将CLICK删去,就不会发生CLICK事件了。
以上的方法我都试过了,百分之百好使。
 
这个问题应该再详细些,比如你的最终目的是什么,因为直接解决这问题也许有些得
不偿失,不知能否绕过,用其它方案解决。
 
可以重新定义一个事件响应句柄。
 
我发现最近总有类似的反常问题提出。

把TBUTTON的ENTER键变成了ONKEYDOWN/ONKEYUP有什么好处呢?TBUTTON不接受
ENTER键了,如果你的鼠标又不太灵光的时候,你的BUTTON就无法用了。

当然这样做是能够实现的,只需要修改TBUTTON控件的源码,按照MJT的做法就能可
以,但是有和必要呢????
 
基本上同意mjt的看法,并表示感谢!
但下面的好象有问题:
"并在工程菜单中ADD FILE TO PROJECT选项中加入delphi/source/vcl/stdctrls.pas重新编译即可."

其他朋友的看法大概都行不通。
 
基本上同意mjt的看法,并表示感谢!
但下面的好象有问题,应在环境变量Libray Path前面加入$(DELPHI)/soruce/vcl.
"并在工程菜单中ADD FILE TO PROJECT选项中加入delphi/source/vcl/stdctrls.pas重新编译即可."

其他朋友的看法大概都行不通。
 
等一下,我有一计:
请看:
procedure TForm1.Button1Click(Sender: TObject);
var msg:Tmsg;
begin
getmessage( msg,self.Handle,0,0);
if msg.message = Wm_keyup then
sendmessage(Button1.Handle,WM_KEYDOWN,13,0)
else showmessage('click');

end;

procedure TForm1.Button1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
showmessage('keydown');
end;
 
其实不用费这么大力气。

设置一个全局(Private)标志位Key_Enter;当回车键被按下时,置Key_Enter为True;
然后在Click事件里写上:
If Key_enter Then Exit;

OK.
 
这是因为TButton使用了标准的Windows button control,其中使用了回车键。 为解决这个问题,需要重写TButton类并添加对消息wm_GetDlgCode的处理,代码如下:
type
TMyButton = class
protected
procedure WMGetDlgCode(var Msg: TWMGetDlgCode); message wm_GetDlgCode;
end;

procedure TMyButton.WMGetDlgCode;
begin
inherited;
Msg.Result := Msg.Result or dlgc_WantReturn;
end;
请参阅WinAPI帮助文件获得关于此消息的更多信息
 
给钱结束如何?太长时间了。
 
在wndproc中捕获再处理如何?
 
后退
顶部