С# HwndSource из Process.MainWindowHandle

Я пытаюсь «подцепиться» к сообщениям окна, чтобы обнаружить минимизацию/максимизацию. Я осмотрелся и думаю, что единственное/лучшее решение для этого - подключиться к сообщениям окна и проверить сообщение WM_WINDOWPOSCHANGED, а затем проверить его статус.

Я столкнулся с проблемой.

System.Windows.Interop.HwndSource source = System.Windows.Interop.HwndSource.FromHwnd(System.Diagnostics.Process.GetProcessesByName("notepad")[0].MainWindowHandle);
System.Windows.Interop.HwndSourceHook hook = new System.Windows.Interop.HwndSourceHook(WndProc);
source.AddHook(hook);

Это даст мне «Ссылка на объект не установлена ​​​​на экземпляр объекта». ошибка в "source.AddHook...". При постановке брейкпойнта также становится ясно, что исходная переменная имеет значение null. Другими словами: не удается получить HwndSource в первой строке.

Я знаю, что это возможно с помощью «WindowInteropHelper», но это когда у вас есть фактическое окно как доступное Windows.Window, но в моей ситуации я этого не делаю.

Будем очень признательны за любые обходные пути/решения,
Рене Сакерс.

P.S. Я на 100% уверен, что Блокнот запущен, когда код выполняется, и ему удается найти его и его дескриптор главного окна.


person René Sackers    schedule 22.10.2011    source источник


Ответы (2)


HwndSource и HwndSourceHook делают не то, что вы думаете. Они существуют только для взаимодействия между WPF и стандартными окнами Win32 — в том же процессе. Их нельзя использовать для перехвата оконной процедуры окна в другом процессе.

HwndSource.FromHwnd() не создает новый объект HwndSource, он «возвращает объект HwndSource указанного окна». Если hWnd не связан с ним, FromHwnd() вернет null. Это было бы похоже на вызов System.Windows.Forms.Control.FromHandle на hWnd из блокнота, который также вернул бы ноль, поскольку окно блокнота не является элементом управления WinForms.

Чтобы перехватить оконную процедуру другого процесса, используйте SetWindowsHookEx. А чтобы подключить другой процесс, код должен быть написан на C или C++.

person shf301    schedule 22.10.2011
comment
Хорошо, это проясняет некоторые вещи, спасибо. Я уже думал о SetWindowsHookEx, но у меня есть плохой опыт, начиная с отключения клавиатуры и мыши. Я попробую. Спасибо еще раз. - person René Sackers; 22.10.2011

Вы неправильно используете WindowInteropHelper. В документации для конструктора указано:

Инициализирует новый экземпляр класса WindowInteropHelper для указанного окна Windows Presentation Foundation (WPF).

Окно блокнота не является окном WPF, поэтому FromHwnd возвращает null.

На самом деле, я не верю, что это когда-либо могло работать для окна в отдельном процессе, даже если другое окно было окном WPF.

person David Heffernan    schedule 22.10.2011