C# - user32.dll - GetWindowRect问题

xor*_*mer 2 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);
Run Code Online (Sandbox Code Playgroud)

我该怎么做"???"?.它告诉我我必须放置一个HandleRef对象,但我不知道如何从Process方法获取HandleRef对象.

mek*_*ian 10

如果您的进程中已经存在窗口的窗口坐标,则还有其他方法可以获得不需要枚举进程的窗口句柄.

对于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

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

Process.GetProcessById @ MSDN

添加(#2):

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

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

C#源代码示例@ gist.github