アクセラレーターキーについて


earthed  2006-08-01 02:22:50  No: 22777  IP: 192.*.*.*

フォーム上でボタンやチェックボックス等にフォーカスがある場合に
キーを押すと、Altキーを一緒に押していなくてもフォーム内のコンポーネントに
割り当てたアクセラレーターキーが応答してしまいます。
この現象を回避するにはどのようにしたら良いのでしょうか?

編集 削除
Syake  2006-08-01 11:43:33  No: 22778  IP: 192.*.*.*

OnKeyDownやOnKeyUpでTShiftStateで判定されたらいかがでしょうか?

編集 削除
earthed  2006-08-01 12:47:35  No: 22779  IP: 192.*.*.*

フォームやコンポーネントのキーイベントよりも先にアクセラレーターが
機能するので、キーイベントでは制御できません。

編集 削除
Syake  2006-08-01 16:10:04  No: 22780  IP: 192.*.*.*

失礼しました。
以前どこかで見たような。

procedure WM_KEYDOWN_MSG( var KeyMsg : TWMKEYDOWN ); message CM_CHILDKEY;
を追加して、ここで処理することができそうです。
procedure TFrom1.WM_KEYDOWN_MSG( var Msg : TWMKEYDOWN );
begin
  //ここで判定
end;
これなら、まずここで処理できそうです。

編集 削除
Syake  2006-08-01 16:21:53  No: 22781  IP: 192.*.*.*

一応、簡単に
Button1.Caption := XXXX(&A)で

procedure TfrmMain.WMKEYDOWNMSG(var Msg: TWMKEYDOWN);
begin
   if Button1.Focused = True then
   begin
      with Msg do
      begin
         if CharCode = 65 then
         begin
            Result := 1;
         end;
      end;
   end;
   inherited;
end;

編集 削除
Syake  2006-08-01 17:10:16  No: 22782  IP: 192.*.*.*

たびたび、すいません。
上記だけでは、[Alt]Keyを押している時も無視されます。


   function WndProc(var M: TMessage):Boolean;
private
    { Private 宣言 }

    FShiftKey :TShiftState;
    procedure WM_KEYDOWN_MSG( var KeyMsg : TWMKEYDOWN ); message CM_CHILDKEY;

{略}

procedure TFrom1.FormCreate(Sender: TObject);
begin
   Application.HookMainWindow(WndProc);
end;

function TFrom1.WndProc(var M: TMessage):Boolean;
begin
   FShiftKey := KeyDataToShiftState(TWMKey(m).KeyData);   
end;

procedure TForm1.WMKEYDOWNMSG(var Msg: TWMKEYDOWN);
begin
   if Button1.Focused = True then
   begin
      with Msg do
      begin     
         if (CharCode in [65..90]) and ((FShiftKey <> [ssAlt]) then
         begin
            Result := 1;
         end;
      end;
   end;
   inherited;
end;

です。

編集 削除
earthed  2006-08-01 23:29:30  No: 22783  IP: 192.*.*.*

ありがとうございます。
ちょっとコーディングに時間が掛かりそうなので、後日検証して結果を書き込み
ます。

編集 削除