WM_CONTEXTMENUを親よりあとに受け取りたい

解決


ひる  2012-03-12 22:33:08  No: 73229  IP: 192.*.*.*

あるCWnd派生のウィンドウクラスを作成し、
その中でWM_CONTEXTMENUも処理しているのですが、
ここにハンドラを入れてしまうと、フォーカスを持っているときに、
そのウィンドウを使っている親ウィンドウやダイアログが
自身のコンテキストメニューを出すことができなくなってしまいます。

エディットボックスが勝手に「右から左に読む」などのメニューを
出してしまうのと同じような流れだと思われます。

ウィンドウ自身のコンテキストメニューは、
親ウィンドウが誰もWM_CONTEXTMENUを処理しなかったときに
デフォルトの処理として出すようにできればと思っているのですが、
そのようなWM_CONTEXTMENUの流れを実現することはできるのでしょうか?

編集 削除
オショウ  2012-03-14 21:18:07  No: 73230  IP: 192.*.*.*

wParamに入っているhwndを利用して判断されてますか?
してないなら、WM_CONTEXTMENUの仕様を再確認してください。

以上。参考まで

編集 削除
ひる  2012-03-15 09:39:08  No: 73231  IP: 192.*.*.*

> wParamに入っているhwndを利用して判断されてますか?

もちろんCWnd派生クラス::OnContextMenu()のpWndはthisと一致します。
ただ、ここで自身でコンテキストメニューを出す前に、
親ウィンドウを優先させたいのです。

ここでなにもせずに

void CWnd派生クラス::OnContextMenu(CWnd* pWnd, CPoint point)
{
    CWnd::OnContextMenu(pWnd, point);
}

としたり、メッセージマップのON_WM_CONTEXTMENU()を削除してしまえば、
親のOnContextMenu()まで届くのはわかっていますが、
それをやってしまうと、親が処理しなかったときにも
自身のコンテキストメニューを出せなくなってしまいます。

編集 削除
YuO  2012-03-15 09:42:51  No: 73232  IP: 192.*.*.*

> 親ウィンドウが誰もWM_CONTEXTMENUを処理しなかったときに
> デフォルトの処理として出すようにできればと思っているのですが、
> そのようなWM_CONTEXTMENUの流れを実現することはできるのでしょうか?

無理です。
WM_CONTEXTMENUを処理したかどうかを知る術がありません。
さらに,DefWindowProcは親ウィンドウにWM_CONTEXTMENUを投げます。
このため,逆の流れを作るとコンテキストメニューを複数開こうとしたり,メッセージが循環したりすることになります。

MSDN: WM_CONTEXTMENU message
http://msdn.microsoft.com/en-us/library/windows/desktop/ms647592.aspx
> Return value
> No return value.
> Remarks
> If a window is a child window, DefWindowProc sends the message to the parent.

編集 削除
ひる  2012-03-15 10:41:20  No: 73233  IP: 192.*.*.*

> 無理です。
> WM_CONTEXTMENUを処理したかどうかを知る術がありません。
> さらに,DefWindowProcは親ウィンドウにWM_CONTEXTMENUを投げます。

そうですか、WM_CONTEXTMENUだけでは実現できないのですね。

仕方がないので、CWnd派生クラスのOnContextMenu()の中で、
「あなたのほうでコンテキストメニュー出したいですか?」
といった独自のメッセージを親ウィンドウに送り、
親が「はい」と言ってきたらそのままCWnd::OnContextMenu()に渡し、
親が無視したり「いいえ」と言ってきたら
自身でデフォルトのコンテキストメニューを出すようにしてみました。

ちょっと面倒ですが、これでちゃんと動いていそうです。
ありがとうございます。

編集 削除