在我的TComponent中,有一点我想要听取键事件并拦截ESC键并在我的组件中处理它,消耗/“吃掉”击键,以便例如所有者表单不会处理它阶段.就像在TDragObject中开始时一样,拖动并按ESC取消它.
问题是TDragObject具有由其所有者表单通知CN_KEYDOWN的AllocateHWnd.但是没有人通知我的组件.
我需要用自己的窗体替换窗体的WindowProc吗?如果是,那么如何正确地“按书”做到这一点呢?
只是100%明确:
TMyComponent = class(TComponent)
我做了一个小测试,似乎工作:
TMyComponent = class(TComponent) private FOldWindowProc: TWndMethod; FParentForm: TCustomForm; procedure FormWindowProc(var Message: TMessage); public constructor Create(AOwner: TComponent); override; destructor Destroy; override; end; ... constructor TMyComponent.Create(AOwner: TComponent); begin if not (AOwner is TWinControl) then raise Exception.Create('TMyComponent.Create: Owner must be a TWinControl'); inherited Create(AOwner); // hook parent form FParentForm := GetParentForm(TWinControl(Owner)); if Assigned(FParentForm) then begin FOldWindowProc := FParentForm.WindowProc; FParentForm.WindowProc := FormWindowProc; end; end; destructor TMyComponent.Destroy; begin // unhook parent form if Assigned(FParentForm) then FParentForm.WindowProc := FOldWindowProc; inherited; end; procedure TMyComponent.FormWindowProc(var Message: TMessage); begin FOldWindowProc(Message); if Message.Msg = CM_CHILDKEY then // CM_CHILDKEY -> CM_DIALOGKEY -> CM_DIALOGCHAR begin OutputDebugString('CM_CHILDKEY'); if Message.WParam = VK_ESCAPE then begin Beep; // do my stuff... Message.Result := 1; // consume keystroke end; end; end;
我想知道这是否是正确/唯一的方法.
解决方法
一种方法可能是在组件内部创建TApplicationEvents对象,然后使用其OnMessage事件在其他VCL处理它们之前查看来自主线程消息队列的消息,例如击键.
原文地址:https://www.jb51.cc/delphi/102151.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。