子ウィンドウにWM_MOUSEWHEELが来ない、受け取れない、処理できない時

チャイルドウィンドウにWM_MOUSEWHEEL(マウスホイールが回されたときのウィンドウメッセージ)が渡されない事がある。
親ウィンドウには届くんだけど、本命の子ウィンドウには届かない、そんな時。

結論

SetFocus( HWND); を使って、子ウィンドウにフォーカスを移しましょう。
あるいは親に渡されたメッセージを子ウィンドウへ丸投げするなど。
SetCapture〜ReleaseCaptureは必要なさそうです。

もっと! もっともっと便利に

WM_MOUSEWHEELを受け取りたい窓が複数ある場合、どの窓にどうやってフォーカスを設定するか

(複数ある子ウィンドウのうち、特定の子ウィンドウにフォーカスを設定したい時)
僕のやりたい事とは関係ないのでほんのメモ程度に。

  1. ChildWindowFromPointExでマウスポインタの真下にある窓を調べる
  2. その窓に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番目の引数は, 親ウィンドウからの相対座標です。