Windows11下C#窗体透明PictureBox鼠标事件拦截异常问题排查
透明PictureBox的鼠标事件拦截问题
我在Windows 11的C#环境中创建了一个带纯色背景和透明PictureBox的窗体。窗体加载后,PictureBox确实呈现透明状态,但鼠标移动到该透明区域时,鼠标处理事件会被发送到窗体后方的对象。
为了让窗体能够处理透明区域的鼠标悬停事件,我重写了WndProc方法,拦截WM_NCHITTEST消息并返回值为1的HTCLIENT。更新WndProc后,我可以接收到Form_MouseMove的消息,但PictureBox_MouseMove的消息完全没有响应,且透过透明元素可见的窗体后方对象仍在处理鼠标事件。我认为可以通过拦截这些鼠标控制消息来强制窗体处理它们,但始终无法找到实现方法。
相关C#代码
using System; using System.Drawing; using System.Windows.Forms; namespace TransparentFormExample { public class TransparentForm : Form { private PictureBox pictureBox; public TransparentForm() { // 设置窗体属性 this.TransparencyKey = Color.LimeGreen; this.Size = new Size(500, 800); this.TopMost = true; // 初始化并设置PictureBox属性 pictureBox = new PictureBox { BackColor = Color.LimeGreen, Size = new Size(200, 200), Location = new Point(150, 300) // 在窗体中居中 }; // 将PictureBox添加到窗体 this.Controls.Add(pictureBox); // 添加事件处理器 this.MouseMove += new MouseEventHandler(Form_MouseMove); pictureBox.MouseMove += new MouseEventHandler(PictureBox_MouseMove); } // 重写WndProc处理WM_NCHITTEST消息 protected override void WndProc(ref Message m) { const int WM_NCHITTEST = 0x84; const int HTCLIENT = 0x1; if (m.Msg == WM_NCHITTEST) { m.Result = (IntPtr)HTCLIENT; return; } base.WndProc(ref m); } private void Form_MouseMove(object sender, MouseEventArgs e) { Console.WriteLine("Mouse over form"); } private void PictureBox_MouseMove(object sender, MouseEventArgs e) { // 加空格方便识别是否触发 Console.WriteLine(" Mouse over PictureBox"); } public void Start () { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault( false ); Application.Run( this ); } } }
PowerShell启动代码
write-host "load main.cs" add-type -path "TransparentForm.cs" -ReferencedAssemblies @( "System.Windows.Forms" "System.Drawing" "System.Drawing.Primitives" ) $ProgramInstance = [TransparentFormExample.TransparentForm]::New() [System.Windows.Forms.Application]::Run( $ProgramInstance )
内容的提问来源于stack exchange,提问作者Ro Yo Mi
相关产品推荐
相关产品推荐

