The problem here is that it is the Label control that gets the mouse notifications, not your borderless form. By far the best way to solve this problem is making the label transparent to the mouse. You already know how to do that, WM_NCHITTEST also permits returning HTTRANSPARENT. Windows keeps looking for the next candidate for the notification, it will be the label's Parent.
Especially easy to do for a label since you don't normally have any use for its mouse events at all:
using System;
using System.Windows.Forms;
public class LabelEx : Label {
protected override void WndProc(ref Message m) {
const int wmNcHitTest = 0x84;
const int htTransparent = -1;
if (!DesignMode && m.Msg == wmNcHitTest) m.Result = new IntPtr(htTransparent);
else base.WndProc(ref m);
}
}
Works for any Control class, you'd want to be more selective if it were a button. Might be all you need, still pretty awkward however if you have a lot of different kind of controls close to the edge. Another technique you can use is called "sub-classing" in native Windows programming. Universally used in Winforms to create wrapper .NET classes for native Windows controls. It works well here too, you can have a peek at the messages of any control and intercept WM_NCHITTEST that way:
const int edge = 16;
class MouseFilter : NativeWindow {
private Form form;
public MouseFilter(Form form, Control child) {
this.form = form;
this.AssignHandle(child.Handle);
}
protected override void WndProc(ref Message m) {
const int wmNcHitTest = 0x84;
const int htTransparent = -1;
if (m.Msg == wmNcHitTest) {
var pos = new Point(m.LParam.ToInt32());
if (pos.X < this.form.Left + edge ||
pos.Y < this.form.Top + edge||
pos.X > this.form.Right - edge ||
pos.Y > this.form.Bottom - edge) {
m.Result = new IntPtr(htTransparent);
return;
}
}
base.WndProc(ref m);
}
}
And just create a MouseFilter instance for every control that gets close to the window edge:
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
subClassChildren(this.Controls);
}
private void subClassChildren(Control.ControlCollection ctls) {
foreach (Control ctl in ctls) {
var rc = this.RectangleToClient(this.RectangleToScreen(ctl.DisplayRectangle));
if (rc.Left < edge || rc.Right > this.ClientSize.Width - edge ||
rc.Top < edge || rc.Bottom > this.ClientSize.Height - edge) {
new MouseFilter(this, ctl);
}
subClassChildren(ctl.Controls);
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…