Migaro. 技術Tips

                       

ミガロ. 製品の技術情報
IBMiの活用に役立つ情報を掲載!


【Delphi】同じキーコードのキーの判別方法

今回は、テンキーのEnterと通常のEnterや、左右CTRLキーのような
同じキーコードを持った複数のキーの判別についてご説明したいと思います。

通常のキー判定にはKeyPressやKeyDownイベントを使用しますが、
これらのイベントに提供されるキーコードは
EnterならVK_RETURN、CTRLならVK_CONTROLといった同じ値が取得されるため、
複数ある場合は判別ができません。

今回はApplication変数のOnMessageイベントを使用する方法で、
この判別を行うためのサンプルを作成していきます。

Application変数は自動生成されるアプリケーションレベルの情報を持った変数です。
通常はこのような変数のイベントはコードでイベントの割り当てを行いますが、
Application変数に関してはTApplicationEventsという専用のコンポーネントが用意されています。
こちらを使用してOnMessageイベントを設定することでメッセージを拾います。

 

まず、フォームのグローバル変数に「LeftDown」というプロパティを追加します。

// ※宣言部
  TForm1 = class(TForm)
    ApplicationEvents1: TApplicationEvents;
    procedure ApplicationEvents1Message(var Msg: tagMSG;
      var Handled: Boolean);
  private
    { Private 宣言 }
    FLeftDown: Boolean;
  public
    { Public 宣言 }
    property LeftDown: Boolean read FLeftDown;
  end;

 

次にTApplicationEventsのOnMessageイベントで以下のようなロジックを記述し、
CTRLなどのキー押下時に左右の判断を行い、LeftDown変数にセットさせます。
また今回はCTRL以外にもEnter・Shiftキーにも対応させています。

// アプリケーションのメッセージ拾得時イベント
procedure TForm1.ApplicationEvents1Message(var Msg: TMsg; var Handled: Boolean);
begin
  // メッセージ種別の判別を行う
  if Msg.message = WM_KEYDOWN then
  begin
    // キーの種類を確認する
    case Msg.wParam of
      // Ctrlキー
      VK_CONTROL:
      begin
        // 左Controlが押されたときにTrueを
        // 右Controlが押されたときにFalseをセットする
        FLeftDown := ((Msg.lParam AND $01000000) = 0);
      end;

      // Enterキー
      VK_RETURN:
      begin
        // 通常のEnterが押されたときにTrueを
        // テンキーのEnterが押されたときにFalseをセットする
        FLeftDown := ((Msg.lParam AND $01000000) = 0);
      end;

      // Shiftキー
      VK_SHIFT:
      begin
        // 左Shiftが押されたときにTrueを
        // 右Shiftが押されたときにFalseをセットする
        FLeftDown := ((Msg.lParam AND $0100000) = 0); // ※条件が少し異なる
      end;
    end;
  end;
end;

 

画面内で使用する場合は以下のようなイメージとなります。
(ここではShowMessageしているだけですが、実際の処理に読み換えて下さい。)

// フォーム内のキー押下時処理
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin

  // キーの左右を判定した上で処理を分岐する
  // ※画面内のどこからでも反応するよう、フォームのKeyPreviewをTrueにしておく
  case Key of
    // Ctrlキー
    VK_CONTROL:
    begin
      if FLeftDown then
        ShowMessage('左Controlが押されました。')
      else
        ShowMessage('右Controlが押されました。');
    end;

    // Enterキー
    VK_RETURN:
    begin
      if FLeftDown then
        ShowMessage('通常のEnterが押されました。')
      else
        ShowMessage('テンキーのEnterが押されました。');
    end;

    // Shiftキー
    VK_SHIFT:
    begin
      if FLeftDown then
        ShowMessage('左Shiftが押されました。')
      else
        ShowMessage('右Shiftが押されました。');
    end;
  end;
end;

 

この方法を使えば、カスタムコンポーネントの作成などの手間も不要です。

今回の題材の右CTRL押下時のみ処理を行いたい、
テンキー側についている方のEnterだけをTabに置き換えたい、
といった局面で活用できますので、お試しください。

 

 

(ミガロ.情報マガジン「MIGARO News!!」Vol.034~035 2003年11~12月号より)