子ウィンドウにWM_MOUSEWHEELが来ない、受け取れない、処理できない時
チャイルドウィンドウにWM_MOUSEWHEEL(マウスホイールが回されたときのウィンドウメッセージ)が渡されない事がある。
親ウィンドウには届くんだけど、本命の子ウィンドウには届かない、そんな時。
結論
SetFocus( HWND); を使って、子ウィンドウにフォーカスを移しましょう。
あるいは親に渡されたメッセージを子ウィンドウへ丸投げするなど。
SetCapture〜ReleaseCaptureは必要なさそうです。
もっと! もっともっと便利に
WM_MOUSEWHEELを受け取りたい窓が複数ある場合、どの窓にどうやってフォーカスを設定するか
(複数ある子ウィンドウのうち、特定の子ウィンドウにフォーカスを設定したい時)
僕のやりたい事とは関係ないのでほんのメモ程度に。
- ChildWindowFromPointExでマウスポインタの真下にある窓を調べる
- その窓にSetFocus
WM_MOUSEMOVEの時にこれをやるといいと思う。
でもWM_ACTIVATEのたびに親ウィンドウをSetCaptureしないと、子ウィンドウにWM_MOUSEMOVEが行っちゃうかも。
やってみないとよくわかりません。
WM_MOUSEWHEELを必要とする窓がひとつしかない場合
WM_ACTIVATEのたびにSetFocusすればいいと思います。
ただしこのメッセージはアクティブになった時だけでなく、非アクティブ状態になったときも送られてくるので注意。
// WTLのやり方でやってみる (m_ImgViewは子ウィンドウ) LRESULT OnActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { if(WA_INACTIVE == LOWORD(wParam)) // 非アクティブ状態になった時 return 0; if(m_ImgView.IsWindow()) m_ImgView.SetFocus(); return 0; }
// SDKのやり方でやってみる (ウィンドウプロシジャにて) case WM_ACTIVATE: if(WA_INACTIVE == LOWORD(wParam)) break; if(IsWindow(hView)) SetFocus( hView); break;
こんなところでしょうか。
注意
ChildWindowFromPointExの2番目の引数は, 親ウィンドウからの相対座標です。