Delphi VCL 应用程序,如何禁用 KeyDown 事件的默认行为?
Delphi VCL app, how to disable the default behavior of a KeyDown event?
在阅读代码时,我发现在 KeyDown
事件中可以设置 Key := 0;
以停止进一步处理该事件。例如:TIncrementalForm.FormKeyDown
编码为:
procedure TIncrementalForm.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if Key = VK_RETURN then begin
Key := 0; // Stop processing by input window
if Shift = [ssShift] then
btnPrevClick(nil)
else
btnNextClick(nil);
end;
end;
另一个例子来自unit FindFrm
:
procedure TFindForm.cboFindTextKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if Key = VK_TAB then begin
cboFindText.SelText := #9;
Key := 0; // prevent propagation
end;
end;
我自己测试过,不行:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Memo2: TMemo;
Button1: TButton;
procedure Memo1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
private const
VK_X = Ord('X');
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Memo1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if Key = VK_X then
begin
Key := 0;
Memo2.Lines.Add('yes');
end;
end;
end.
我的意图是:每当用户按下 TMemo
控件中的 x 键时,我都会执行一些业务逻辑(即在备忘录中添加“是”)并停止进一步处理。但结果是 x 键仍然插入到 TMemo
文本中。我想知道如何禁用默认按键按住事件行为(插入相应的按键)。
这里的关键(没有双关语意)是使用 OnKeyPress
而不是 OnKeyDown
:
procedure TForm1.Memo1KeyPress(Sender: TObject; var Key: Char);
begin
if Key = 'x' then
begin
Key := #0;
Memo1.Lines.Add('yes');
end;
end;
不是答案,而是评论,但我需要发布代码,所以...
您可以使用这些函数测试当前 Shift 状态:
CONST
VK_ALT = VK_MENU;
VK_CTRL = VK_CONTROL;
FUNCTION KeyPressed(VirtualKey : WORD) : BOOLEAN;
BEGIN
Result:=(GetKeyState(VirtualKey) AND 000000<>0)
END;
FUNCTION Shift : BOOLEAN;
BEGIN
Result:=KeyPressed(VK_SHIFT)
END;
FUNCTION Alt : BOOLEAN;
BEGIN
Result:=KeyPressed(VK_ALT)
END;
FUNCTION Ctrl : BOOLEAN;
BEGIN
Result:=KeyPressed(VK_CTRL)
END;
但请注意,您必须在键盘事件的尾部和新的键盘事件发生之前调用这些函数,因为此调用将 return 与 的状态相同最新的 键盘事件,而不是在您想要的时间必须处于活动状态的事件(如果您在键盘事件处理程序之外调用它)。
在阅读代码时,我发现在 KeyDown
事件中可以设置 Key := 0;
以停止进一步处理该事件。例如:TIncrementalForm.FormKeyDown
编码为:
procedure TIncrementalForm.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if Key = VK_RETURN then begin
Key := 0; // Stop processing by input window
if Shift = [ssShift] then
btnPrevClick(nil)
else
btnNextClick(nil);
end;
end;
另一个例子来自unit FindFrm
:
procedure TFindForm.cboFindTextKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if Key = VK_TAB then begin
cboFindText.SelText := #9;
Key := 0; // prevent propagation
end;
end;
我自己测试过,不行:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Memo2: TMemo;
Button1: TButton;
procedure Memo1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
private const
VK_X = Ord('X');
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Memo1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if Key = VK_X then
begin
Key := 0;
Memo2.Lines.Add('yes');
end;
end;
end.
我的意图是:每当用户按下 TMemo
控件中的 x 键时,我都会执行一些业务逻辑(即在备忘录中添加“是”)并停止进一步处理。但结果是 x 键仍然插入到 TMemo
文本中。我想知道如何禁用默认按键按住事件行为(插入相应的按键)。
这里的关键(没有双关语意)是使用 OnKeyPress
而不是 OnKeyDown
:
procedure TForm1.Memo1KeyPress(Sender: TObject; var Key: Char);
begin
if Key = 'x' then
begin
Key := #0;
Memo1.Lines.Add('yes');
end;
end;
不是答案,而是评论,但我需要发布代码,所以...
您可以使用这些函数测试当前 Shift 状态:
CONST
VK_ALT = VK_MENU;
VK_CTRL = VK_CONTROL;
FUNCTION KeyPressed(VirtualKey : WORD) : BOOLEAN;
BEGIN
Result:=(GetKeyState(VirtualKey) AND 000000<>0)
END;
FUNCTION Shift : BOOLEAN;
BEGIN
Result:=KeyPressed(VK_SHIFT)
END;
FUNCTION Alt : BOOLEAN;
BEGIN
Result:=KeyPressed(VK_ALT)
END;
FUNCTION Ctrl : BOOLEAN;
BEGIN
Result:=KeyPressed(VK_CTRL)
END;
但请注意,您必须在键盘事件的尾部和新的键盘事件发生之前调用这些函数,因为此调用将 return 与 的状态相同最新的 键盘事件,而不是在您想要的时间必须处于活动状态的事件(如果您在键盘事件处理程序之外调用它)。