将键盘事件从一个Windows控件转发到另一个Windows控件
在Delphi XE中,我正在尝试实现一个“即时搜索”功能 – 一个类似于Firefox的“在键入时搜索”的功能,但在开源剪贴板扩展器
Ditto中的类似功能更好地说明了这一功能:
有一个处理典型导航事件的项目列表.但是,任何字母数字键以及导航和编辑命令(向右/向左箭头,移位箭头,退格键,删除等)都应该重新路由到列表下方的编辑框.编辑框的OnChange事件将触发刷新列表. UI的要点是用户不必在控件之间使用制表符或shift键.这两个控件(列表和编辑框)应该“感觉”好像它们是单个控件.搜索UI的行为不应该取决于哪个控件具有焦点. 似乎我最好的选择是将某些键盘事件从列表控件(我正在使用TcxTreeList)转发到编辑框,并将一些导航键从编辑框转发到列表.我怎样才能做到这一点? 笔记: > TcxTreeList当然支持增量搜索,但这不是我追求的.搜索转到SQLite数据库并查找子字符串匹配.该列表仅显示db中的匹配项. 在编辑: type THackEdit = class( TEdit ); procedure TMainForm.cxTreeList1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin THackEdit( edit1 ).KeyDown( Key,Shift ); end; 不幸的是,这没有任何效果.我的猜测是TEdit不会处理关键事件,除非它是专注的.使用SendMessage(THackEdit(edit1).Handle,WM_KEYDOWN,Key,0)也没有效果. 解决方法
您可以使用VCL控件的消息处理功能,并将相关消息发送给彼此.我不知道’TcxTreeList’,但下面演示了编辑控件和同步响应键盘事件的备忘录控件的想法(当然可能).
type TEdit = class(stdctrls.TEdit) private FMsgCtrl: TWinControl; FRecursing: Boolean; procedure WmChar(var Msg: TWMChar); message WM_CHAR; procedure WmKeyDown(var Msg: TWMKeyDown); message WM_KEYDOWN; procedure WmKeyUp(var Msg: TWMKeyUp); message WM_KEYUP; end; TMemo = class(stdctrls.TMemo) private FMsgCtrl: TWinControl; FRecursing: Boolean; procedure WmChar(var Msg: TWMChar); message WM_CHAR; procedure WmKeyDown(var Msg: TWMKeyDown); message WM_KEYDOWN; procedure WmKeyUp(var Msg: TWMKeyUp); message WM_KEYUP; end; TForm1 = class(TForm) Edit1: TEdit; Memo1: TMemo; procedure FormCreate(Sender: TObject); private public end; var Form1: TForm1; implementation {$R *.dfm} { TEdit } procedure TEdit.WmChar(var Msg: TWMChar); begin if not FRecursing then begin inherited; // Insert test here to see if the message will be forwarded // exit/modify accordingly. if Assigned(FMsgCtrl) then begin FRecursing := True; try FMsgCtrl.Perform(Msg.Msg,MakeWParam(Msg.CharCode,Msg.Unused),Msg.KeyData); finally FRecursing := False; end; end; end; end; procedure TEdit.WmKeyDown(var Msg: TWMKeyDown); begin // exact same contents as in the above procedure end; procedure TEdit.WmKeyUp(var Msg: TWMKeyUp); begin // same here end; { TMemo } procedure TMemo.WmChar(var Msg: TWMChar); begin // same here end; procedure TMemo.WmKeyDown(var Msg: TWMKeyDown); begin // same here end; procedure TMemo.WmKeyUp(var Msg: TWMKeyUp); begin // same here end; { TForm1 } procedure TForm1.FormCreate(Sender: TObject); begin Edit1.FMsgCtrl := Memo1; Memo1.FMsgCtrl := Edit1; end; 您可能需要干预其他消息,但您明白了. 如果由于某种原因您无法派生新控件或覆盖消息处理,则可以考虑对控件进行子类化.回答this question会告诉你如何做到这一点. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- windows-mobile – Windows Mobile 6开发,视觉工作室的替代
- windows-server-2008 – 混合以太网速度的Windows 2008 Ser
- Microsoft Office Project 2016使用心得(一)
- windows-phone-7 – 如何将SqlCe数据库部署到用于Windows P
- windows-phone-8.1 – Windows Phone 8.1应用程序中的部署错
- 视力受损的人和Windows更新
- 如果崩溃,如何自动重启Windows服务?
- windows – 如何获得屏幕自动旋转的状态?
- windows – 当请求的缓冲区大小大于可用数据量时,为什么rec
- windows-server-2008 – 仅在Windows客户端和域控制器之间打