2012-01-02 55 views
1

方案 我有我的主要應用程序,它最初是用C#.Net應用程序啓動的Borland C++編寫的。這個主應用程序偶爾會從一個名爲BRWSEXE的進程打開一個模態對話框。彈出模態對話框窗口後,您可能無意中單擊主應用程序中的某個位置(而不是對話框),導致焦點短暫變爲主應用程序,並以Z順序發送後面的模式對話框。但是你實際上不能在主應用程序上做任何事情,它會被那個必須先關閉的模式對話框鎖定,然後才能繼續。SetForegroundWindow在Windows Server 2008上失敗

的問題 使用啓動一切的.NET應用程序,我可以找出所涉及到的主要應用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.net更好的pinvoke聲明。

+0

原諒我我是一個新手,我必須有一個不好的初始信息來源。用你所說的話,這意味着只有我的SetForegroundWindow調用正在工作,因爲它能夠成功地將窗口置於前臺。但是,這些都不能幫助我找出爲什麼它可以在Windows Server 2008上的任何地方工作。 感謝您提供有關從這些調用中獲取錯誤的信息。我一定會在使用它的同時繼續努力實現這一目標。 – Hagelt18 2012-01-03 14:55:20

+1

AttachThreadInput()調用是有原因的。沒有它們,SetForegroundWindow()很有可能不會將窗口實際放到前臺。 – 2012-01-03 15:55:20

0

我用SwitchToThisWindow(),雖然MSDN說,它可能會在未來的Windows版本中刪除,它仍然爲我工作。

+0

它是否適用於最小化窗口? – deadfish 2012-01-02 16:18:40

+0

@MichałMokrzycki是的,它應該顯示並把窗口放到前臺。 – scottm 2012-01-02 16:23:46

+0

感謝您的建議!我改變了我的代碼來使用該函數,但我得到了相同的結果。它使用其他操作系統,但使用Windows Server 2008時失敗。 – Hagelt18 2012-01-02 16:26:49

相關問題