WPF--How to handle WndProc messages in WPF?

Finding WPF a steep learning curve.

In good ol' Windows Forms, I'd just override WndProc, and start handling messages as they came in.

Can someone show me an example of how to acheive the same thing in WPF?

link | flag
 
  

9 Answers

up vote 10 down vote accepted

Actually, as far as I understand such a thing is indeed possible in WPF using HwndSource and HwndSourceHook. See this thread on MSDN as an example. (The code posted works fine - the question is about something slightly specialised.)

Now, I'm not quite sure why you'd want to handle Windows Messaging messages in a WPF application (unless it's the most obvious form of interop for working with another WinForms app). The design ideology and the nature of the API is very different in WPF from WinForms, so I would suggest you just familiarise yourself with WPF more to see exactly why there is no equivalent of WndProc.

link | flag
 
  

You can do this via the System.Windows.Interop namespace which contains a class named HwndSource.

Example of using this

using System; 
using
System.Windows; 
using
System.Windows.Interop; 
 
namespace
WpfApplication1 
{ 
   
public partial class Window1 : Window 
   
{ 
       
public Window1() 
       
{ 
           
InitializeComponent(); 
       
} 
 
       
protected override void OnSourceInitialized(EventArgs e) 
       
{ 
           
base.OnSourceInitialized(e); 
           
HwndSource source = PresentationSource.FromVisual(this) as HwndSource; 
            source
.AddHook(WndProc); 
       
} 
 
       
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
       
{ 
           
// Handle messages... 
 
           
return IntPtr.Zero; 
       
} 
   
} 
} 

Completely taken from the excellent blog post: Using a custom WndProc in WPF apps by Steve Rands

link | flag
 
  

HwndSource src = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle); src.AddHook(new HwndSourceHook(WndProc));

.......

public IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) {

if(msg == THEMESSAGEIMLOOKINGFOR) { //Do something here }

return IntPtr.Zero; }

link | flag
 
  

No disrespect to the other posters - but the world doesn't actually run on WPF and a lot of third party apps, especially C/C++ ones, use Windows Messaging as a way to broadcast data, or to add special hardware events. It's nice to say 'you don't need it with WPF', but that's both being shortsighted and not actually answering the question asked - especially if you don't actually explain WHY you don't need it in the context of the question asked.

You're thinking 'you don't need it', but to me, it reads 'WPF has a major defect'.

link | flag
 
  

The short answer is you can't. WndProc works by passing messages to a HWND on a Win32 level. WPF windows have no HWND and hence can't participate in WndProc messages. The base WPF message loop does sit on top of WndProc but it abstracts them away from core WPF logic.

You can use a HWndHost and get at a WndProc for it. However this is almost certainly not what you want to do. For the majority of purposes, WPF does not operate on HWND and WndProc. Your solution almost certainly relies on making a change in WPF not in WndProc.

link | flag
 
  

You can find another explanation for attaching to WndProc here.

link | flag
 
  

There are ways to handle messages with a WndProc in WPF (e.g. using a HwndSource, etc.), but generally those techniques are reserved for interop with messages that can't directly be handled through WPF. Most WPF controls aren't even windows in the Win32 (and by extension Windows.Forms) sense, so they won't have WndProcs.

link | flag
 
  

WPF doesn't operate on WinForms type wndprocs

You can host an HWndHost in an appropriate WPF element then override the Hwndhost's wndproc, but AFAIK that's as close as you're going to get.

http://msdn.microsoft.com/en-us/library/ms742522.aspx

http://blogs.msdn.com/nickkramer/archive/2006/03/18/554235.aspx

link | flag
 
  

I have tried use the code on the MSDN thread example you gave only that I used WM_QUERYENDSESION. I was trying to imitate the behavior where user shutsdown/restart/logoff, my application propts for "Do you want to save changes?" then close the file i'm using. However nothing happens when I click yes/no, my application does not close. and if I try to close it again using the close button, I receive an error? why is this so? is it because of the added Hook??

link | flag
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值