当其客户区被控件覆盖时,处理 WinForms 窗体中的鼠标后退和前进按钮

Process mouse back and forward buttons in WinForms form when its client area is covered by controls

我有一个为经典 .NET Framework(即 v4.7.2)编写的 WinForms 应用程序。我需要以其中一种形式处理鼠标后退和前进按钮。问题是表单完全被其他控件(如 SplitContainer 和 Panels)覆盖,我找不到使用标准本机 .NET 技术拦截所需按钮的方法。

例如,覆盖 WndProc

的解决方案
private const int WM_XBUTTONDOWN = 0x020B;
private const int MK_XBUTTON1 = 0x0020;
private const int MK_XBUTTON2 = 0x0040;

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_XBUTTONDOWN)
    {
        int lowWord = (m.WParam.ToInt32() << 16) >> 16;
        switch (lowWord)
        {
            case MK_XBUTTON1:
                // navigate backward
                break;
            case MK_XBUTTON2:
                // navigate forward
                break;
        }
    }
    base.WndProc(ref m);
}

仅当鼠标指针位于未被任何控件覆盖的客户区部分时有效。

有没有办法使用 .NET 本机技术使所有表单控件 'transparent' 用于单击鼠标 back/forward 按钮并在 WndProc 或类似的表格方法?如果没有,我是否应该使用基于 WinAPI 的低级鼠标钩子来实现我需要的东西?欢迎使用 C# 或 VB.NET 的所有解决方案。

基于 IMessageFilter 的解决方案可以解决问题:

public partial class Form1 : Form, IMessageFilter
{
    public Form1()
    {
        Application.AddMessageFilter(this);
        this.FormClosed += (s, e) => Application.RemoveMessageFilter(this);

        InitializeComponent();
    }

    private const int WM_XBUTTONDOWN = 0x020B;
    private const int MK_XBUTTON1 = 0x0020;
    private const int MK_XBUTTON2 = 0x0040;

    public bool PreFilterMessage(ref Message m)
    {
        if (m.Msg == WM_XBUTTONDOWN)
        {
            int lowWord = (m.WParam.ToInt32() << 16) >> 16;
            switch (lowWord)
            {
                case MK_XBUTTON1:
                    // navigate backward
                    BackButton_Click(null, null);
                    break;
                case MK_XBUTTON2:
                    // navigate forward
                    ForwardButton_Click(null, null);
                    break;
            }
        }
        return false; // dispatch further
    }
}