2009-05-27 13 views
26

トップにウィンドウを持参I持ってそれに2つの2の窓があるWindowsプログラム:私はHWNDをダブルクリックするとのWin32:

hwnd (main interface) 

hwnd2 (toplevel window, no parent, created by hwnd) 

が、私はhwnd2がポップアップし、いくつかのデータを表示する必要があるので、私をトップにhwnd2もたらすために、この機能を使用します。

BringWindowToTop(hwnd2); 

hwnd2トップに持っているが、奇妙一つのことがあります。もう一度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つはビデオディスパッチ用、もう1つはプログレスバーとボリュームバー用のトラックバーコントロール、コントロールパネル用のツールバーコントロールです)

(これは、どのウィンドウをクリックしても問題ありませんhwnd2、hwndは、 "マウスがメニューバーとクライアント以外の領域を含めて、Z方向でhwndの上にある"とロンとして自動的にポップアップします)

(このメディアプレーヤーはDirect Showで書かれています。 IVideoWindow :: put_Ownerを使用してビデオウィンドウをビデオ所有者として配置し、Direct Showはビデオウィンドウの子としてサブビデオウィンドウを内部的に作成します。ソースコードを見ることができないこのサブビデオウィンドウを除いて、hwnd2で何か疑わしいものは見られません。)

ダイレクトショーが原因です。私はそれを実行するためにマルチスレッドを使用し、問題は解決されました。しかし、なぜ??

この問題は、(SendMessageではなく)PostMessageを使用して解決できます。

+2

hwnd2に親がない理由は何ですか? hwndは作成時に親として設定できます。 –

+0

hwnd2のマウスボタン操作コードではどうしますか?そこに何か魚がいる? –

+1

それでは、PostMessageを使ってどのように解決しましたか? –

答えて

6

SwitchToThisWindowが最適です。

+15

MSDN:この関数は非推奨であり、一般的な使用目的ではありません。それ以降のバージョンのWindowsでは、変更されているか、または使用できない可能性があるため、新しいプログラムでは使用しないことをお勧めします。 –

+2

Microsoftが何か推奨されていないと言われたら、おいてください。彼らはまだそれを使用するかどうか。 –

4

SwitchToThisWindow()は推奨されていません。
私は運用環境で14年間使用しています。
を参照してください、Windowsのソースコードを、あなたはそれがどこにでも呼ばれています表示されます...

+0

ここでは、単に「不正行為」を呼び出す必要はありません。しかし、この場合、前景ウィンドウを既に持っているので、アクティブウィンドウを変更する権利があります – Anders

13

は素晴らしい仕事両方:

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

をしかし、最後の1は、常に上のウィンドウを設定することを覚えています上。

+9

両方ともwin10で動作しません –

+0

少し遅れるかもしれませんが、ウィンドウを表示する前に ':: SetForegroundWindow'を呼び出さなければなりませんウィンドウも更新してください)。 – Cedric

-4

//素晴らしい作品です!

Var 
WndHandle:HWND; 

begin 
WndHandle :=FindWindowEx(0,0,nil,'Calculator'); 
PostMessage(WndHandle,WM_SHOWWINDOW,SW_RESTORE,0); 
SetForegroundWindow(WndHandle); 
end; 
15

それは多くの試みとerrors.Iは、この問題に次の解決策た後に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); 
+0

私は今この魔法の歌と踊りを探しています。それは私のために完璧に動作します。 – ulatekh

+0

私はまだそれが何を理解することはできませんが、ただで動作します –

+0

なぜ私はそれを "魔法"と呼んだのですか:-) – ulatekh

0

から来ると言われ、これを試してください:HWNDはあなたの窓である

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); 
RedrawWindow(hwnd,nil,0,RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); // redraw to prevent the window blank. 

をHWND。コピー&ペーストしないでください。また、api呼び出しごとにapiエラーを確認するには、GetLastErrorを使用する必要があります。

私はwin7の上、以下の結果を確認している:

  • は窓なしのエラーリターンを最小限に復元することができます。
  • ウィンドウがすでに上にある場合は、ウィンドウのタイトルが点滅し、エラーは返されません。
  • ウィンドウが閉じている場合、「0x578無効なウィンドウハンドル」というエラーが返されます。
  • これは、一番上のウィンドウではなく、エラーを返さないすべてのウィンドウを上に持ってくることができます(例えば、一番上のタスクマネージャの後ろにあります)。
  • ウィンドウを一番上にしません。ユーザーは、その上に別のウィンドウを作成することができます。