サブクラス化したCStaticでUPDATE_COMMAND_UIの処理 – プログラミング – Home

サブクラス化したCStaticでUPD...
 
通知
すべてクリア

[解決済] サブクラス化したCStaticでUPDATE_COMMAND_UIの処理


たいちう
 たいちう
(@たいちう)
ゲスト
結合: 23年前
投稿: 662
Topic starter  

お世話になります。たいちうです。

スタティックコントロールでポップアップメニューを表示させているのですが、
メニューアイテムの有効無効の切替えのためのON_UPDATE_COMMAND_UIの
マッピングがうまくできません。TRACEで確認すると、メニューアイテムが
クリックされたときにON_UPDATE_COMMAND_UIで関連付けた関数が呼ばれています。

原因のわかる方、お教え願います。
以下、詳しく。

・Windows2000/XP/98 VC6.0+SP5
・MFC SDIでCFormView使用
・CStaticを継承させたクラスCHogeを作成し、
 CFormViewに貼り付けたstaticのコントロールメンバ変数とする。
・CHogeは、ModifyStyleでSS_NOTIFYを設定。
 OnContextMenuでポップアップメニューを表示。ポップアップの所有はthis(CHoge)。
・CHogeでON_COMMANDを追加し、CHogeのメンバ関数でメッセージを処理。

ここまでは問題なくできています。
つまり、CFormView上のスタティックコントロールを右クリックして、
ポップアップメニューを表示させ、メニューアイテムを選択すると、
CHogeのメンバ関数が呼ばれています。

メニューアイテムを無効にするつもりでON_UPDATE_COMMAND_UIとCHogeのメンバ
関数を新しく追加したのですが、TRACEで確認すると、関数が呼ばれるのはクリック
したときでON_COMMANDの方の関数の直前に呼ばれます。
無効にするつもりのアイテムも選択できてしまうのが現状です。

OnContextMenuでアイテムを無効にすることはできましたので、ON_UPDATE_COMMAND_UIに
こだわる理由はないのですが、何が間違っているのか気になっています。
ちょっとややこしい質問かもしれませんが、識者の方々、もしお時間が許しましたら、
その、あれしてください。よろしくお願いします。


引用未解決
トピックタグ
Wanderer
 Wanderer
(@Wanderer)
ゲスト
結合: 22年前
投稿: 35
 

多少違うかもしれませんが大筋は合っていると思いますのでご参考までに。

メニューが表示されるときに WM_INITMENUPOPUP が親ウインドウに届きます。
CFrameWndにはこれの独自処理ハンドラがあり、ここでメニューのUpdateCmdUI
処理が行なわれているようです。

しかしたいちうさんの場合ポップアップの所有をCHogeとしているため
WM_INITMENUPOPUPの独自ハンドラを持っていないCStaticでは、UpdateCmdUI
処理されないのだと思います。

また、メニュー選択時にはWM_COMMANDがポストされますが、CWnd::OnCommand()
では無効なアイテムのコマンド実行を防止するために、先に一度UpdateCmdUI処
理を呼び出してから、ユーザーのコマンドハンドラを呼び出すようになっている
ようです。これはCWndでの処理なので、CStaticでも処理されるのでしょう。

親をCFrameWnd派生クラスにすればUpdateCmdUI機構は働くと思いますが、
CHoge内で処理を行なうということであれば、WM_CONTEXTMENUか、WM_INITMENUPOPUP
内で独自に処理を実装することになりそうですね。


返信引用
たいちう
 たいちう
(@たいちう)
ゲスト
結合: 23年前
投稿: 662
Topic starter  

Wandererさま、回答有難うございます。
回答は付かないのかなとそろそろ思い始めていました。

> メニューが表示されるときに WM_INITMENUPOPUP が親ウインドウに届きます。
> CFrameWndにはこれの独自処理ハンドラがあり、ここでメニューのUpdateCmdUI
> 処理が行なわれているようです。
>
> しかしたいちうさんの場合ポップアップの所有をCHogeとしているため
> WM_INITMENUPOPUPの独自ハンドラを持っていないCStaticでは、UpdateCmdUI
> 処理されないのだと思います。

確認しましたが、CFrameWnd::OnInitMenuPopup()の中でCCmdUI::DoUpdate()を呼び出して、
CN_UPDATE_COMMAND_UIメッセージを発生させているようですね。
CStatic::OnInitMenuPopup()ではそんな処理はありませんでした。

> また、メニュー選択時にはWM_COMMANDがポストされますが、CWnd::OnCommand()
> では無効なアイテムのコマンド実行を防止するために、先に一度UpdateCmdUI処
> 理を呼び出してから、ユーザーのコマンドハンドラを呼び出すようになっている
> ようです。これはCWndでの処理なので、CStaticでも処理されるのでしょう。

なるほど。確かにUpdateCmdUIのみを記述したときには呼ばれませんでした。

> 親をCFrameWnd派生クラスにすればUpdateCmdUI機構は働くと思いますが、
> CHoge内で処理を行なうということであれば、WM_CONTEXTMENUか、WM_INITMENUPOPUP
> 内で独自に処理を実装することになりそうですね。

はい。クラス内で処理したいのでWM_CONTEXTMENUで処理しようと思います。
有難うございました。おかげさまで理解を少し深めることができました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました