メニューアクセラレータキーが表示されない(Delphi 2009)
-
07-07-2019 - |
質問
ベストを尽くしましたが、ここで何が起こったのかわかりません。 Delphi 4で問題なく動作しました。Delphi2009にアップグレードした後、これが動作するはずなのか、それが問題なのかわかりません。
これは、Delphi 2009のデザインモードで私のプログラムのメニューがどのように見えるかです。
メインメニューとファイルサブメニューのすべての単語に下線が付いていることに注意してください。こうなるはずです。この下線付きの文字はアクセラレータキーと呼ばれ、Windowsアプリケーションの標準です。そのため、Altキーとその文字を使用して、マウスではなくキーボードでメニュー項目とサブメニュー項目をすばやく選択できます。
"&"を使用してこの方法で取得しますアイテムのキャプションの一部としての文字、例:Save& As ...
アプリケーションを実行し、マウスを使用して[ファイル]メニューを開くと、次のようになります。
文字はメインメニューでは下線が引かれますが、[ファイル]メニューでは下線が引かれません。
代わりに、Alt-Fキーを使用して[ファイル]サブメニューを開くと、次のように表示されます。
およびすべてのアクセラレータキー文字に適切に下線が引かれます。
AutoHotKeysオプションを試しましたが、それは問題ではありません。
以前に誰かがこの問題に遭遇したことはありますか? 2番目の画像の例は、私が知らない正しい動作ですか?または、私が見逃したかもしれないいくつかのオプションまたはコーディングミスがありますか?
2009年11月(1年後):mghieはこの根本原因を突き止め、問題を突き止めたようです。以下の受け入れられた答えを参照してください。
解決
Altキーが押されていない限り、通常これらのアクセラレータを非表示にする標準のWindows設定(表示プロパティの下)があります。 Alt + F10でメニューを開くとそれらが表示される理由を説明します。たぶんそれが原因ですか?
[編集]:いいえ、そうではありません。試したところ、メニュー項目のある単純なTFormにアクセラレータが表示されていますが、TImageListを追加して単一のメニュー項目のImageIndexを設定するか、OwnerDrawをtrueに設定すると、アクセラレータの下線が消えます。これは本当にVCLのバグだと思います。
ところで、これはWindows XP上にあります。
回避策:
Windows XP 64でDelphi 2009を使用してこれをデバッグしましたが、アクセラレーターが見つからない根本的な原因は、Windowsが ODS_NOACCEL
フラグが設定された WM_DRAWITEM
メッセージを送信することです、システムが常にアクセラレータを表示するように設定されている場合は、そうすべきではありません。したがって、これはVCLのバグではなく、VCLが回避できないWindowsの問題であると言えます。
ただし、独自のコードで回避することができます。メッセージをVCLに渡す前にフラグをリセットする必要があります。ウィンドウプロシージャをオーバーライドします
protected
procedure WndProc(var Message: TMessage); override;
そのように:
procedure TYourForm.WndProc(var Message: TMessage);
const
ODS_NOACCEL = $100;
var
pDIS: PDrawItemStruct;
ShowAccel: BOOL;
begin
if (Message.Msg = WM_DRAWITEM) then begin
pDIS := PDrawItemStruct(Message.LParam);
if (pDIS^.CtlType = ODT_MENU)
and SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, @ShowAccel, 0)
then begin
if ShowAccel then
pDIS^.itemState := pDIS^.itemState and not ODS_NOACCEL;
end;
end;
inherited;
end;
これはデモンストレーションコードのみです。 WM_DRAWITEM
メッセージを受信するたびに SystemParametersInfo()
を呼び出さないでください。ただし、プログラムの開始時に1回、次にプログラムのたびに WM_SETTINGCHANGE
メッセージを受信します。
他のヒント
これは「機能」ですWindows 2000で導入された:
古い新機能: Windowsがキーボードアクセラレータを非表示にする理由デフォルトで長方形をフォーカスしますか?
Delphi 4はこのWindows機能をサポートしていなかったようです。
2000およびXPメニューにアクセラレータキーを表示するには、デスクトップ上の空の場所を右クリックし、[プロパティ]を選択し、[外観]タブをクリックし、[効果]で[Altキー。 [OK]を2回クリックします。
Vistaでの実行方法がわからない。
Vistaのメモ帳でも同じ動作をするため、Delphiで生成されたバグではないと思います。また、Delphi自体にも...
私はあなたの質問の前に注意を払わなかったことを告白しなければなりません。ご指摘いただきありがとうございます。
ジム・マッキースが上記のように(正しく)述べたように、これは「設計による」ものです。動作。メニューがキーボードアクションによってトリガーされる場合、アクセラレータが表示されますが、マウスによってトリガーされる場合、アクセラレータは意図的に表示されません。
常にアクセラレータを表示するようにXPを構成しましたが、そのオプションを変更した簡単なテストにより、メニューにも下線が表示されないことが確認されました(Visual Studioは期待どおりに応答し、マウスの使用時に下線は表示されません)。ただし、Microsoft Officeはこの設定を無視し、常に下線を表示します。したがって、Delphiでのメニューの描画方法のバグのように見えます(私自身はDelphiの経験がありません)。
Vistaのオプションも見つけました: http://www.vistax64.com/vista-general/42125-always-show-menu-underline-keyboard-accelerators.html
新しいEase of Access Centerでこれをオンにできます(コントロールに移動します パネルで、[簡単なアクセス]をクリックし、[簡単なアクセスセンター]をクリックします)。に Ease of Access Centerで、[キーボードを使いやすくする]をクリックし、 一番下で、下線のキーボードショートカットとアクセスを選択します キーチェックボックス。
さらに調査を行っていると、Delphiフォーラムでこの関連バグが見つかりました。 http: //qc.codegear.com/wc/qcmain.aspx?d=37403
あなたの場合、子ウィンドウ(描画メニュー)が親ウィンドウからWM_UIUPDATESTATEメッセージを取得していないか、処理していないように見えます。これがアクセラレータによる再描画の原因です。