大佬教程收集整理的这篇文章主要介绍了WinForms 编辑器:覆盖 WndProc WM_NCHITEST 时无法选择表单控件,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
WM_NCHITEST
的 WndProc
。问题是放置在表单中的所有控件都无法通过单击来选择。我可以通过选择容器内的一个区域来选择面板之类的容器,但是当我点击它们时,我再次选择了表单。这也意味着我不能通过拖动来放置控件。
@H_944_2@这是 borderlessResizeableForm
类:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.windows.Forms;
namespace CustomWinFormsControls {
/// <sumMary>
/// Form with a <see cref="Formborderstyle.None"/> which can be resized and moved if Drag control is set.
/// </sumMary>
public class borderlessResizableForm : Form {
private FormDragControl dragControl;
private Dictionary<Control,borderWndProcFilter> borderFilters;
privatE int _resizeborderThickness = 5;
/// <sumMary>
/// The control which should be used to move the window around.
/// </sumMary>
[Editorbrowsable(EditorbrowsableState.Always)]
[browsable(true)]
[DefaultValue(null)]
[category("BehavIoUr")]
[Description("The control which should be used to move the window around.")]
public Control DragTarget {
get => this.dragControl?.Target;
set {
if (!(this.dragControl is null))
this.dragControl.Target = value;
}
}
/// <sumMary>
/// The thickness of the resize border on all sIDes of the window. The border is invisible. SetTing it will not result in a padding.
/// </sumMary>
[Editorbrowsable(EditorbrowsableState.Always)]
[browsable(true)]
[DefaultValue(null)]
[category("BehavIoUr")]
[Description("The thickness of the resize border on all sIDes of the window. The border is invisible. SetTing it will not result in a padding.")]
public int ResizeborderThickness {
get => this._resizeborderThickness;
set {
if (this._resizeborderThickness == value)
return;
this._resizeborderThickness = value;
foreach (borderWndProcFilter filter in this.borderFilters.Values)
filter.borderThinckness = value;
}
}
/// <sumMary>
/// Creates a new instance of the class <see cref="borderlessResizableForm"/>
/// </sumMary>
public borderlessResizableForm() {
this.Formborderstyle = Formborderstyle.None;
this.SetStyle(ControlStyles.ResizeRedraw,truE);
this.dragControl = new FormDragControl();
this.borderFilters = new Dictionary<Control,borderWndProcFilter>();
this.ControlAdded += this.Control_ControlAdded;
this.ControlRemoved += this.Control_ControlRemoved;
}
private voID Control_ControlAdded(object sender,ControlEventArgs E) {
this.ApplyFiltersRecursive(this,e.Control);
}
private voID Control_ControlRemoved(object sender,ControlEventArgs E) {
this.RemoveFiltersRecursive(e.Control);
}
private voID ApplyFiltersRecursive(Control parent,Control control) {
if (control is null)
return;
this.borderFilters[control] = new borderWndProcFilter(parent,control,this.ResizeborderThickness);
// remove them in case they were already added.
control.ControlAdded -= this.Control_ControlAdded;
control.ControlRemoved -= this.Control_ControlRemoved;
control.ControlAdded += this.Control_ControlAdded;
control.ControlRemoved += this.Control_ControlRemoved;
foreach (Control c in control.Controls)
if (!(c is null))
this.ApplyFiltersRecursive(parent,c);
}
private voID RemoveFiltersRecursive(Control control) {
if (control is null)
return;
this.borderFilters.Remove(control);
control.ControlAdded -= this.Control_ControlAdded;
control.ControlRemoved -= this.Control_ControlRemoved;
foreach (Control c in control.Controls)
if (!(c is null))
this.RemoveFiltersRecursive(c);
}
protected overrIDe voID WndProc(ref message m) {
if (m.Msg != borderWndProcFilter.WM_NCHITTEST) {
base.WndProc(ref m);
return;
}
Point pos = this.PointToClIEnt(new Point(m.LParam.ToInt32()));
// if in top left corner
if (pos.X <= this.ResizeborderThickness && pos.Y <= this.ResizeborderThickness) {
m.Result = new IntPtr(borderWndProcFilter.HTtopleft);
return;
}
// if in top right corner
if (pos.X >= this.CLIENtSize.WIDth - this.ResizeborderThickness && pos.Y <= this.ResizeborderThickness) {
m.Result = new IntPtr(borderWndProcFilter.HTtopRIGHT);
return;
}
// if in bottom left corner
if (pos.X <= this.ResizeborderThickness && pos.Y >= this.CLIENtSize.Height - this.ResizeborderThickness) {
m.Result = new IntPtr(borderWndProcFilter.HTBottOMleft);
return;
}
// if in bottom right corner
if (pos.X >= this.CLIENtSize.WIDth - this.ResizeborderThickness && pos.Y >= this.CLIENtSize.Height - this.ResizeborderThickness) {
m.Result = new IntPtr(borderWndProcFilter.HTBottomrIGHT);
return;
}
// if on the left
if (pos.X <= this.ResizeborderThickness) {
m.Result = new IntPtr(borderWndProcFilter.HTleft);
return;
}
// if on top
if (pos.Y <= this.ResizeborderThickness) {
m.Result = new IntPtr(borderWndProcFilter.HTtop);
return;
}
// if on the right
if (pos.X >= this.CLIENtSize.WIDth - this.ResizeborderThickness) {
m.Result = new IntPtr(borderWndProcFilter.HtrigHT);
return;
}
// if on the bottom
if (pos.Y >= this.CLIENtSize.Height - this.ResizeborderThickness) {
m.Result = new IntPtr(borderWndProcFilter.HTBottOM);
return;
}
base.WndProc(ref m);
}
}
/// <sumMary>
/// A filter for the WM_NCHITTEST message to ignore it when the mouse hovers the resize border.
/// </sumMary>
public class borderWndProcFilter : NativeWindow {
public const int WM_NCHITTEST = 0x0084;
public const int HTCAPTION = 0x00000002;
public const int HTtop = 0x0000000c;
public const int HTBottOM = 0x0000000F;
public const int HTleft = 0x0000000A;
public const int HtrigHT = 0x0000000B;
public const int HTtopleft = 0x0000000D;
public const int HTtopRIGHT = 0x0000000E;
public const int HTBottOMleft = 0x00000010;
public const int HTBottomrIGHT = 0x00000011;
public const int HTtransparent = -1;
public static List<Type> TypeBlackList { get; set; } = new List<Type>();
private Control parent;
private Control child;
public int borderThinckness { get; set; }
public bool Resizeborderleft { get; set; }
public bool ResizeborderRight { get; set; }
public bool Resizebordertop { get; set; }
public bool ResizeborderBottom { get; set; }
/// <sumMary>
/// Creates a new instance of the class <see cref="borderWndProcFilter"/>. Sets all borders to true.
/// </sumMary>
/// <param name="parent">The resizable control which should have a non blocked resize border.</param>
/// <param name="child">The child control the filter should be applIEd to for not blocking the resize border of the parent control.</param>
/// <param name="borderThinckness">The resize border thickness of the parent.</param>
public borderWndProcFilter(Control parent,Control child,int borderThinckness) {
this.parent = parent;
this.child = child;
try {
if (!borderWndProcFilter.TypeBlackList.Contains(child.GetType()))
this.AssignHandle(child.HandlE);
} catch (Exception) { }
this.borderThinckness = borderThinckness;
this.Resizeborderleft = true;
this.ResizeborderRight = true;
this.Resizebordertop = true;
this.ResizeborderBottom = true;
}
/// <sumMary>
/// Creates a new instance of the class <see cref="borderWndProcFilter"/>. Sets all borders to true.
/// </sumMary>
/// <param name="parent">The resizable control which should have a non blocked resize border.</param>
/// <param name="child">The child control the filter should be applIEd to for not blocking the resize border of the parent control.</param>
/// <param name="borderThinckness">The resize border thickness of the parent.</param>
/// <param name="left">If true the parent has a left-sIDe resize border which should not be blocked.</param>
/// <param name="right">If true the parent has a right-sIDe resize border which should not be blocked.</param>
/// <param name="top">If true the parent has a top-sIDe resize border which should not be blocked.</param>
/// <param name="bottom">If true the parent has a bottom-sIDe resize border which should not be blocked.</param>
public borderWndProcFilter(Control parent,int borderThinckness,bool left,bool right,bool top,bool bottom) {
this.parent = parent;
this.child = child;
this.AssignHandle(child.HandlE);
this.borderThinckness = borderThinckness;
this.Resizeborderleft = left;
this.ResizeborderRight = right;
this.Resizebordertop = top;
this.ResizeborderBottom = bottom;
}
protected overrIDe voID WndProc(ref message m) {
if (m.Msg != WM_NCHITTEST) {
base.WndProc(ref m);
return;
}
if (this.parent is null) {
base.WndProc(ref m);
return;
}
Point pos = new Point(m.LParam.ToInt32());
Point parentGlobalPos = this.parent is Form ? this.parent.LOCATIOn : this.parent.PointToScreen(this.parent.LOCATIOn);
// if on the left
if (pos.X <= parentGlobalPos.X + this.borderThinckness && this.Resizeborderleft) {
m.Result = new IntPtr(HTtransparent);
return;
}
// if on top
if (pos.Y <= parentGlobalPos.Y + this.borderThinckness && this.Resizebordertop) {
m.Result = new IntPtr(HTtransparent);
return;
}
// if on the right
if (pos.X >= parentGlobalPos.X + this.parent.WIDth - this.borderThinckness && this.ResizeborderRight) {
m.Result = new IntPtr(HTtransparent);
return;
}
// if on the bottom
if (pos.Y >= parentGlobalPos.Y + this.parent.Height - this.borderThinckness && this.ResizeborderBottom) {
m.Result = new IntPtr(HTtransparent);
return;
}
base.WndProc(ref m);
}
}
}
@H_944_2@编辑:
我还尝试在设计时忽略 WndProc,但这也不起作用:
if (licenseManager.UsageMode == licenseUsageMode.DesigntimE) {
base.WndProc(ref m);
return;
}
以上是大佬教程为你收集整理的WinForms 编辑器:覆盖 WndProc WM_NCHITEST 时无法选择表单控件全部内容,希望文章能够帮你解决WinForms 编辑器:覆盖 WndProc WM_NCHITEST 时无法选择表单控件所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。