ウィンドウの最前面化

[戻る]
NEO 2011/02/28(月) 20:19:00
ウィンドウが表示されたときのみ、最前面化する(常に最前面ではない)方法を教えてく
ださい。

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);

このようにしているソースコードを真似ました。
うまくいく場合もあるのですが、そうでない場合もあります。

うまくいかない原因は、他のウィンドウの表示方法にもよりますか?

仲澤@失業者 2011/03/01(火) 11:48:08
>SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | 
SWP_SHOWWINDOW);

一般にはこれで成功するはずですね。
というか、自分はこの方法で問題に遭遇したことはありません。
ただし、慎重な人はSetForegroundWindow()を併用するかもしれません。

bun 2011/03/01(火) 13:19:47
私の場合、以下のHPにある
  http://www.sangyo-rock.com/tech/index.php?WindowsAPI%B4%D8%CF%A2

SetAbsoluteForegroundWindow()という関数を利用しています。

ロマ 2011/03/06(日) 16:46:30
こういう動作でしょうか。
(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を呼び出したのかわからないと回答も出にくいと思います。

ロマ 2011/03/06(日) 17:22:40
すみません、訂正です。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);

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