C# - user32.dll - GetWindowRect问题

时间:2011-02-24 00:20:24

标签: c# c#-4.0

[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对象。

4 个答案:

答案 0 :(得分:10)

如果您需要窗口中的窗口坐标,那么还有其他方法可以获得不需要枚举进程的窗口句柄。

对于WinForms窗口,请使用Handle属性。

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

对于WPF应用程序,请使用WindowInteropHelper

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

如果您尝试枚举无法直接从.NET访问的窗口;从第三方控件中创建一个超出代码范围的顶级窗口,您可能希望通过win32 EnumWindows函数进行枚举。

EnumWindows (Win32) @ MSDN

EnumWindows的P / Invoke签名可在此处获取:

User32.dll EnumWindows @ pinvoke.net

<强>加了:

看起来你想枚举所有的窗口和放大器相关流程。使用EnumWindows,然后致电GetWindowThreadProcessId以获取相关的流程&amp;每个窗口的非托管线程ID。

GetWindowThreadProcessId (Win32) @ MSDN

P / Invoke签名可在此处获取:

User32.dll GetWindowThreadProcessId @ pinvoke.net

最后,您可以通过静态方法GetProcessById获取Process对象。

Process.GetProcessById @ MSDN

已添加(#2):

这是一个简短的控制台程序,可以枚举窗口,进程和放大器线程ID。与您的代码段有一些区别。

  1. 我使用的是IntPtr,而不是HandleRef。正如其他人所指出的那样,这可能会让你感到困惑。
  2. 我没有指定return属性。如果需要,您应该可以将其重新添加。
  3. 我是以管理员身份运行的;如果您使用用户级权限运行,某些事情可能会以不同的方式运行。
  4. C# Source Code Example @ gist.github

答案 1 :(得分:2)

使用新的HandleRef(pr,pr.MainWindowHandle)可能会有效。假设你的程序实际上有一个主窗口。获得此信息肯定更简单。

你的foreach循环需要工作,不能在Process.GetCurrentProcess()上编译。尝试迭代所有进程将会轰炸代码,您将获得不关心共享信息的特权系统进程。你无法猜到为什么要这样做。使用EnumWindows枚举桌面上的所有顶层窗口。

答案 2 :(得分: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);

答案 3 :(得分:0)

你不需要一个处理句柄,而是窗口的句柄。

您可以在pinvoke http://pinvoke.net/default.aspx/user32/GetWindowRect.html

上使用一些示例