C# – user32.dll – GetWindowRect问题

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

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

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

System.Windows.Forms.Control …处理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以获取每个窗口的关联Process和Unmanaged Thread ID。

GetWindowThreadProcessId(Win32)@ MSDN

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

User32.dll GetWindowThreadProcessId @ pinvoke.net

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

Process.GetProcessById @ MSDN

添加(#2):

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

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

C#源代码示例@ gist.github

使用新的HandleRef(pr,pr.MainWindowHandle)可能会起作用。 假设您的程序实际上有一个主窗口。 有更简单的方法来获取此信息。

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

这将有效,但首先你需要使用像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); 

你不需要一个进程句柄,而是一个窗口的句柄。

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