代码:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.FormBorderStyle = FormBorderStyle.None; // no borders
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.ResizeRedraw, true); // this is to avoid visual artifacts
}
protected override void OnPaint(PaintEventArgs e) // you can safely omit this method if you want
{
e.Graphics.FillRectangle(Brushes.Green, Top);
e.Graphics.FillRectangle(Brushes.Green, Left);
e.Graphics.FillRectangle(Brushes.Green, Right);
e.Graphics.FillRectangle(Brushes.Green, Bottom);
}
private const int
HTLEFT = 10,
HTRIGHT = 11,
HTTOP = 12,
HTTOPLEFT = 13,
HTTOPRIGHT = 14,
HTBOTTOM = 15,
HTBOTTOMLEFT = 16,
HTBOTTOMRIGHT = 17;
const int _ = 10; // you can rename this variable if you like
Rectangle Top { get { return new Rectangle(0, 0, this.ClientSize.Width, _); } }
Rectangle Left { get { return new Rectangle(0, 0, _, this.ClientSize.Height); } }
Rectangle Bottom { get { return new Rectangle(0, this.ClientSize.Height - _, this.ClientSize.Width, _); } }
Rectangle Right { get { return new Rectangle(this.ClientSize.Width - _, 0, _, this.ClientSize.Height); } }
Rectangle TopLeft { get { return new Rectangle(0, 0, _, _); } }
Rectangle TopRight { get { return new Rectangle(this.ClientSize.Width - _, 0, _, _); } }
Rectangle BottomLeft { get { return new Rectangle(0, this.ClientSize.Height - _, _, _); } }
Rectangle BottomRight { get { return new Rectangle(this.ClientSize.Width - _, this.ClientSize.Height - _, _, _); } }
protected override void WndProc(ref Message message)
{
base.WndProc(ref message);
if (message.Msg == 0x84) // WM_NCHITTEST
{
var cursor = this.PointToClient(Cursor.Position);
if (TopLeft.Contains(cursor)) message.Result = (IntPtr)HTTOPLEFT;
else if (TopRight.Contains(cursor)) message.Result = (IntPtr)HTTOPRIGHT;
else if (BottomLeft.Contains(cursor)) message.Result = (IntPtr)HTBOTTOMLEFT;
else if (BottomRight.Contains(cursor)) message.Result = (IntPtr)HTBOTTOMRIGHT;
else if (Top.Contains(cursor)) message.Result = (IntPtr)HTTOP;
else if (Left.Contains(cursor)) message.Result = (IntPtr)HTLEFT;
else if (Right.Contains(cursor)) message.Result = (IntPtr)HTRIGHT;
else if (Bottom.Contains(cursor)) message.Result = (IntPtr)HTBOTTOM;
}
}}
但是出于某种原因,只有当我的控件不是我的表格的全尺寸时,Message才会触发。例如,如果我在Form上设置了1的填充,那么就有一个1像素的边框,然后它会触发。但如果我的控制占据了整个尺寸,它根本不会发射。
我在WinForms项目中使用CEFSharp WinForms控件,并使用StyleMode.Fill来填充整个表单。
using System;
using System.Drawing;
using System.Windows.Forms;
class wndProcGlobalHook : NativeWindow
{
private Form form;
private Control child;
const int _ = 8;
Rectangle _Top { get { return new Rectangle(0, 0, form.ClientSize.Width, _); } }
Rectangle _Left { get { return new Rectangle(0, 0, _, form.ClientSize.Height); } }
Rectangle _Bottom { get { return new Rectangle(0, form.ClientSize.Height - _, form.ClientSize.Width, _); } }
Rectangle _Right { get { return new Rectangle(form.ClientSize.Width - _, 0, _, form.ClientSize.Height); } }
Rectangle TopLeft { get { return new Rectangle(0, 0, _, _); } }
Rectangle TopRight { get { return new Rectangle(form.ClientSize.Width - _, 0, _, _); } }
Rectangle BottomLeft { get { return new Rectangle(0, form.ClientSize.Height - _, _, _); } }
Rectangle BottomRight { get { return new Rectangle(form.ClientSize.Width - _, form.ClientSize.Height - _, _, _); } }
public wndProcGlobalHook(Form form, Control child)
{
this.form = form;
this.child = child;
AssignHandle(child.Handle);
}
protected override void WndProc(ref Message m)
{
System.Diagnostics.Debug.Write("wndProc executed");
if (m.Msg == 0x84) {
System.Diagnostics.Debug.Write("0x84 :D:D:D");
Point cursor = child.PointToClient(Cursor.Position);
System.Diagnostics.Debug.Write("Cursor: " + cursor.ToString());
if (TopLeft.Contains(cursor)) {
m.Result = (IntPtr)13;
} else if (TopRight.Contains(cursor)) {
m.Result = (IntPtr)14;
} else if (BottomLeft.Contains(cursor)) {
m.Result = (IntPtr)16;
} else if (BottomRight.Contains(cursor)) {
m.Result = (IntPtr)17;
} else if (_Top.Contains(cursor)) {
m.Result = (IntPtr)12;
} else if (_Left.Contains(cursor)) {
m.Result = (IntPtr)10;
} else if (_Right.Contains(cursor)) {
m.Result = (IntPtr)11;
} else if (_Bottom.Contains(cursor)) {
m.Result = (IntPtr)15;
}
}
base.WndProc(ref m);
}
}
然后在Form1中:
//where ui == ChromiumWebBrowser control
new wndProcGlobalHook(this, ui);
foreach (Control ctrl in ui.Controls) {
new wndProcGlobalHook(this, ctrl);
}
调用大量其他消息但从不调用0x84。最近的一个在启动时被称为0x85。
如果在将control.Capture = true;
发送到wndProcGlobalHook之前设置ssh $s "$@" >outfile &
wait
o=$(cat outfile)
它会开始发送0x200,这是一般的悬停事件,然后在我点击我的应用后停止触发它。但仍然没有0x84