No Windows Forms, eu apenas substituiria WndProc
e começaria a lidar com as mensagens assim que chegassem
Alguém pode me mostrar um exemplo de como conseguir a mesma coisa no WPF?
Na verdade, tanto quanto eu entendo tal coisa é realmente possível em WPF usando HwndSource
e HwndSourceHook
. Veja este tópico no MSDN como um exemplo. (Código relevante incluído abaixo)
// '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;
}
Agora, não tenho certeza de por que você deseja lidar com mensagens do Windows Messaging em um aplicativo WPF (a menos que seja a forma mais óbvia de interoperabilidade para trabalhar com outro aplicativo WinForms). A ideologia de design e a natureza da API são muito diferentes no WPF e no WinForms, então eu sugiro que você se familiarize mais com o WPF para ver exatamente por que não há equivalente do WndProc.
WM_MOUSEWHEEL
por exemplo, a única maneira de interceptar essas mensagens de maneira confiável era adicionando oWndProc
a uma janela do WPF. Isso funcionou para mim, enquanto o oficialMouseWheelEventHandler
simplesmente não funcionou conforme o esperado. Não consegui alinhar os táquions WPF corretos para obter um comportamento confiávelMouseWheelEventHandler
, daí a necessidade de acesso direto aoWndProc
.Você pode fazer isso por meio do
System.Windows.Interop
namespace que contém uma classe chamadaHwndSource
.Exemplo de uso
Completamente retirado da excelente postagem do blog: Usando um WndProc personalizado em aplicativos WPF por Steve Rands
fonte
fonte
Se você não se importa em fazer referência a WinForms, pode usar uma solução mais orientada para MVVM que não acople o serviço à visualização. Você precisa criar e inicializar um System.Windows.Forms.NativeWindow, que é uma janela leve que pode receber mensagens.
Use SpongeHandle para registrar as mensagens nas quais você está interessado e, em seguida, substitua WndProc para processá-las:
A única desvantagem é que você precisa incluir a referência System.Windows.Forms, mas caso contrário, esta é uma solução muito encapsulada.
Mais sobre isso pode ser lido aqui
fonte
Aqui está um link sobre como substituir WindProc usando Behaviors: http://10rem.net/blog/2010/01/09/a-wpf-behavior-for-window-resize-events-in-net-35
[Editar: antes tarde do que nunca] Abaixo está minha implementação com base no link acima. Apesar de revisitar isso, eu gosto mais das implementações AddHook. Eu posso mudar para isso.
No meu caso, eu queria saber quando a janela estava sendo redimensionada e algumas outras coisas. Essa implementação conecta-se ao xaml do Windows e envia eventos.
fonte
Here is a link...
, como acima.Você pode anexar à classe 'SystemEvents' da classe Win32 integrada:
em uma classe de janela WPF:
fonte
Existem maneiras de lidar com mensagens com um WndProc no WPF (por exemplo, usando um HwndSource, etc.), mas geralmente essas técnicas são reservadas para interoperabilidade com mensagens que não podem ser tratadas diretamente através do WPF. A maioria dos controles WPF nem mesmo são janelas no sentido Win32 (e, por extensão, Windows.Forms), portanto, não terão WndProcs.
fonte
WndProc
para substituição, oSystem.Windows.Interop
permite obter umHwndSource
objeto por meio deHwndSource.FromHwnd
ouPresentationSource.FromVisual(someForm) as HwndSource
, ao qual você pode vincular um delegado especialmente padronizado. Este delegado tem muitos dos mesmos argumentos de umWndProc
objeto Message.WPF não opera em wndprocs do tipo WinForms
Você pode hospedar um HWndHost em um elemento WPF apropriado e, em seguida, substituir o wndproc do Hwndhost, mas AFAIK é o mais próximo que você conseguirá.
http://msdn.microsoft.com/en-us/library/ms742522.aspx
http://blogs.msdn.com/nickkramer/archive/2006/03/18/554235.aspx
fonte
A resposta curta é que você não pode. WndProc funciona passando mensagens para um HWND em um nível Win32. As janelas WPF não têm HWND e, portanto, não podem participar de mensagens WndProc. O loop de mensagem básico do WPF fica sobre o WndProc, mas os abstrai da lógica principal do WPF.
Você pode usar um HWndHost e obter um WndProc para isso. No entanto, quase certamente não é isso que você deseja fazer. Para a maioria dos propósitos, o WPF não opera em HWND e WndProc. Sua solução quase certamente depende de fazer uma alteração no WPF e não no WndProc.
fonte