2012-01-02 16 views
1

シナリオ 元々C#.Netアプリケーションによって起動されているBorland C++で書かれた私の主なアプリケーションがあります。このメインアプリケーションは、BRWSEXEというプロセスからモーダルダイアログを開くことがあります。モーダルダイアログウィンドウがポップアップした後、メインアプリケーションのどこかで(ダイアログではなく)間違ってクリックすると、フォーカスがメインアプリケーションに短時間変更され、モーダルダイアログがZオーダーでその背後に表示されます。しかし、実際にはメインアプリケーションでは何もできません。続行するには、最初に閉じなければならないモーダルダイアログウィンドウでロックされます。すべてを起動する.NETアプリケーションを使用してSetForegroundWindowがWindows Server 2008で失敗する

問題 、私はメインのアプリケーションに関連するBRWSEXEのインスタンスを探し出し、フォアグラウンドにそれらを強制することができます。この方法は、これまでのところテストしたところ(Windows XP、Windows 7、Windows Server 2003 R2)では完璧に動作しますが、Windows Server 2008では動作しません。その環境の中の何かがそれを投げ捨てています。

マイコード

[DllImport("user32.dll")] 
static extern bool SetForegroundWindow(IntPtr hWnd); 

[DllImport("user32.dll")] 
static extern IntPtr AttachThreadInput(IntPtr idAttach, IntPtr idAttachTo, bool fAttach); 


private void PushBRWSEXEToFront() 
{ 
    //Make sure MyApplication is running 
    if (Process.GetProcessesByName("MyApplicationName").Length == 1) 
    { 
     Process[] brwsProc = Process.GetProcessesByName("BRWSEXE"); //Locate any processes for the browse dialog windows 
     for (int x = brwsProc.Length - 1; x > -1; x--) 
     { 
      //Make sure the browse window we are looking at is associated with the active program we are looking at 
      if (brwsProc[x].SessionId == Process.GetCurrentProcess().SessionId 
       || brwsProc[x].SessionId == Process.GetProcessesByName("MyApplicationName")[0].SessionId) 
      { 
       //attach to the main applications thread 
       AttachThreadInput(brwsProc[x].MainWindowHandle, Process.GetProcessesByName("MyApplicationName")[0].MainWindowHandle, true); 

       //Call Set foreground window to push the browse window in front of the rest of the program. 
       SetForegroundWindow(brwsProc[x].MainWindowHandle); 

       //Detach from the main thread 
       AttachThreadInput(brwsProc[x].MainWindowHandle, Process.GetProcessesByName("MyApplicationName")[0].MainWindowHandle, false); 
      } 
     } 
    } 
} 

答えて

3

AttachThreadInputの宣言は完全に間違っています。 boolを返し、引数はuintです。そしてあなたはそれを間違って使用しています、あなたはスレッドIDではなく、ウィンドウハンドルを渡すことになっています。 GetWindowThreadProcessId()が必要です。

エラーを一切チェックしていないので、明らかに障害を診断することはできません。 SetLastErrorプロパティが必要な場合は、Marshal.GetLastWin32Error()でエラーを取得します。 Pinvoke宣言を改善するには、pinvoke.netを使用します。

+0

私は初心者です。あなたが言ったことは、ウィンドウをフォアグラウンドに正常に持って来て以来、私のSetForegroundWindow呼び出しだけが働いていたことを意味します。しかし、これはWindows Server 2008のどこで動作するのかわかりません。 これらの呼び出しでエラーが発生したことについては、ありがとうございます。私はこの作業を続けようとしている間、私はそれを必ず使用します。 – Hagelt18

+1

AttachThreadInput()呼び出しには理由があります。それらがなければ、SetForegroundWindow()は実際にウィンドウをフォアグラウンドに持ってこない可能性が非常に高いです。 –

0

私はSwitchToThisWindow()を使用しました、とMSDNが、それは、Windowsの将来のバージョンで削除することができることを述べているが、それはまだ私のために働いています。

+0

最小化されたウィンドウでは機能しますか? – deadfish

+0

@MichałMokrzyckiはい、それが表示され、フォアグラウンドにウィンドウが表示されます。 – scottm

+0

提案していただきありがとうございます!代わりにその関数を使用するようにコードを変更しましたが、私は同じ結果を得ています。それは他のオペレーティングシステムを使用しても動作しますが、Windows Server 2008を使用すると失敗します。 – Hagelt18

関連する問題