В Windows Forms я бы просто переопределил WndProc
и начал обрабатывать сообщения по мере их поступления.
Может ли кто-нибудь показать мне пример того, как добиться того же в WPF?
На самом деле, насколько я понимаю, такое возможно в WPF с использованием HwndSource
и HwndSourceHook
. См. Эту ветку в MSDN в качестве примера. (Соответствующий код приведен ниже)
// 'this' is a Window
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
source.AddHook(new HwndSourceHook(WndProc));
private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
// do stuff
return IntPtr.Zero;
}
Теперь я не совсем уверен, почему вы хотите обрабатывать сообщения Windows Messaging в приложении WPF (если только это не самая очевидная форма взаимодействия для работы с другим приложением WinForms). Идеология дизайна и природа API сильно отличаются в WPF от WinForms, поэтому я предлагаю вам просто ознакомиться с WPF побольше, чтобы понять, почему нет эквивалента WndProc.
WM_MOUSEWHEEL
например, единственный способ надежно перехватить эти сообщения - это добавитьWndProc
в окно WPF. У меня это сработало, в то время как чиновникMouseWheelEventHandler
просто не работал должным образом. Мне не удалось получить правильные тахионы WPF, выстроенные в линию для обеспечения надежного поведенияMouseWheelEventHandler
, отсюда и необходимость прямого доступа кWndProc
.Вы можете сделать это через
System.Windows.Interop
пространство имен, которое содержит класс с именемHwndSource
.Пример использования этого
Полностью взято из отличного сообщения в блоге: Использование настраиваемого WndProc в приложениях WPF от Стива Рэндса
источник
источник
Если вы не против ссылаться на WinForms, вы можете использовать более MVVM-ориентированное решение, которое не связывает службу с представлением. Вам необходимо создать и инициализировать System.Windows.Forms.NativeWindow, которое представляет собой легкое окно, которое может получать сообщения.
Используйте SpongeHandle для регистрации интересующих вас сообщений, а затем переопределите WndProc для их обработки:
Единственным недостатком является то, что вам нужно включить ссылку на System.Windows.Forms, но в остальном это очень инкапсулированное решение.
Подробнее об этом можно прочитать здесь
источник
Вот ссылка на переопределение WindProc с помощью Behaviors: http://10rem.net/blog/2010/01/09/a-wpf-behavior-for-window-resize-events-in-net-35
[Изменить: лучше поздно, чем никогда] Ниже представлена моя реализация на основе указанной выше ссылки. Хотя я и возвращаюсь к этому, мне больше нравятся реализации AddHook. Я могу переключиться на это.
В моем случае я хотел знать, когда изменяли размер окна, и еще пару вещей. Эта реализация подключается к Window xaml и отправляет события.
источник
Here is a link...
около 20 точных: ответов, как указано выше.Вы можете присоединиться к классу 'SystemEvents' встроенного класса Win32:
в классе окна WPF:
источник
Существуют способы обработки сообщений с помощью WndProc в WPF (например, с использованием HwndSource и т. Д.), Но обычно эти методы зарезервированы для взаимодействия с сообщениями, которые не могут быть обработаны напрямую через WPF. Большинство элементов управления WPF даже не являются окнами в смысле Win32 (и расширением Windows.Forms), поэтому у них не будет WndProcs.
источник
WndProc
переопределению, ониSystem.Windows.Interop
позволяют вам получитьHwndSource
объект посредствомHwndSource.FromHwnd
илиPresentationSource.FromVisual(someForm) as HwndSource
, к которому вы можете привязать делегат с особым шаблоном. Этот делегат имеет многие из тех же аргументов, что иWndProc
объект Message.WPF не работает с типом WinForms wndprocs
Вы можете разместить HWndHost в соответствующем элементе WPF, а затем переопределить wndproc Hwndhost, но, AFAIK, это настолько близко, насколько вы собираетесь получить.
http://msdn.microsoft.com/en-us/library/ms742522.aspx
http://blogs.msdn.com/nickkramer/archive/2006/03/18/554235.aspx
источник
Короткий ответ: вы не можете. WndProc работает, передавая сообщения HWND на уровне Win32. Окна WPF не имеют HWND и, следовательно, не могут участвовать в сообщениях WndProc. Базовый цикл сообщений WPF находится поверх WndProc, но абстрагирует их от базовой логики WPF.
Вы можете использовать HWndHost и получить для него WndProc. Однако это почти наверняка не то, что вам нужно. В большинстве случаев WPF не работает с HWND и WndProc. Ваше решение почти наверняка зависит от внесения изменений в WPF, а не в WndProc.
источник