DatulaなどMFCを利用して作成されたアプリケーションの場合内部のウィンドウに対して別スレッドの子ウィンドウにフォーカスをセットする方法を使って SetFocus
しても正しくビューがアクティブになってくれません。これは SetFocus
した後に Tab キーを押したり Shift + F10 でコンテキストメニューを開いてみるとよくわかります。
これは何故かと言うとMFCではアクティブなビューを記憶する変数を持っていてこれはフォーカスの移動では変更されないためです。ですからこれを変更してもらえば正しくビューがアクティブになってくれるはずです。MFCのソースを読んでみるとちょうど OnMouseActivate
で SetActiveView
を呼んでいますのでアクティブにしたいウィンドウに対して WM_MOUSEACTIVATE
を送ってやります。
- int nResult = ::SendMessage(hTarget, WM_MOUSEACTIVATE,
- (WPARAM) hApplication, // アプリケーションのウィンドウを指定
- MAKELPARAM(HTCLIENT, WM_LBUTTONDOWN)); // とりあえずクライアント領域でLBUTTONDOWNにしておく
- if (nResult == MA_ACTIVATE || nResult == MA_ACTIVATEANDEAT)
- ::SetFocus(hTarget); // アクティブにする場合だけフォーカスを移す