wordpress   发布时间:2022-04-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了将键盘事件从一个Windows控件转发到另一个Windows控件大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_197_0@

概述

在Delphi XE中,我正在尝试实现一个“即时搜索”功能 – 一个类似于Firefox的“在键入时搜索”的功能,但在开源剪贴板扩展器 Ditto中的类似功能更好地说明了这一功能: 有一个处理典型导航事件的项目列表.但是,任何字母数字键以及导航和编辑命令(向右/向左箭头,移位箭头,退格键,删除等)都应该重新路由到列表下方的编辑框.编辑框的OnChange事件将触发刷新列表. UI的要点是用户不必在
在Delphi XE中,我正在尝试实现一个“即时搜索功能一个类似于Firefox的“在键入时搜索”的功能,但在开源剪贴板扩展器 Ditto中的类似功能更好地说明了这一功能

一个处理典型导航事件的项目列表.但是,任何字母数字键以及导航和编辑命令(向右/向左箭头,移位箭头,退格键,删除等)都应该重新路由到列表下方的编辑框.编辑框的OnChange事件将触发刷新列表.

UI的要点是用户不必在控件之间使用制表符或shift键.这两个控件(列表和编辑框)应该“感觉”好像它们是单个控件.搜索UI的行为不应该取决于哪个控件具有焦点.

似乎我最好的选择是将某些键盘事件从列表控件(我正在使用TcxTreeList)转发到编辑框,并将一些导航键从编辑框转发到列表.我怎样才能做到这一点?

笔记:

> TcxTreeList当然支持增量搜索,但这不是我追求的.搜索转到sqlite数据库并查找子字符串匹配.该列表仅显示db中的匹配项.
>有一些重叠,例如两个控件通常都会处理VK_HOME和VK_END,但这没关系 – 在这种情况下,键会进入列表.我需要决定是否转发每个单独的按键,或者在接收它的控件中处理它.

在编辑:
一个显而易见的方法似乎是调用编辑控件的相应KeyDown,KeyUp和KeyPress方法,如下所示:

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控件转发到另一个Windows控件全部内容,希望文章能够帮你解决将键盘事件从一个Windows控件转发到另一个Windows控件所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。