.net - 当其客户区被控件覆盖时,处理 WinForms 窗体中的鼠标后退和前进按钮
问题描述
我有一个为经典的 .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 本机技术使所有表单控件“透明”以单击鼠标后退/前进按钮,并以WndProc
或类似的表单方法处理这些 x 按钮?如果没有,我应该使用基于 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
}
}
推荐阅读
- arrays - 函数中的 PostgreSQL 数组格式化
- c# - 我有多个表,我想在 2 个表中存储包含数据的文件,如何使用 AngularJs 在不同的表中上传不同的文件?
- swift - 无法将 iCloud 数据加载到 UITableView
- django - 当 debug=false 时 Django 媒体文件不起作用
- asp.net - 在 asp.net core 中生成报告的最佳方法是什么?
- sql-server - 将每个日期的多个相同日期行转换为单个
- xamarin - 删除玩家记录系统时会在 Xamarin Forms 中引发对象引用错误
- python-3.x - 如何解决实例属性类中的“属性错误”?
- shell - 迭代函数的输出
- html - 如何为输入字段提供全宽和全高