Di Windows Forms, saya baru saja mengganti WndProc
, dan mulai menangani pesan saat mereka masuk.
Bisakah seseorang menunjukkan kepada saya contoh bagaimana mencapai hal yang sama di WPF?
Sebenarnya, sejauh yang saya pahami hal seperti itu memang mungkin di WPF menggunakan HwndSource
dan HwndSourceHook
. Lihat utas ini di MSDN sebagai contoh. (Kode yang relevan disertakan di bawah)
// '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;
}
Sekarang, saya tidak begitu yakin mengapa Anda ingin menangani pesan Perpesanan Windows dalam aplikasi WPF (kecuali itu adalah bentuk interop yang paling jelas untuk bekerja dengan aplikasi WinForms lain). Ideologi desain dan sifat API sangat berbeda di WPF dari WinForms, jadi saya sarankan Anda membiasakan diri dengan WPF lebih banyak untuk melihat dengan tepat mengapa tidak ada yang setara dengan WndProc.
WM_MOUSEWHEEL
misalnya, satu-satunya cara untuk menjebak pesan tersebut adalah dengan menambahkanWndProc
ke jendela WPF. Ini berhasil untuk saya, sedangkan pejabatMouseWheelEventHandler
tidak bekerja seperti yang diharapkan. Saya tidak bisa mendapatkan tachyons WPF yang benar yang berbaris tepat untuk mendapatkan perilaku yang dapat diandalkanMouseWheelEventHandler
, oleh karena itu perlu akses langsung keWndProc
.Anda dapat melakukan ini melalui
System.Windows.Interop
namespace yang berisi kelas bernamaHwndSource
.Contoh penggunaan ini
Sepenuhnya diambil dari posting blog yang luar biasa: Menggunakan WndProc khusus di aplikasi WPF oleh Steve Rands
sumber
sumber
Jika Anda tidak keberatan merujuk WinForms, Anda dapat menggunakan solusi yang lebih berorientasi MVVM yang tidak memasangkan layanan dengan tampilan. Anda perlu membuat dan menginisialisasi System.Windows.Forms.NativeWindow yang merupakan jendela ringan yang dapat menerima pesan.
Gunakan SpongeHandle untuk mendaftar pesan yang Anda minati dan kemudian ganti WndProc untuk memprosesnya:
Satu-satunya downside adalah Anda harus menyertakan referensi System.Windows.Forms, tetapi selain itu ini adalah solusi yang sangat dikemas.
Lebih lanjut tentang ini bisa dibaca di sini
sumber
Berikut ini tautan untuk mengganti WindProc menggunakan Behaviors: http://10rem.net/blog/2010/01/09/a-wpf-behavior-for-window-resize-events-in-net-35
[Sunting: lebih baik terlambat daripada tidak sama sekali] Di bawah ini adalah implementasi saya berdasarkan tautan di atas. Meskipun mengunjungi kembali ini, saya lebih menyukai implementasi AddHook. Saya mungkin beralih ke itu.
Dalam kasus saya, saya ingin tahu kapan jendela diubah ukurannya dan beberapa hal lainnya. Implementasi ini terhubung ke Window xaml dan mengirimkan event.
sumber
Here is a link...
jawaban tepat , seperti di atas.Anda dapat melampirkan ke kelas 'SystemEvents' dari kelas Win32 bawaan:
di kelas jendela WPF:
sumber
Ada cara untuk menangani pesan dengan WndProc di WPF (misalnya menggunakan HwndSource, dll.), Tetapi umumnya teknik tersebut dicadangkan untuk interop dengan pesan yang tidak dapat ditangani secara langsung melalui WPF. Kebanyakan kontrol WPF bahkan bukan windows dalam pengertian Win32 (dan dengan ekstensi Windows.Forms), jadi mereka tidak akan memiliki WndProcs.
sumber
WndProc
untuk ditimpa, namunSystem.Windows.Interop
memungkinkan Anda untuk mendapatkanHwndSource
objek dengan caraHwndSource.FromHwnd
atauPresentationSource.FromVisual(someForm) as HwndSource
, yang dapat Anda ikat ke delegasi berpola khusus. Delegasi ini memiliki banyak argumen yang sama denganWndProc
objek Message.WPF tidak beroperasi pada wndprocs tipe WinForms
Anda dapat meng-host HWndHost dalam elemen WPF yang sesuai kemudian menimpa wndproc Hwndhost, tetapi AFAIK sedekat yang akan Anda dapatkan.
http://msdn.microsoft.com/en-us/library/ms742522.aspx
http://blogs.msdn.com/nickkramer/archive/2006/03/18/554235.aspx
sumber
Jawaban singkatnya adalah Anda tidak bisa. WndProc bekerja dengan meneruskan pesan ke HWND pada level Win32. Jendela WPF tidak memiliki HWND dan karenanya tidak dapat berpartisipasi dalam pesan WndProc. Loop pesan WPF dasar tidak berada di atas WndProc tetapi memisahkannya dari logika inti WPF.
Anda dapat menggunakan HWndHost dan mendapatkan WndProc untuk itu. Namun ini hampir pasti bukan yang ingin Anda lakukan. Untuk sebagian besar tujuan, WPF tidak beroperasi di HWND dan WndProc. Solusi Anda hampir pasti bergantung pada membuat perubahan di WPF, bukan di WndProc.
sumber