W Windows Forms po prostu przesłoniłbym WndProc
i zacząłem obsługiwać wiadomości w miarę ich pojawiania się.
Czy ktoś może pokazać mi przykład, jak osiągnąć to samo w WPF?
Właściwie, o ile rozumiem, taka rzecz jest rzeczywiście możliwa w WPF przy użyciu HwndSource
i HwndSourceHook
. Zobacz ten wątek w witrynie MSDN jako przykład. (Odpowiedni kod zawarty poniżej)
// '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;
}
Teraz nie jestem do końca pewien, dlaczego chcesz obsługiwać wiadomości systemu Windows Messaging w aplikacji WPF (chyba że jest to najbardziej oczywista forma współpracy przy pracy z inną aplikacją WinForms). Ideologia projektowania i natura API jest bardzo różna w WPF od WinForms, więc sugerowałbym po prostu zapoznanie się z WPF, aby zobaczyć dokładnie, dlaczego nie ma odpowiednika WndProc.
WM_MOUSEWHEEL
na przykład jedynym sposobem niezawodnego przechwytywania tych komunikatów było dodanieWndProc
do okna WPF. To zadziałało dla mnie, podczas gdy urzędnikMouseWheelEventHandler
po prostu nie działał zgodnie z oczekiwaniami. Nie udało mi się uzyskać poprawnych tachionów WPF ustawionych w odpowiedniej linii, aby uzyskać niezawodne zachowanieMouseWheelEventHandler
, stąd potrzeba bezpośredniego dostępu doWndProc
.Możesz to zrobić za pośrednictwem
System.Windows.Interop
przestrzeni nazw, która zawiera klasę o nazwieHwndSource
.Przykład użycia tego
Całkowicie zaczerpnięte z doskonałego wpisu na blogu: Używanie niestandardowego WndProc w aplikacjach WPF autorstwa Steve'a Randsa
źródło
źródło
Jeśli nie masz nic przeciwko odwołaniu się do WinForms, możesz użyć rozwiązania bardziej zorientowanego na MVVM, które nie łączy usługi z widokiem. Musisz utworzyć i zainicjować System.Windows.Forms.NativeWindow, który jest lekkim oknem, które może odbierać wiadomości.
Użyj SpongeHandle, aby zarejestrować wiadomości, które Cię interesują, a następnie zastąp WndProc, aby je przetworzyć:
Jedynym minusem jest to, że musisz dołączyć odniesienie do System.Windows.Forms, ale poza tym jest to bardzo zamknięte rozwiązanie.
Więcej na ten temat można przeczytać tutaj
źródło
Oto link do zastępowania WindProc za pomocą Behaviors: http://10rem.net/blog/2010/01/09/a-wpf-behavior-for-window-resize-events-in-net-35
[Edycja: lepiej późno niż wcale] Poniżej znajduje się moja realizacja na podstawie powyższego linku. Chociaż wracam do tego, bardziej podobają mi się implementacje AddHook. Mógłbym przejść na to.
W moim przypadku chciałem wiedzieć, kiedy zmieniano rozmiar okna i kilka innych rzeczy. Ta implementacja łączy się z xaml okna i wysyła zdarzenia.
źródło
Here is a link...
odpowiedzi, jak wyżej.Możesz dołączyć do klasy „SystemEvents” wbudowanej klasy Win32:
w klasie okna WPF:
źródło
Istnieją sposoby obsługi komunikatów za pomocą WndProc w WPF (np. Przy użyciu HwndSource itp.), Ale ogólnie te techniki są zarezerwowane do współdziałania z komunikatami, których nie można bezpośrednio obsłużyć przez WPF. Większość kontrolek WPF nie jest nawet oknami w sensie Win32 (i przez rozszerzenie Windows.Forms), więc nie będą miały WndProcs.
źródło
WndProc
na przesłonięcie,System.Windows.Interop
pozwala uzyskaćHwndSource
obiekt za pomocąHwndSource.FromHwnd
lubPresentationSource.FromVisual(someForm) as HwndSource
, z którym można powiązać delegata ze specjalnym wzorcem. Ten delegat ma wiele takich samych argumentów, jakWndProc
obiekt Message.WPF nie działa na typie WinForm wndprocs
Możesz hostować HWndHost w odpowiednim elemencie WPF, a następnie zastąpić wndproc Hwndhost, ale AFAIK jest tak blisko, jak chcesz.
http://msdn.microsoft.com/en-us/library/ms742522.aspx
http://blogs.msdn.com/nickkramer/archive/2006/03/18/554235.aspx
źródło
Krótka odpowiedź brzmi: nie możesz. WndProc działa poprzez przekazywanie komunikatów do HWND na poziomie Win32. Okna WPF nie mają HWND i dlatego nie mogą uczestniczyć w komunikatach WndProc. Podstawowa pętla komunikatów WPF znajduje się na szczycie WndProc, ale usuwa je z podstawowej logiki WPF.
Możesz użyć HWndHost i uzyskać za to WndProc. Jednak prawie na pewno nie jest to to, co chcesz robić. W większości przypadków WPF nie działa na HWND i WndProc. Twoje rozwiązanie prawie na pewno polega na wprowadzeniu zmiany w WPF, a nie w WndProc.
źródło