2つのウィンドウが2つあるWindowsプログラムがあります。
hwnd (main interface)
hwnd2 (toplevel window, no parent, created by hwnd)
Hwndをダブルクリックすると、hwnd2がポップアップしていくつかのデータを表示する必要があるため、この関数を使用してhwnd2を先頭に表示します。
BringWindowToTop(hwnd2);
hwnd2がトップになりましたが、奇妙なことが1つあります。もう一度hwnd2をクリックすると、hwnd(メインインターフェイス)が再び自動的にポップアップします。この問題を解決するために次の関数を使用しようとしましたが、どれも機能しません。
SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
//doesn't work
BringWindowToTop(hwnd2); //This is the function brings hwnd2 to top
SetForegroundWindow(hwnd2); //doesn't work
SetWindowPos(hwnd2, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
//doesn't work
SetWindowPos(hwnd2, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
// hwnd2 "always" on top, not what I want
SetActiveWindow(hwnd2); // doesn't work too (for replying to Magnus Skog, thanks)
SwitchToThisWindow(hwnd2, TRUE);// got the same problem with BringWindowToTop function
SwitchToThisWindow(hwnd2, FALSE);
どうすればこの問題を解決できますか?前もって感謝します。
(aJに返信する場合、hwnd2は他のウィンドウの前面/背面に配置できるようにトップレベルウィンドウである必要があるため、親はありません)
(hwnd2は複数のウィンドウで構成されるメディアプレーヤーです。ウィンドウの1つはビデオ表示用で、他の2つのトラックバーコントロールはプログレスバーとボリュームバー用、1つはコントロールパネル用のツールバーコントロールです。)
(これが役立つ可能性のあるウィンドウが1つあります。hwnd2をクリックしたウィンドウに関係なく、hwndはメニューバーや非クライアント領域など、「マウスがZオーダーでhwndの上にある」のと同じくらい長くポップアップします。)
(このメディアプレーヤーはダイレクトショーで記述されています。私はIVideoWindow :: put_Ownerを使用してビデオウィンドウをビデオ所有者として配置します。ダイレクトショーは内部的にサブビデオウィンドウをビデオウィンドウの子として作成します。このサブビデオウィンドウを除き、私はソースコードを見ることができず、hwnd2で疑わしいものは何もありません。)
その理由を見つけました、それはダイレクトショーのためです。マルチスレッドを使用して実行すると、問題は解決します。しかし、なぜ??
この問題は、(SendMessageではなく)PostMessageを使用して解決できます。
これを試してください、それはM $から来ていると言われています
HWND hCurWnd = ::GetForegroundWindow();
DWORD dwMyID = ::GetCurrentThreadId();
DWORD dwCurID = ::GetWindowThreadProcessId(hCurWnd, NULL);
::AttachThreadInput(dwCurID, dwMyID, TRUE);
::SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
::SetWindowPos(m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
::SetForegroundWindow(m_hWnd);
::AttachThreadInput(dwCurID, dwMyID, FALSE);
::SetFocus(m_hWnd);
::SetActiveWindow(m_hWnd);
両方とも素晴らしい:
::SetForegroundWindow(wnd)
または
::SetWindowPos(m_hWnd, // handle to window
HWND_TOPMOST, // placement-order handle
0, // horizontal position
0, // vertical position
0, // width
0, // height
SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE// window-positioning options
);
しかし、最後のものはウィンドウを常に一番上に置くことを覚えておいてください。
SwitchToThisWindow が最適です。
SwitchToThisWindow()は非推奨ではありません。
私は本番環境で14年間使用しています。
Windowsのソースコードを見ると、どこからでも呼び出されていることがわかります...
多くの試行錯誤の後、私はこの問題の次の解決策を見つけました:
SendMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0); // restore the minimize window
SetForegroundWindow(hwnd);
SetActiveWindow(hwnd);
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
//redraw to prevent the window blank.
RedrawWindow(hwnd, NULL, 0, RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN );
Hwndは、Windows HWNDです。コピーして貼り付けないでください。また、GetLastError
を使用して、すべてのAPI呼び出しの後にAPIエラーをチェックする必要があります。
私のwin7で次の結果を確認しました。
あなたは試しましたSetActiveWindow()?