如何在TEdit控件中捕获一个VK_TAB键,而不是让它失去焦点? [英] How do I catch a VK_TAB key in my TEdit control and not let it lose the focus?

查看:920
本文介绍了如何在TEdit控件中捕获一个VK_TAB键,而不是让它失去焦点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的TEdit字段中,我的文本格式为< number1> ..< number2>

In my TEdit field I have text in the form <number1>..<number2>.

我的想法是:

当用户使用另一个控件的 TAB 输入控件时, number1 被选中。

When a user enters the control using TAB from another control, number1 gets selected.

当我的TEdit控件有焦点,用户再次按 TAB 时,我想要$ code > number2 以获得选择,并且 number1 被取消选择。

When my TEdit control has a focus and user presses TAB again, I want the number2 to get selected and number1 to be deselected.

如果当前的插入符号位置在number2的地方,按 TAB 应该正常运行,并将焦点移动到窗体上的下一个控件。

And if current caret position is at the place where number2 is, pressing TAB should act normal and move the focus to the next control on the form.

我有2个问题。


  1. 当编辑字段已激活时,我无法抓住标签键。

  1. I cannot catch the tab key press when the Edit field is active already. I can only catch it when this control is being entered/focused.

我不知道是否有一个类似于#0的键,所以我可以转过来NoOP中的关键。

I don't know if there is a key similar to #0 so I could turn the key into NoOP.

任何想法,怎么做?

推荐答案

你最好编写自己的TEdit后代处理WM_GETDLGCODE消息。一般的想法是:

You are better to write your own TEdit descendant that processes WM_GETDLGCODE message. The general idea is:

unit Unit1;

interface

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

type
  TMyEdit = class(TEdit)
    procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
  end;

type
  TForm1 = class(TForm)
    Edit2: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
  private
    { Private declarations }
    FMyEdit: TMyEdit;
    FDone: Boolean;
    procedure MyEditEnter(Sender: TObject);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyEdit }

procedure TMyEdit.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
  inherited;
  Message.Result:= Message.Result or DLGC_WANTTAB;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FMyEdit:= TMyEdit.Create(Self);
  FMyEdit.Left:= 40;
  FMyEdit.Top:= 40;
  FMyEdit.Parent:= Self;
  FMyEdit.Text:= '45..90';
  FMyEdit.OnEnter:= MyEditEnter;
  KeyPreview:= True;
end;

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
  if (Key = #9) and (ActiveControl = FMyEdit) then begin
    if FDone then begin
      Perform(CM_DialogKey, VK_TAB, 0);
    end
    else begin
      FMyEdit.SelStart:= 4;
      FMyEdit.SelLength:= 2;
    end;
    FDone:= not FDone;
    Key:= #0;
  end;
end;

procedure TForm1.MyEditEnter(Sender: TObject);
begin
  FDone:= False;
  FMyEdit.SelStart:= 0;
  FMyEdit.SelLength:= 2;
end;

end.

更新:没有制作TEdit后代类的相同想法:单位Unit1; p>

Updated: The same idea without making a TEdit descendant class:

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    procedure Edit2Enter(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
  private
    { Private declarations }
    FDone: Boolean;
    FOldWndProc: TWndMethod;
    procedure Edit2WindowProc(var Message: TMessage);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Edit2Enter(Sender: TObject);
begin
  FDone:= False;
  Edit2.SelStart:= 0;
  Edit2.SelLength:= 2;
end;

procedure TForm1.Edit2WindowProc(var Message: TMessage);
begin
  if Message.Msg = WM_GETDLGCODE then
    Message.Result:= Message.Result or DLGC_WANTTAB
  else
    if Assigned(FOldWndProc) then FOldWndProc(Message);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  KeyPreview:= True;
  Edit2.Text:= '45..90';
  FOldWndProc:= Edit2.WindowProc;
  Edit2.WindowProc:= Edit2WindowProc;
end;

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
  if (Key = #9) and (ActiveControl = Edit2) then begin
    if FDone then begin
      Perform(CM_DialogKey, VK_TAB, 0);
    end
    else begin
      Edit2.SelStart:= 4;
      Edit2.SelLength:= 2;
    end;
    FDone:= not FDone;
    Key:= #0;
  end;
end;

end.

这篇关于如何在TEdit控件中捕获一个VK_TAB键,而不是让它失去焦点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆