VC6.0SP3 Win2Kです。
IEでもVCでもメニューを見ると「開く(O)... CTRL+O」
とありますが、この「...」ってどういう意味でしょう?
あるのと無いのがありますが。
またCTRL+Oでショートカットキーとなってますが、
これの設定方法が知りたいです。PretransrateMessage()で
やればよいのでしょうか?またメニュー上の「CTRL+O」は
自分で記述してるだけなのでしょうか?
以上宜しくお願いします。
「...」はMicrosoft が謳う Windows UI の標準で、簡単に言えば
「このメニューを選択すると詳細はダイアログが開く」ということを示します。
メニューのショートカット自体は、メニュー作成時に「&O」などと & 付きで入力すれ
ば、
O に下線がついて有効になると思います。
メニュー上の「CTRL+O」は自分で記述していると思われます。
Banさんありがとうございます。
>メニューのショートカット自体は、メニュー作成時に「&O」など
書き方が悪かったでしょうか。
現在、「ファイル(&F)」としサブに「開く(&O)」を設定してます。
ALT+F→ALT+Oで、確かにコモンダイアログが開きます。
しかし、CTRL+Oでは全く動きません。
ここでCTRL+Oで開くには、Pre~で、キー入力判定をして、
「開く(&O)」メニューで呼ばれるイベントプロシージャ(と言ってOK?)を
コールしてやればよいのかな?って事です。
「CTRL+O」そのものの文字列はプログラムで書いてるんですね。
どこかで設定すれば自動的に書かれるものかと考えていたので。
質問の内容がわかれば、再度ご回答頂けると幸いです。
宜しくお願い致しまする
> ここでCTRL+Oで開くには、Pre~で、キー入力判定をして、
> 「開く(&O)」メニューで呼ばれるイベントプロシージャ(と言ってOK?)を
> コールしてやればよいのかな?って事です。
読み違えてました。申し訳ないです。
それはPreTranslateをいじらなくとも、リソースの「アクセラレータ」で設定できます。
> 「CTRL+O」そのものの文字列はプログラムで書いてるんですね。
> どこかで設定すれば自動的に書かれるものかと考えていたので。
Wizard が作ってくるメニューでもハードコーディングしてありますし、
自動的に書いてくれるということはないと思いますが......。
# 動的に差し替えたいなら自分でメニューの表示メッセージを捕まえる?
VC++6sp6/WTL7.0では、CFrameWindowImplBase::m_hAccel に
アクセラレータのハンドルを渡す事で、アクセラレータは自動的に
切り替わりますが、メニューは自分で描写する必要があります。
アクセラレータ関連については、下記のAPIを調べてみてください。
LoadAccelerators
CreateAcceleratorTable
CFrameWindowImplBase::m_hAccel
は、いわゆる、CMainFrame::m_hAccel のことです。
それから、メニュー変更は、WM_INITMENUPOPUP のタイミングで良いようです。
Banさん
>リソースの「アクセラレータ」で設定できます。
了解です。早速やってみます。
RAPTさん
>CFrameWindowImplBase::m_hAccel にアクセラレータのハンドルを渡す事で、
あ。環境書き忘れてましたが、ダイアログベースなんです。
今後の為に覚えておきます。
ありがとうございました。
あぅ。「解決」押したのに詰まってしまった・・・。
すいません。
リソースに「Accelerator」追加して、
そのなかにID:ID_SC_OPEN キー:Ctrl+O タイプ:VIRTKEYとして
ClassWizardで、このIDのCOMMANDメッセージに、メニューから
「開く」を選択した場合の関数をコールしてみましたが、
CTRL+Oが効きません・・・。
この後に他にソース書かなきゃならないのでしょうか?
自己レスですいません。
http://www.ccn.aitai.ne.jp/~ccc/C++/MFCAccelerator.html
に解答がありました。
原因としてわかったのが、
AcceleratorのIDって「既存のメニューorボタンのID」なんですね。
アクセラレータ用に新規にIDをつけるものだと思ってました。
これでCTRL+Oでコモンダイアログが出来ました。
しかし、CTRL+Oで開いてファイル選択orキャンセルで「ポーン」と
音が鳴ってしまうんです。(裏でなんかキーが叩かれてるのでしょうか。)
メニューから開くを選択した場合はそんな音ならないのですが。
やればやるほど、新たな問題が発生してる気がします。
取りあえず「CTRL+O」でダイアログを開く事は出来たので、ヨシとします。
が、上の問題で何かお分かりの方いましたら、是非教えてください。
> それから、メニュー変更は、WM_INITMENUPOPUP のタイミングで良いようです
# PSDKならそれでいいと思うのですが、
# MFCだとON_UPDATE_COMMAND_UIのハンドらでSetTextする方がお行儀がいいのでは。
> が、上の問題で何かお分かりの方いましたら、是非教えてください。
確認はしてないですが、多分このあたりでは。
参照先のサイトは TranslateAccelerator の戻り値を見てませんが、
TranslateAccelerator が成功した場合、そのメッセージを他の処理に流しては
いけません。そのため、戻り値をきちんと見て、処理に成功したら
PreTranslate~の処理を中断してその戻り値で処理済の旨を返すべきです。
この処理がないので、普通の入力として多重処理されているのではないでしょうか。
Banさん
きちんと色々やってみてから書き込みすべきと猛省します。
参考のサイトは戻り値見てませんでした。気になってはいたのですが、
その通りだと思われます。よくよくMSDNを見たら、
>TranslateAccelerator 関数が 0 以外の値を返し、そのメッセージが変換された場合は、
>TranslateMessage 関数を使ってそのメッセージをもう一度処理するべきではありません。
こんな事書いてあったので、下記を加えたところ音がならなくなりました。
// アクセラレータキーの処理
BOOL bRtn = TranslateAccelerator(m_hWnd, hAccel, pMsg);
if (bRtn != 0) return TRUE;
なんか繋がってるとは言え、「メニューの表記」から「メッセージの処理」に話が
シフトしてしまいましたが、お蔭様でアクセラレータキーの使い方を覚える事が
出来ました。
心よりお礼申し上げます。ありがとうございました。
また何かの際には宜しくお願い致します。