Reputation: 9541
After calling Application.AddMessageFilter, the PreFilterMessage method is never called. It's just in a simple WPF application (below). Is there something I've missed here?
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var _filter = new PreMessageFilter();
Application.AddMessageFilter(_filter);
}
}
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public class PreMessageFilter : IMessageFilter
{
public bool PreFilterMessage(ref Message m)
{
Console.WriteLine(m.ToString());
return true;
}
}
Upvotes: 0
Views: 1316
Reputation: 4824
I successfully used IMessageFilter
under WinForms but I'm not sure if it can work properly under WPF.
If you need some messages to be intercepted in WPF, there's the other way of doing it.
This way is different from MessageFilter
because it can't filter the messages but just listening for Message Loop.
Let's listen WM_KEYDOWN
message.
Showing the full App code to make it easy to reproduce
MyMessageHook.cs
using System;
using System.Windows.Input;
using System.Windows.Interop;
namespace WPFMessageHookExample
{
public class MyKeyEventArgs : EventArgs
{
public Key Key { get; private set; }
public MyKeyEventArgs(Key key) { Key = key; }
}
public class MyMessageHook : IDisposable
{
private const int WM_KEYDOWN = 0x0100;
private readonly HwndSourceHook _hook;
private static HwndSource _hwndSource;
public event EventHandler<MyKeyEventArgs> KeyDown;
public MyMessageHook(HwndSource hwndSource)
{
_hook = new HwndSourceHook(WndProc);
_hwndSource = hwndSource ?? throw new ArgumentNullException(nameof(hwndSource));
_hwndSource.AddHook(_hook);
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
{
case WM_KEYDOWN:
KeyDown?.Invoke(this, new MyKeyEventArgs(KeyInterop.KeyFromVirtualKey((int)wParam)));
break;
}
return IntPtr.Zero;
}
#region IDisposable
private bool disposed;
protected virtual void Dispose(bool disposing)
{
if (disposed) return;
if (disposing)
{
_hwndSource.RemoveHook(_hook);
}
disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~MyMessageHook()
{
Dispose(false);
}
#endregion
}
}
MainWindow.xaml.cs
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Interop;
namespace WPFMessageHookExample
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
private MyMessageHook messageHook;
private string _myText;
public string MyText
{
get => _myText;
set
{
_myText = value;
OnPropertyChanged();
}
}
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
private void Window_SourceInitialized(object sender, EventArgs e)
{
HwndSource hwnd = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
messageHook = new MyMessageHook(hwnd);
messageHook.KeyDown += MessageHook_KeyDown;
}
private void MessageHook_KeyDown(object sender, MyKeyEventArgs e)
{
MyText += e.Key + ", ";
}
private void Window_Closing(object sender, CancelEventArgs e)
{
messageHook.Dispose();
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
MainWindow.xaml
<Window x:Class="WPFMessageHookExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFMessageHookExample"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" SourceInitialized="Window_SourceInitialized" Closing="Window_Closing">
<Grid>
<TextBox Margin="5" VerticalScrollBarVisibility="Auto" Text="{Binding MyText}" IsReadOnly="True" TextWrapping="Wrap"/>
</Grid>
</Window>
Note that TextBox
is Read-Only.
Upvotes: 1