开发者

C# - user32.dll - GetWindowRect problem

[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);

What should I put for " ??? " ? . It tells me I have to put a HandleRef object but I do not know how to get HandleRef object from Process method.


If you need window coordinates for a window already in your process, there are other ways to get a window handle that don't require enumerating processes.

For WinForms windows, use the Handle property.

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

For WPF applications, use WindowInteropHelper

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

If you are trying to enumerate windows that you aren't able to access directly from .NET; say from a 3rd party control that creates a top-level window out of scope of your code, you may wish to enumerate via the win32 EnumWindows function.

EnumWindows (Win32) @ MSDN

Signatures for P/Invoke for EnumWindows are available here:

User32.dll EnumWindows @ pinvoke.net

Added:

Looks like you want to enumerate all the windows & associated processes. Use EnumWindows, then call GetWindowThreadProcessId to get the associated Process & Unmanaged Thread ID for each window.

GetWindowThreadProcessId (Win32) @ MSDN

The P/Invoke signature is available here:

User32.dll GetWindowThreadProcessId @ pinvoke.net

Last, you can get a Process object via the static method GetProcessById.

Process.GetProcessById @ MSDN

Added (#2):

Here's a short console program that can enumerate windows, process & thread ids. There are a few differences from your snippet.

  1. I use IntPtr, not HandleRef. As other people have pointed out, this may be confusing things for you.
  2. I didn't specify a return attribute. If this is required, you should be able to add it back in.
  3. I'm running as administrator; some things may run differently for you if you are running with user-level privileges.

C# Source Code Example @ gist.github


This will work, but at first you need to find an IntPtr hwnd of the window using winapi functions like FindWindowEx:

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

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


Using new HandleRef(pr, pr.MainWindowHandle) might work. Assuming that your program actually has a main window. There are definitely easier ways to get this info.

Your foreach loop is going to need work, that doesn't compile on Process.GetCurrentProcess(). Trying to iterate all the processes is going to bomb the code, you'll get privileged system processes that don't care much about sharing information. It is impossible to guess why you are trying to do this. Use EnumWindows to enumerate all toplevel windows on the desktop.


You need not a process handle but a handle of your window.

You can use some example on pinvoke http://pinvoke.net/default.aspx/user32/GetWindowRect.html

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜