メッセージハンドラの優先順位

[戻る]
亀山 2008/07/04(金) 15:51:59
VC6 MFC です。

CFrameWnd派生クラスとそれに属するCView派生クラスの両方に
同じコマンドに対するハンドラを用意してみたのですが、
CFrameWnd派生クラスのほうにSendMessage(WM_COMMAND, ...)を送っても
CView派生クラスのほうが呼ばれてしまいます。

MFCのCFrameWndがそのような仕組みになっているのは理解しているのですが、
CFrameWnd派生クラスのメッセージマップを一時的に最優先させるような
メッセージの送りかたはあるのでしょうか?

やりたいことは、任意のウィンドウ(CWnd*)に外から定期的に固定メッセージを送り、
受け取ったウィンドウが内部で処理を行うというものです。
ここにCFrameWnd派生クラスやCView派生クラスを任意のタイミングで指定したいのです。

おとなしくウィンドウごとに別のコマンドIDを使うしか無いのでしょうか?

ん? 2008/07/04(金) 16:08:46
CWnd* pMainWnd = AfxGetApp()->m_pMainWnd;
CMainFrame* pMainFrame = (CMainFrame*)pMainWnd;
HWND hWnd = pMainFrame->GetSafeHwnd();
ASSERT(hWnd != NULL);    // オーナーのウインドウハンドルがNULLの場合、エラーです。

上記は使えませんか?

Kerry 2008/07/04(金) 16:47:37
そういう場合は、WM_COMMANDではなく、ユーザー定義メッセージ(WM_APP + n)
を使うべきでしょう。

MFCのコマンドルーティングを変えたい場合は、CFrameWnd::OnCmdMsg()を
オーバーライドすれば可能ですが、この方法はメッセージの受け側で処理を
切り替える形になります。

BOOL CXXXXFrameWnd::OnCmdMsg(UINT nID, int nCode, void* pExtra,
    AFX_CMDHANDLERINFO* pHandlerInfo)
{
    if (条件)
    {
        // このクラスでコマンドを処理する
        return CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
    }
    else
    {
        // 基底クラスの処理
        return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
    }
}

亀山 2008/07/04(金) 18:12:32
[[解決]]
WM_COMMANDでなければよかったのですね。
もともとCView派生クラスのみにコマンドハンドラとして用意していたものだったので、
そのメッセージを流用してしまいました。うかつでした。

独自のメッセージに置き換えてみたところ、
CFrameWnd派生クラスでも自分のハンドラがコールされるようになりました。

ん?さん、Kerryさん、ありがとうございます。

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