Code:
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;
}
}}
But for some reason the Message only fires when I have my control NOT full-size of my form. For example if I set a padding of 1 on my Form, so there's a 1-pixel border, then it fires. But if my control takes up the full size, it doesn't fire at all ever.
I'm using a CEFSharp WinForms control on a WinForms project with it StyleMode.Fill to fill the entire Form.
The Control-Based wndProc hook code
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);
}
}
Then in Form1:
//where ui == ChromiumWebBrowser control
new wndProcGlobalHook(this, ui);
foreach (Control ctrl in ui.Controls) {
new wndProcGlobalHook(this, ctrl);
}
Calling tons of other Messages but never 0x84. Closest one called was 0x85 on startup.
Capture = true
If I set control.Capture = true;
before sending it to wndProcGlobalHook it starts sending 0x200 which is a general hover event and then stops firing it once I click my app. But still no 0x84