首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Application.AddMessageFilter之后从未调用过IMessageFilter.PreFilterMessage

在Application.AddMessageFilter之后从未调用过IMessageFilter.PreFilterMessage
EN

Stack Overflow用户
提问于 2020-07-30 21:17:06
回答 1查看 252关注 0票数 0

在调用Application.AddMessageFilter之后,永远不会调用PreFilterMessage方法。它只是在一个简单的WPF应用程序中(如下所示)。我是不是漏掉了什么?

代码语言:javascript
复制
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;
    }
}
EN

回答 1

Stack Overflow用户

发布于 2020-07-31 00:29:41

我在WinForms下成功地使用了IMessageFilter,但我不确定它在WPF下是否能正常工作。

如果你需要在WPF中截取一些消息,还有另一种方法。

这种方式不同于MessageFilter,因为它不能过滤消息,只能监听消息循环。

让我们来听一听WM_KEYDOWN消息。

显示完整的应用程序代码,以便于重现

MyMessageHook.cs

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
<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>

请注意,TextBox是只读的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63174051

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档