2010-04-21 74 views
0

我試圖通過調用本機的GetForegroundWindow WinAPI函數,在我的應用程序的窗體中的C#/ Net 2.0/WinForms的前景窗口句柄構造函數。GetForegroundWindow不工作,當C#程序從桌面快捷方式的快捷鍵運行

當我直接從Windows資源管理器或Total Commander運行程序時,它可以正確識別Windows資源管理器或Total Commander窗口。但是,如果我在桌面上爲我的程序創建快捷方式併爲快捷方式(假設爲Ctrl + Alt + X)設置快捷鍵,那麼當我使用快捷方式運行我的程序時,會識別前景窗口作爲「Shell_TrayWnd窗口」(Handle 0x00010064),而不是實際的窗口。 (假設我在頂部運行Firefox,當我按下Ctrl + Alt + X時,我的程序啓動,並且前景窗口不是Firefox,因爲它應該顯示它是任務欄--Shell_TrayWnd。)

public MainForm() 
    { 
     this.InitializeComponent(); 

     IntPtr handle = WinAPI.GetForegroundWindow(); 
     this.Text = handle.ToString(); 
     StringBuilder title = new StringBuilder(255); 
     if (WinAPI.GetWindowText(handle, title, 255) > 0) 
     { 
      this.Text += title.ToString(); 
     } 
    } 

我怎樣才能得到真正的前景窗口?我應該(也)使用其他函數,如GetWindow?

謝謝

回答

1

注意,任務欄可能當時真正的前臺窗口調用GetForegroundWindow,只是因爲這是瀏覽器誰的操控快捷鍵按下,任務欄屬於資源管理器(Shell_TrayWnd是任務欄的窗口類)。

如果您想要在全局活動窗口中執行某些操作,您最好先啓動應用程序並讓它在後臺等待。然後,您可以在應用程序運行時處理按鍵操作,因此Explorer不會產生干擾。

不知何故,這讓我想起Raymond Chen的一篇文章。

0

我想你正在嘗試做同樣的事情,因爲我在—從當前路徑的資源管理器中打開一個shell。

我遇到了完全相同的問題。這是一個爲我工作的程序。它使用EnumWindows來搜索所有可見的窗口,直至找到其標題爲真實路徑的人。

using System; 
using System.IO; 
using System.Text; 
using System.Diagnostics; 
using System.Runtime.InteropServices; 

public class ShellHere 
{ 
    // Thanks to pinvoke.net for the WinAPI stuff 

    [DllImport("user32.dll")] 
    private static extern int EnumWindows(CallBackPtr callPtr, int lPar); 

    [DllImport("user32.dll")] 
    static extern int GetWindowText(int hWnd, StringBuilder text, int count); 

    [DllImport("user32.dll", EntryPoint="GetWindowLong")] 
    private static extern IntPtr GetWindowLongPtr32(IntPtr hWnd, GWL nIndex); 

    [DllImport("user32.dll", EntryPoint="GetWindowLongPtr")] 
    private static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, GWL nIndex); 

    public delegate bool CallBackPtr(int hwnd, int lParam); 
    private static CallBackPtr _callBackPtr; 

    // This static method is required because Win32 does not support 
    // GetWindowLongPtr directly 
    public static IntPtr GetWindowLongPtr(IntPtr hWnd, GWL nIndex) 
    { 
     if (IntPtr.Size == 8) 
      return GetWindowLongPtr64(hWnd, nIndex); 
     else 
      return GetWindowLongPtr32(hWnd, nIndex); 
    } 

    public static bool FindPathInTitle(int hwnd, int lparams) 
    { 
     const int nChars = 256; 
     StringBuilder buffer = new StringBuilder(nChars); 

     IntPtr result = GetWindowLongPtr(new IntPtr(hwnd), GWL.GWL_STYLE); 

     // ignore invisible windows 
     if ((result.ToInt64() & WS_VISIBLE) != 0) 
     { 
      if (GetWindowText(hwnd, buffer, nChars) > 0) 
      { 
       string title = buffer.ToString(); 

       // ignore the taskbar 
       if (title.ToLower() != "start" && Directory.Exists(title)) 
       { 
        _folder = title; 
        return false; 
       } 
      } 
     } 

     return true; 
    } 

    private static string _folder; 

    public static void Main() 
    { 
     _callBackPtr = new CallBackPtr(FindPathInTitle); 
     EnumWindows(_callBackPtr, 0); 

     Process shell = new Process(); 
     shell.StartInfo.FileName = "cmd.exe"; 
     if (!string.IsNullOrEmpty(_folder)) 
      shell.StartInfo.WorkingDirectory = _folder; 
     shell.Start(); 
    } 

    public enum GWL 
    { 
     GWL_WNDPROC = (-4), 
     GWL_HINSTANCE = (-6), 
     GWL_HWNDPARENT = (-8), 
     GWL_STYLE =  (-16), 
     GWL_EXSTYLE = (-20), 
     GWL_USERDATA = (-21), 
     GWL_ID =  (-12) 
    } 

    // Window Styles 
    const UInt32 WS_VISIBLE = 0x10000000; 
} 

它到目前爲止我的工作(Win7-64)。請注意,您不必直接在資源管理器窗口中工作—它將使用Tab鍵順序中的下一個。

0

我不知道你所需要的前臺窗口,所以這可能會或可能不會幫助:

你或許可以檢測出你是通過一個快捷方式啓動:

檢查dwFlags在這種情況下,你可能嘗試獲得窗T帽子的前一個按Z順序排列,或在桌面窗口頂部。