4

タッチスクリーンのキーパッドのように機能するフォームを構築しています。現時点で私が抱えている問題は、「1」ボタンなどのボタンを押すと、その文字「1」を編集ボックスに追加する必要があることです。編集ボックスには、既に押されたキーが表示されます。今私が経験している問題は、人がキーを押すと、編集ボックスに既に表示されている文字列に文字を追加できるが、カーソルが編集ボックスの前面に移動し、背面に表示されないことです。次のコードを使用して、編集ボックスに文字を追加します。

edtPassword.text := edtPassword.text + key;

編集ボックスの最後に文字を追加するだけですが、編集ボックスの最後にカーソルを移動するにはどうすればよいですか。

さらに、バックスペース ボタンもあります。編集ボックスをクリックした場合、編集ボックス内の文字列の最後の文字を消去するには、どのコードを使用しますか?

Delphi XE2を使用しています

4

2 に答える 2

6

免責事項:

そのまま質問に答えているわけではありません。仮想キーボードが必要な場合に、むしろ従う方法を提案しようとしています。

1.既製のコンポーネントはどうですか?

TTouchKeyboard仮想キーボードを表す VCL コンポーネントであるコンポーネントを使用することをお勧めします。つまり、すでに Delphi ディストリビューションの一部となっているものを開発しているということです。バージョン 2010 以降の Delphi の一部ですが、どのディストリビューションに含まれているかはわかりません。

2. 見栄えが悪いので、自分で作成します。

TTouchKeyboardコンポーネントを初めて見たとき、所有者が描画できることを望んでいました。残念ながらそうではありません。その場合、近いうちにまたは後で使用する可能性のある別のコンポーネントでこのようなケースを解決するのではなく、キーストロークを自分でシミュレートしようとします。

2.1. 独自の方法でキーストロークをシミュレートする方法は?

次のコードは、関数を使用してキーストロークをシミュレートします。これは、コンポーネントSendInputで使用されるコードに基づいています。TTouchKeyboard

type
  TKeyState = (ksDown, ksUp);

function SendInputKey(AVirtualKey: Integer; AScanCode: Integer;
  AKeyState: TKeyState): Boolean;
var
  Input: TInput;
begin
  Input.Itype := INPUT_KEYBOARD;
  if (AVirtualKey = -1) and (AScanCode >= 0) then
  begin
    Input.ki.wVk := MapVirtualKey(AScanCode, MAPVK_VSC_TO_VK);
    Input.ki.wScan := AScanCode;
  end
  else if (AVirtualKey >= 0) and (AScanCode = -1) then
  begin
    Input.ki.wVk := AVirtualKey;
    Input.ki.wScan := MapVirtualKey(AVirtualKey, MAPVK_VK_TO_VSC);
  end
  else if (AVirtualKey >= 0) and (AScanCode >= 0) then
  begin
    Input.ki.wVk := AVirtualKey;
    Input.ki.wScan := AScanCode;
  end;
  case AKeyState of
    ksDown: Input.ki.dwFlags := 0;
    ksUp: Input.ki.dwFlags := KEYEVENTF_KEYUP;
  end;
  Result := SendInput(1, Input, SizeOf(TInput)) = 1;
end;

そして、上記の関数の使い方。この関数には、仮想キー、スキャン コード、またはその両方を渡すことができます。いずれかが不明な場合は、-1 の値を渡すと、キー コードが関数によって追加でマップされMapVirtualKeyます。次の例は、 を送信してから を送信する方法を示していBackspaceますShift + A

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
  SendInputKey(VK_BACK, -1, ksDown);
  SendInputKey(VK_BACK, -1, ksUp);
  SendInputKey(VK_SHIFT, -1, ksDown);
  SendInputKey(Ord('A'), -1, ksDown);
  SendInputKey(Ord('A'), -1, ksUp);
  SendInputKey(VK_SHIFT, -1, ksUp);
end;

2.2. 禁止された方法でキーストロークをシミュレートする方法は?

また、参照に逆らってSendKeyfromVcl.Touch.Keyboardユニットを使用することもできます。参照には、SendKeyは内部で使用され、呼び出されるべきではないと記載されていますが、ユニットの外部で表示されます。大胆な場合は、次のように使用できます。

uses
  Vcl.Touch.Keyboard, Vcl.Touch.KeyboardTypes;

procedure TForm1.SpeedButton1Click(Sender: TObject);
var
  KeyData: TKeyData;
begin
  KeyData := VKey(VK_BACK, -1);
  SendKey(KeyData, ksDown);
  SendKey(KeyData, ksUp);
  KeyData := VKey(VK_SHIFT, -1);
  SendKey(KeyData, ksDown);
  KeyData := VKey(Ord('A'), -1);
  SendKey(KeyData, ksDown);
  SendKey(KeyData, ksUp);
  KeyData := VKey(VK_SHIFT, -1);
  SendKey(KeyData, ksUp);
end;

2.3. 別のビューでキーストロークをシミュレートする方法は?

于 2012-09-24T13:23:20.287 に答える
3

あなたは試すことができます:

edtPassword.Text := edtPassword.Text + key;
edtPassword.SelStart := Length(edtPassword.Text);
edtPassword.SelLenght := 0;

また、次のように、編集ウィンドウ ハンドルにメッセージを投稿することもできます。

PostMessage(edtPassword.Handle, WM_KEYDOWN, VK_END, 0);
PostMessage(edtPassword.Handle, WM_KEYUP, VK_END, 0);
PostMessage(edtPassword.Handle, WM_CHAR, StrToInt(key), 0);

バックスペースに関しては、カーソルが仮想であるため、テキストの最後の記号を削除するだけで削除をシミュレートできます。

キーパッドに矢印キーを含める予定がある場合は、カーソルの現在の位置を計算し、テキストの末尾ではなく、カーソル値 (オフセット) に対応する任意の位置で記号を削除する必要があります。

于 2012-09-23T17:24:23.833 に答える