C # - user32.dll - проблема GetWindowRect - PullRequest
2 голосов
/ 24 февраля 2011
[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, но я не знаю, как получить объект HandleRef из метода Process.

Ответы [ 4 ]

10 голосов
/ 24 февраля 2011

Если вам нужны координаты окна для окна, уже находящегося в вашем процессе, есть другие способы получить дескриптор окна, который не требует перечисления процессов.

Для окон WinForms используйте свойство Handle.

System.Windows.Forms.Control ... Обрабатывать свойство @ MSDN

Для приложений WPF используйте WindowInteropHelper

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

Если вы пытаетесь перечислить окна, к которым у вас нет доступа напрямую из .NET; скажем, от стороннего элемента управления, который создает окно верхнего уровня вне области вашего кода, вы можете перечислить с помощью функции win32 EnumWindows.

EnumWindows (Win32) @ MSDN

Подписи для P / Invoke для EnumWindows доступны здесь:

User32.dll EnumWindows @ pinvoke.net

Добавлено:

Похоже, вы хотите перечислить все окна и связанные процессы. Используйте EnumWindows, затем вызовите GetWindowThreadProcessId, чтобы получить связанный идентификатор процесса и неуправляемого потока для каждого окна.

GetWindowThreadProcessId (Win32) @ MSDN

Подпись P / Invoke доступна здесь:

User32.dll GetWindowThreadProcessId @ pinvoke.net

Наконец, вы можете получить объект Process с помощью статического метода GetProcessById.

Process.GetProcessById @ MSDN

Добавлено (# 2):

Вот короткая консольная программа, которая может перечислять окна, идентификаторы процессов и потоков. Есть несколько отличий от вашего фрагмента.

  1. Я использую IntPtr, а не HandleRef. Как отмечали другие люди, это может сбить вас с толку.
  2. Я не указал атрибут return. Если это необходимо, вы сможете добавить его обратно.
  3. Я работаю администратором; некоторые вещи могут работать по-другому, если вы работаете с привилегиями уровня пользователя.

Пример исходного кода C # @ gist.github

2 голосов
/ 24 февраля 2011

Использование нового HandleRef (pr, pr.MainWindowHandle) может работать. Предполагая, что ваша программа на самом деле имеет главное окно. Есть определенно более простые способы получить эту информацию.

Вашему циклу foreach потребуется работа, которая не компилируется в Process.GetCurrentProcess (). Попытка перебрать все процессы приведет к бомбардировке кода, вы получите привилегированные системные процессы, которые не заботятся об обмене информацией. Невозможно угадать, почему вы пытаетесь это сделать. Используйте EnumWindows для перечисления всех окон верхнего уровня на рабочем столе.

1 голос
/ 09 июля 2014

Это будет работать, но сначала вам нужно найти IntPtr hwnd окна, используя такие функции winapi, как FindWindowEx :

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

Rect r = new Rect();
GetWindowRect(hwnd, ref r);
0 голосов
/ 24 февраля 2011

Вам нужен не дескриптор процесса, а дескриптор вашего окна.

Вы можете использовать пример на pinvoke http://pinvoke.net/default.aspx/user32/GetWindowRect.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...