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.
- I use IntPtr, not HandleRef. As other people have pointed out, this may be confusing things for you.
- I didn't specify a
return
attribute. If this is required, you should be able to add it back in. - 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
精彩评论