【问题标题】:Distribute keypresses between parent form and child control在父窗体和子控件之间分配按键
【发布时间】:2011-01-25 12:52:22
【问题描述】:

有时,根据应用程序的状态,表单上的击键可能有不同的配方。请参阅以下示例:

unit Unit1;

interface

uses
  Windows,
  Messages,
  SysUtils,
  Variants,
  Classes,
  Graphics,
  Controls,
  Forms,
  Dialogs,
  ComCtrls,
  Buttons;

type
  TForm1 = class(TForm)
  private
    ListView1: TListView;
    ButtonOK: TBitBtn;
    ButtonCancel: TBitBtn;
    procedure ButtonClick(Sender: TObject);
  public
    constructor Create(AOwner: TComponent); override;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

constructor TForm1.Create(AOwner: TComponent);
begin
  inherited CreateNew(AOwner);
  ClientWidth := 300;
  ClientHeight := 240;

  ListView1 := TListView.Create(Self);
  ListView1.Name := 'ListView1';
  ListView1.Parent := Self;
  ListView1.Height := 200;
  ListView1.Align := alTop;
  ListView1.AddItem('aaaaa', nil);
  ListView1.AddItem('bbbbb', nil);
  ListView1.AddItem('ccccc', nil);

  ButtonOK := TBitBtn.Create(Self);
  ButtonOK.Parent := Self;
  ButtonOK.Left := 8;
  ButtonOK.Top := 208;
  ButtonOK.Kind := bkOK;
  ButtonOK.OnClick := ButtonClick;

  ButtonCancel := TBitBtn.Create(Self);
  ButtonCancel.Parent := Self;
  ButtonCancel.Left := 90;
  ButtonCancel.Top := 208;
  ButtonCancel.Kind := bkCancel;
  ButtonCancel.OnClick := ButtonClick;
end;

procedure TForm1.ButtonClick(Sender: TObject);
begin
  ShowMessage((Sender as TBitBtn).Caption);
  Application.Terminate;
end;

end.

(要运行它,请创建一个标准的 VCL 应用程序并将 Unit1.pas 的内容替换为上述内容。)

如果启动应用程序并按下 EnterEsc,则会“单击”相应的按钮。然而,当一个人开始编辑列表视图(通过在一个项目上单击一个半时间) EnterEsc 应该接受或取消他们不接受或取消的编辑 - 他们仍然“点击”按钮。

如果在包含 cxGrid 的表单上使用快捷键 F2F4 的操作(默认情况下使用这些快捷键启动编辑模式或下拉组合框),则存在类似情况编辑。

您知道如何继续使用 TButton.Default/Cancel 和操作的舒适性,而 不必 必须重新实现我使用的所有组件的键处理吗?

【问题讨论】:

    标签: delphi keyboard-shortcuts vcl


    【解决方案1】:

    我猜你使用的控件运气不好。 TMemo 正确处理它,但实际上可编辑的 TListView 没有。 problem seems to originate from win32 而不是围绕它的 VCL 包装器。因此,如果您不喜欢 TListView 当前的行为,您似乎必须在 TListView 上重新实现密钥处理。

    procedure WMGetDlgCode(var Message: TMessage); message WM_GETDLGCODE;
    
    procedure TMyListView.WMGetDlgCode(var Message: TMessage);
    begin
      inherited;
    
      if IsEditing then
        Message.Result := Message.Result or DLGC_WANTALLKEYS;
    end;
    

    由于所有控件的行为都不同,并且是控件本身决定了它们对哪些键感兴趣,因此我看不出如何在不更改不需要的行为的情况下修复它。

    【讨论】:

    • 不创建后代类也应该可以做同样的事情,就像这里:stackoverflow.com/questions/2363456/…
    • 无需创建自己的 TmyEdit 等,只需使用type TEdit = class(StdCtrls.TEdit) {...} end; 之类的行将您希望添加到 TEdit 的任何内容,包括按键的新消息处理。现在,在您的表单上,您拥有标准 TEdit 的任何地方都将使用您的新扩展版本。或者,将您的新类型声明添加到一个单元以在多个表单中使用它。您必须确保在包含原始控件的所有单元之后将您的单元添加到使用子句(在末尾添加它是最简单的解决方案)。
    猜你喜欢
    • 2015-05-02
    • 2016-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多