ウィンドウが表示されたときのみ、最前面化する(常に最前面ではない)方法を教えてく
ださい。
SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
これではうまくいかなったので、
ShowWindow(hWnd, SW_RESTORE);
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE |
SWP_SHOWWINDOW);
SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE |
SWP_SHOWWINDOW);
このようにしているソースコードを真似ました。
うまくいく場合もあるのですが、そうでない場合もあります。
うまくいかない原因は、他のウィンドウの表示方法にもよりますか?
>SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE |
SWP_SHOWWINDOW);
一般にはこれで成功するはずですね。
というか、自分はこの方法で問題に遭遇したことはありません。
ただし、慎重な人はSetForegroundWindow()を併用するかもしれません。
私の場合、以下のHPにある
http://www.sangyo-rock.com/tech/index.php?WindowsAPI%B4%D8%CF%A2
SetAbsoluteForegroundWindow()という関数を利用しています。
こういう動作でしょうか。
(1)WS_EX_TOPMOSTのウィンドウが表示されている。
(例)タスクマネージャが開かれていて、タスクマネージャの
メニュー/オプション/常に手前に表示がチェックされている
(2)MyAppのウィンドウをマウスクリックなどでアクティブにすると、
(1)のウィンドウよりも手前に表示される。
(3)(2)の状態で別のウィンドウをアクティブにすると、
(1)のウィンドウは最前面に表示され、
その奥に(3)のウィンドウが表示されアクティブになり、
MyAppは(3)よりも奥に表示される。
それならば、
case WM_NCACTIVATE:
if(wParam)
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW);
else
SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOREDRAW);
return DefWindowProc(hWnd, message, wParam, lParam);
とりあえず、これで何とかなりました。
WM_ACTIVATE,WM_ACTIVATEAPPハンドラやSWP_xxxフラグでもっと良くなるかもしれませ
ん。
ところで、
NEOさん呈示のコードはどのメッセージハンドラにかいたのでしょうか。
または、Createの直後にかいたのでしょうか。
どの段階でSetWindowPosを呼び出したのかわからないと回答も出にくいと思います。
すみません、訂正です。SWP_NOREDRAWは2ケとも削除してください。
正しくは、
case WM_NCACTIVATE:
if(wParam)
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE);
else
SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
return DefWindowProc(hWnd, message, wParam, lParam);