よろしくお願いします。
次の記事で 2 通りの回避策を把握できました。
文字列に「&」を代入して表示するとアンダーラインになるのを回避するには?
https://www.petitmonte.com/bbs/answers?question_id=6610
文字列置換で対処する場合、「&」の他に対策が必要な文字があるでしょうか?
このような「表示時点で文字が変化する振る舞い」の仕様(対象文字)の所在(ヘルプなど)を教えてください。
また、このような文字をまとめてエスケープする関数はあるでしょうか?
どうぞ、よろしくお願いします。
まず、下線がついた文字はアクセスキーとかアクセラレータとかショートカットキーとか呼ばれるもので
(この概念を表す用語は何度も変更されていますが、以後はアクセスキーと呼ぶことにします)
Altとその文字を一緒に押すことで、素早くメニュー項目を実行したりダイアログ上の項目に移動するためのものです。
一般にはコントロールやラベルのキャプションで、文字の前に「&」を付けるとその文字がアクセスキーになります。
もちろん、メッセージボックスのテキストでアクセスキーを使う必要はまったくないわけですが
VCLのShowMessage/MessageDlgはどうやらラベルを使って独自実装しているため「&」がアクセスキー扱いされてしまうようです。
TLabelであればShowAccelChar=falseにすれば「&」の特別扱いをやめされられますが、このケースだとそういう制御は難しそうですね。
> 文字列置換で対処する場合、「&」の他に対策が必要な文字があるでしょうか?
> このような「表示時点で文字が変化する振る舞い」の仕様(対象文字)の所在(ヘルプなど)を教えてください。
メニュー項目の場合は他にもタブ文字とか|とか\036とか色々あった気がしますが、ラベルでは「&」以外の特殊文字はないはずです。
このあたりは、もし厳密に知りたければMSDNなりWindowsプログラミングガイドなりで「リソーススクリプト」の仕様を調べれば出てくるかと。
>また、このような文字をまとめてエスケープする関数はあるでしょうか?
StripHotKeyという関数はありますが、これは「&」を文字列から取り除くものなので目的とは合わなさそうですね。
あくまでShowMessageにこだわるつもりなら、TLabelで特別扱いされる&だけStringReplaceで置き換えてやればいいと思います。
tor さん、ありがとうございます。
・ShowMessage/MessageDlg が TLabel を使っている
・そのため「&」がアクセスキー扱いされる
と理解でき、納得できました。
メッセージダイアログなのにどうして自動で下線にする必要があるのか、その意図を読みきれず、同時に他の振る舞いの可能性も見通せず混乱していました。
上記を理解できて、TLabel に起因する影響範囲の説明も受けられて、すっきりしました。
ShowMessage にはこだわらないのですが、開発済みのコードで ShowMessage を使用した箇所の影響を考えていました。
その点はご指摘のように StringReplace で「&」を「&&」に文字列置換すれば回避できますね。
TEdit で 入力した内容を TLabel に表示する際にも同じ現象が起きますから、こちらは ShowAccelChar=false にする配慮で大丈夫ですね。
補足します。
質問で紹介した記事に「ポムヌンティウス」さんが ShowMessage/MessageDlg のアクセスキーを抑制する代替関数を投稿してくださいました。
※結果的に2重投稿の形となってしまいご不便をおかけします。
ツイート | ![]() |