根据评论,这是一个示例,说明如何通过处理KeyPress
事件而不是手动转换KeyDown
事件来避免问题。TNT 控件不提供WideChar
KeyPress
事件,但添加起来相当容易。理想情况下,您不应该像我在这里所做的那样将扩展放入派生类中TTntMemo
,TTntForm
而是修改 TNT 源代码。
该窗体包含两个TTntMemo
控件。在第一个中按下键将在第二个中记录事件。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, TntForms, StdCtrls, TntStdCtrls;
type
TKeyPressWEvent = procedure(Sender: TObject; var Key: WideChar) of object;
TTntMemo = class(TntStdCtrls.TTntMemo)
private
FOnKeyPressW: TKeyPressWEvent;
procedure WMChar(var Msg: TWMChar); message WM_CHAR;
protected
function DoKeyPressW(var Message: TWMKey): Boolean;
procedure KeyPressW(var Key: WideChar);
published
property OnKeyPressW: TKeyPressWEvent read FOnKeyPressW write FOnKeyPressW;
end;
TTntForm = class(TntForms.TTntForm)
private
FOnKeyPressW: TKeyPressWEvent;
procedure WMChar(var Msg: TWMChar); message WM_CHAR;
protected
function DoKeyPressW(var Message: TWMKey): Boolean;
procedure KeyPressW(var Key: WideChar);
published
property OnKeyPressW: TKeyPressWEvent read FOnKeyPressW write FOnKeyPressW;
end;
TForm1 = class(TTntForm)
TntMemo1: TTntMemo;
TntMemo2: TTntMemo;
procedure FormCreate(Sender: TObject);
procedure FormKeyPressW(Sender: TObject; var Key: WideChar);
procedure TntMemo1KeyPressW(Sender: TObject; var Key: WideChar);
end;
var
Form1: TForm1;
implementation
uses
TntControls;
{$R *.dfm}
type
TWinControlAccess = class(TWinControl);
TTntFormAccess = class(TTntForm);
function TntControl_DoKeyPressW(Self: TWinControl; var Message: TWMKey;
KeyPressW: Pointer): Boolean;
type
TKeyPressWProc = procedure(Self: TWinControl; var Key: WideChar);
var
Form: TCustomForm;
Ch: WideChar;
begin
Result := True;
Form := GetParentForm(Self);
if (Form <> nil) and (Form <> Self) and Form.KeyPreview then
begin
if (Form is TTntForm) and TTntFormAccess(Form).DoKeyPressW(Message) then Exit;
if TWinControlAccess(Form).DoKeyPress(Message) then Exit;
end;
if not (csNoStdEvents in Self.ControlStyle) then
begin
Ch := GetWideCharFromWMCharMsg(Message);
TKeyPressWProc(KeyPressW)(Self, Ch);
SetWideCharForWMCharMsg(Message, Ch);
if Ch = #0 then Exit;
end;
Result := False;
end;
{ TTntMemo }
function TTntMemo.DoKeyPressW(var Message: TWMKey): Boolean;
begin
Result := TntControl_DoKeyPressW(Self, Message, @TTntMemo.KeyPressW);
end;
procedure TTntMemo.KeyPressW(var Key: WideChar);
begin
if Assigned(FOnKeyPressW) then FOnKeyPressW(Self, Key);
end;
procedure TTntMemo.WMChar(var Msg: TWMChar);
begin
if not DoKeyPressW(Msg) then inherited;
end;
{ TTntForm }
function TTntForm.DoKeyPressW(var Message: TWMKey): Boolean;
begin
Result := TntControl_DoKeyPressW(Self, Message, @TTntForm.KeyPressW);
end;
procedure TTntForm.KeyPressW(var Key: WideChar);
begin
if Assigned(FOnKeyPressW) then FOnKeyPressW(Self, Key);
end;
procedure TTntForm.WMChar(var Msg: TWMChar);
begin
if not DoKeyPressW(Msg) then inherited;
end;
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
Self.OnKeyPressW := FormKeyPressW;
TntMemo1.OnKeyPressW := TntMemo1KeyPressW;
end;
procedure TForm1.FormKeyPressW(Sender: TObject; var Key: WideChar);
begin
TntMemo2.Lines.Add(WideString('FormKeyPress: ') + Key);
end;
procedure TForm1.TntMemo1KeyPressW(Sender: TObject; var Key: WideChar);
begin
TntMemo2.Lines.Add(WideString('TntMemo1KeyPress: ') + Key);
end;
end.