メニューの表記

[戻る]
める 2005/07/24(日) 16:28:49
VC6.0SP3 Win2Kです。

IEでもVCでもメニューを見ると「開く(O)...       CTRL+O」
とありますが、この「...」ってどういう意味でしょう?
あるのと無いのがありますが。


またCTRL+Oでショートカットキーとなってますが、
これの設定方法が知りたいです。PretransrateMessage()で
やればよいのでしょうか?またメニュー上の「CTRL+O」は
自分で記述してるだけなのでしょうか?

以上宜しくお願いします。

Ban 2005/07/24(日) 17:31:02
「...」はMicrosoft が謳う Windows UI の標準で、簡単に言えば
「このメニューを選択すると詳細はダイアログが開く」ということを示します。

メニューのショートカット自体は、メニュー作成時に「&O」などと & 付きで入力すれ
ば、
O に下線がついて有効になると思います。
メニュー上の「CTRL+O」は自分で記述していると思われます。

める 2005/07/24(日) 19:52:51
Banさんありがとうございます。

>メニューのショートカット自体は、メニュー作成時に「&O」など

書き方が悪かったでしょうか。
現在、「ファイル(&F)」としサブに「開く(&O)」を設定してます。
ALT+F→ALT+Oで、確かにコモンダイアログが開きます。
しかし、CTRL+Oでは全く動きません。

ここでCTRL+Oで開くには、Pre〜で、キー入力判定をして、
「開く(&O)」メニューで呼ばれるイベントプロシージャ(と言ってOK?)を
コールしてやればよいのかな?って事です。

「CTRL+O」そのものの文字列はプログラムで書いてるんですね。
どこかで設定すれば自動的に書かれるものかと考えていたので。
質問の内容がわかれば、再度ご回答頂けると幸いです。
宜しくお願い致しまする

Ban 2005/07/24(日) 20:21:12
> ここでCTRL+Oで開くには、Pre〜で、キー入力判定をして、
> 「開く(&O)」メニューで呼ばれるイベントプロシージャ(と言ってOK?)を
> コールしてやればよいのかな?って事です。

読み違えてました。申し訳ないです。
それはPreTranslateをいじらなくとも、リソースの「アクセラレータ」で設定できます。


> 「CTRL+O」そのものの文字列はプログラムで書いてるんですね。
> どこかで設定すれば自動的に書かれるものかと考えていたので。

Wizard が作ってくるメニューでもハードコーディングしてありますし、
自動的に書いてくれるということはないと思いますが......。
# 動的に差し替えたいなら自分でメニューの表示メッセージを捕まえる?

RAPT 2005/07/24(日) 20:45:00
VC++6sp6/WTL7.0では、CFrameWindowImplBase::m_hAccel に
アクセラレータのハンドルを渡す事で、アクセラレータは自動的に
切り替わりますが、メニューは自分で描写する必要があります。

アクセラレータ関連については、下記のAPIを調べてみてください。
LoadAccelerators
CreateAcceleratorTable

RAPT 2005/07/24(日) 20:48:23
CFrameWindowImplBase::m_hAccel
は、いわゆる、CMainFrame::m_hAccel のことです。

それから、メニュー変更は、WM_INITMENUPOPUP のタイミングで良いようです。

める 2005/07/24(日) 21:12:22
[[解決]]
Banさん
>リソースの「アクセラレータ」で設定できます。
了解です。早速やってみます。

RAPTさん
>CFrameWindowImplBase::m_hAccel にアクセラレータのハンドルを渡す事で、
あ。環境書き忘れてましたが、ダイアログベースなんです。
今後の為に覚えておきます。

ありがとうございました。

める 2005/07/24(日) 21:34:07
あぅ。「解決」押したのに詰まってしまった・・・。
すいません。

リソースに「Accelerator」追加して、
そのなかにID:ID_SC_OPEN キー:Ctrl+O タイプ:VIRTKEYとして
ClassWizardで、このIDのCOMMANDメッセージに、メニューから
「開く」を選択した場合の関数をコールしてみましたが、
CTRL+Oが効きません・・・。

この後に他にソース書かなきゃならないのでしょうか?

める 2005/07/24(日) 22:02:42
[[解決]]
自己レスですいません。

http://www.ccn.aitai.ne.jp/~ccc/C++/MFCAccelerator.html

に解答がありました。

原因としてわかったのが、
AcceleratorのIDって「既存のメニューorボタンのID」なんですね。
アクセラレータ用に新規にIDをつけるものだと思ってました。
これでCTRL+Oでコモンダイアログが出来ました。

しかし、CTRL+Oで開いてファイル選択orキャンセルで「ポーン」と
音が鳴ってしまうんです。(裏でなんかキーが叩かれてるのでしょうか。)
メニューから開くを選択した場合はそんな音ならないのですが。
やればやるほど、新たな問題が発生してる気がします。

取りあえず「CTRL+O」でダイアログを開く事は出来たので、ヨシとします。
が、上の問題で何かお分かりの方いましたら、是非教えてください。

Ban 2005/07/24(日) 22:19:06
> それから、メニュー変更は、WM_INITMENUPOPUP のタイミングで良いようです

# PSDKならそれでいいと思うのですが、
# MFCだとON_UPDATE_COMMAND_UIのハンドらでSetTextする方がお行儀がいいのでは。


> が、上の問題で何かお分かりの方いましたら、是非教えてください。

確認はしてないですが、多分このあたりでは。

参照先のサイトは TranslateAccelerator の戻り値を見てませんが、
TranslateAccelerator が成功した場合、そのメッセージを他の処理に流しては
いけません。そのため、戻り値をきちんと見て、処理に成功したら
PreTranslate〜の処理を中断してその戻り値で処理済の旨を返すべきです。
この処理がないので、普通の入力として多重処理されているのではないでしょうか。

める 2005/07/24(日) 23:07:58
Banさん

きちんと色々やってみてから書き込みすべきと猛省します。
参考のサイトは戻り値見てませんでした。気になってはいたのですが、
その通りだと思われます。よくよくMSDNを見たら、

>TranslateAccelerator 関数が 0 以外の値を返し、そのメッセージが変換された場合は、
>TranslateMessage 関数を使ってそのメッセージをもう一度処理するべきではありません。

こんな事書いてあったので、下記を加えたところ音がならなくなりました。

// アクセラレータキーの処理
BOOL bRtn = TranslateAccelerator(m_hWnd, hAccel, pMsg);
if (bRtn != 0) return TRUE;

なんか繋がってるとは言え、「メニューの表記」から「メッセージの処理」に話が
シフトしてしまいましたが、お蔭様でアクセラレータキーの使い方を覚える事が
出来ました。

心よりお礼申し上げます。ありがとうございました。
また何かの際には宜しくお願い致します。

古いスレッドには追加発言できません。