2011-02-24 140 views
2
[DllImport("user32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)] 
static extern bool GetWindowRect(HandleRef hWnd, out RECT lpRect); 

[StructLayout(LayoutKind.Sequential)] 
public struct RECT 
{ 
    public int Left;  // x position of upper-left corner 
    public int Top;   // y position of upper-left corner 
    public int Right;  // x position of lower-right corner 
    public int Bottom;  // y position of lower-right corner 
} 

foreach (Process pr in Process.GetProcesses()) 
{ 
    RECT rc; 
    GetWindowRect(???, out rc); 

我應該爲「???」做些什麼? 。它告訴我必須放置一個HandleRef對象,但我不知道如何從Process方法獲取HandleRef對象。C# - user32.dll - GetWindowRect問題

+1

你跳過的步驟;你首先需要從窗口獲得本地句柄。例如,如果窗口是應用程序中的C#主窗體(假設爲WinForms應用程序),則可以使用新的'HandleRef(this,this.Handle);'您需要首先獲取有問題窗口的句柄.Handle可能不是)。 –

回答

0

你不需要一個進程句柄,而是一個窗口句柄。

你可以使用一些例如在PInvoke的http://pinvoke.net/default.aspx/user32/GetWindowRect.html

+0

我必須知道所有進程的句柄,不僅僅是我的應用程序。 – xoromer

+1

@Sergey:如果您閱讀該文檔,您將會意識到它不適用於此。這是一個進程句柄,而不是一個窗口句柄。 –

+0

你的鏈接不能幫助OP(顯然已經找到它)。它僅顯示如何獲取應用程序中窗體的窗口句柄。如果這是用例,你根本不需要使用GetWindowRect; .NET窗體已經可以提供這些信息。 -1 –

10

如果你需要一個窗口,在你的工藝窗口座標已經有其他方式獲得,不需要枚舉進程的窗口句柄。

對於WinForms窗口,請使用Handle屬性。

System.Windows.Forms.Control ... Handle Property @ MSDN

對於WPF應用程序,使用WindowInteropHelper

System.Windows.Interop ... WindowInteropHelper Class @ MSDN

如果你試圖枚舉,你是不是能夠直接從.NET訪問窗口;從第三方控件創建一個超出代碼範圍的頂級窗口,您可能希望通過win32 EnumWindows函數進行枚舉。

EnumWindows (Win32) @ MSDN

簽名的P/Invoke的EnumWindows的都可以在這裏:

User32.dll EnumWindows @ pinvoke.net

補充:

看起來要列舉所有的窗戶&關聯的進程。使用EnumWindows,然後調用GetWindowThreadProcessId以獲取每個窗口的關聯進程&非託管線程標識。

GetWindowThreadProcessId (Win32) @ MSDN

的的P/Invoke簽名,請訪問:

User32.dll GetWindowThreadProcessId @ pinvoke.net

最後,您可以通過靜態方法GetProcessById得到一個Process對象。

Process.GetProcessById @ MSDN

添加(#2):

下面是可以枚舉窗口,過程&線程ID很短的控制檯程序。與你的代碼片段有一些不同之處。

  1. 我使用IntPtr而不是HandleRef。正如其他人指出的,這可能會讓你感到困惑。
  2. 我沒有指定return屬性。如果這是必需的,您應該可以重新添加。
  3. 我以管理員身份運行;如果您使用用戶級權限運行,某些事情可能會以不同方式運行。

C# Source Code Example @ gist.github

+0

唯一有用的答案+1 –

+0

謝謝!但我很困惑。是的,它看起來像不讓我從.NET訪問另一個進程的窗口屬性 – xoromer

+0

我能夠得到一個示例工作;但我在我的機器上以管理員身份運行。我將發佈一個鏈接到源代碼,以便您可以在您的環境中的測試項目中嘗試。 – meklarian

2

使用新HandleRef(PR,pr.MainWindowHandle)可能會奏效。假設你的程序實際上有一個主窗口。肯定有更簡單的方法來獲取這些信息。

您的foreach循環將需要工作,它不會在Process.GetCurrentProcess()上編譯。試圖迭代所有進程將會轟炸代碼,您將獲得不關心共享信息的特權系統進程。猜測你爲什麼試圖這樣做是不可能的。使用EnumWindows枚舉桌面上的所有頂層窗口。

+0

HandleRef(pr,pr.MainWindowHandle)不起作用。 謝謝你的Process.GetCurrentProcess()。我修好了。 – xoromer

+2

好吧,將GetWindowRect()參數改爲IntPtr,無論如何HandleRef是非常不必要的。 –

+0

沒有工作。 。 。 。 – xoromer

1

這是可行的,但首先你需要使用像FindWindowEx WINAPI功能找到該窗口的IntPtr的HWND:

[DllImport("user32.dll")] 
public static extern bool GetWindowRect(IntPtr hwnd, ref Rect rectangle); 

Rect r = new Rect(); 
GetWindowRect(hwnd, ref r);