如果控件是全尺寸的

时间:2018-04-18 15:01:32

标签: c# winforms winapi

代码:

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来填充整个表单。

基于控件的wndProc挂钩代码

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。

Capture = true

如果在将control.Capture = true;发送到wndProcGlobalHook之前设置ssh $s "$@" >outfile & wait o=$(cat outfile) 它会开始发送0x200,这是一般的悬停事件,然后在我点击我的应用后停止触发它。但仍然没有0x84

0 个答案:

没有答案