0

このコードを使用して、仮想キーをWideStringに変換しています。

function VKeytoWideString (Key : Word) : WideString; 
var 
 WBuff         : array [0..255] of WideChar; 
 KeyboardState : TKeyboardState; 
 UResult       : Integer;
begin 
 Result := '';
 GetKeyBoardState (KeyboardState); 
 ZeroMemory(@WBuff[0], SizeOf(WBuff));
 UResult := ToUnicode(key, MapVirtualKey(key, 0), KeyboardState, WBuff, Length(WBuff), 0); 
 if UResult > 0 then
  SetString(Result, WBuff, UResult)
 else if UResult = -1 then
  Result := WBuff;
end; 

私のPCでは問題なく動作しますが、中国のPCでは次のようになります。

foo

漢字を羽生拼音に変換します。この関数は、ユーザーが実際に入力したいものではなく、実際にはキーボードの生の入力を返すと思います。

これをどのように処理すればよいですか?

4

2 に答える 2

2

KeyPressコメントによると、イベントを手動で変換する代わりにイベントを処理することで問題を回避する方法の例を次に示しますKeyDown。TNTコントロールはイベントを提供しませんが、WideChar KeyPress追加するのはかなり簡単です。理想的には、ここで行ったように派生クラスに拡張機能を配置するのではTTntMemoなくTTntForm、代わりにTNTソースコードを変更する必要があります。

フォームには2つのTTntMemoコントロールが含まれています。最初のキーを押すと、2番目のイベントがログに記録されます。

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.
于 2012-06-05T21:38:50.383 に答える
1

中国語の入力についてもあまり経験がありませんが、これがIME(Input Method Editor)のキックインだと思います。これにより、中国のユーザーは拼音を入力でき、それがイデオグラフィック文字に変換されます(そうでない場合は、 d 1000以上のキーを備えたキーボードが必要です...)

仮想キーコードはキーボードに直接関連しているため、必然的に、入力されたキーにのみ対応します。したがって、関数は正常に機能します。つまり、VKEYコードをWideCharに変換します。やりたいことをするために、拼音を文字に変換する2番目の関数を書く必要があります。

特に中国人のためにこれをしたいのなら、私はそこにこれをするための機能があるに違いない。より一般的で、ロケールや言語に依存しないようにしたい場合は、関連するTMemoのIMEとインターフェイスすることは可能かもしれませんが、そうであれば、私には手がかりがありません。私の最善の推測は、MSDNでIMEを検索することです。

しかし、hvdのコメントをエコーするために:ここで何を達成したいですか?

TMemoのテキストをコピーする方が簡単ではないでしょうか。

于 2012-06-05T07:01:07.040 に答える