使无边界的forms可移动?

有没有一种方法来做一个没有边界的窗体(FormBorderStyle被设置为“none”),当鼠标在窗体上被点击时,就像有一个边框一样可移动? 谢谢。

这篇关于CodeProject的文章详细介绍了一种技术。 基本上归结为:

public const int WM_NCLBUTTONDOWN = 0xA1; public const int HT_CAPTION = 0x2; [System.Runtime.InteropServices.DllImportAttribute("user32.dll")] public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); [System.Runtime.InteropServices.DllImportAttribute("user32.dll")] public static extern bool ReleaseCapture(); private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) { if (e.Button == MouseButtons.Left) { ReleaseCapture(); SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0); } } 

从窗口pipe理器的angular度来看,这基本上和抓取窗口的标题栏一样。

另一个更简单的方法来做同样的事情。

 public partial class Form1 : Form { public Form1() { InitializeComponent(); // set this.FormBorderStyle to None here if needed // if set to none, make sure you have a way to close the form! } protected override void WndProc(ref Message m) { base.WndProc(ref m); if (m.Msg == WM_NCHITTEST) m.Result = (IntPtr)(HT_CAPTION); } private const int WM_NCHITTEST = 0x84; private const int HT_CLIENT = 0x1; private const int HT_CAPTION = 0x2; } 

我们不要让事情比他们需要的更困难。 我遇到了很多代码片段,允许你拖动一个窗体(或另一个控件)。 而且他们中的许多人都有自己的缺点/副作用。 尤其是那些让Windows认为窗体上的控件是实际窗体的那些窗体。

这就是说,这是我的片段。 我一直使用它。 我还想指出,你不应该使用this.Invalidate(); 就像别人喜欢做的一样,因为它会导致表格在某些情况下闪烁。 在某些情况下,这样做。刷新。 使用this.Update,我没有任何闪烁的问题:

 private bool mouseDown; private Point lastLocation; private void Form1_MouseDown(object sender, MouseEventArgs e) { mouseDown = true; lastLocation = e.Location; } private void Form1_MouseMove(object sender, MouseEventArgs e) { if(mouseDown) { this.Location = new Point( (this.Location.X - lastLocation.X) + eX, (this.Location.Y - lastLocation.Y) + eY); this.Update(); } } private void Form1_MouseUp(object sender, MouseEventArgs e) { mouseDown = false; } 

使用MouseDown,MouseMove和MouseUp。 你可以设置一个variables标志。 我有一个样本,但我认为你需要修改。

我将鼠标操作编码到面板上。 一旦你点击面板,你的表单将随之移动。

 //Global variables; private bool _dragging = false; private Point _offset; private Point _start_point=new Point(0,0); private void panel1_MouseDown(object sender, MouseEventArgs e) { _dragging = true; // _dragging is your variable flag _start_point = new Point(eX, eY); } private void panel1_MouseUp(object sender, MouseEventArgs e) { _dragging = false; } private void panel1_MouseMove(object sender, MouseEventArgs e) { if(_dragging) { Point p = PointToScreen(e.Location); Location = new Point(pX - this._start_point.X,pY - this._start_point.Y); } } 

只有WPF


没有确切的代码,但在最近的一个项目中,我想我使用了MouseDown事件,并简单地把这个:

 frmBorderless.DragMove(); 

Window.DragMove方法(MSDN)

参考。 video链接

这是testing和易于理解。

 protected override void WndProc(ref Message m) { switch (m.Msg) { case 0x84: base.WndProc(ref m); if((int)m.Result == 0x1) m.Result = (IntPtr)0x2; return; } base.WndProc(ref m); } 

没有财产,你可以翻转,让这只是神奇的事情发生。 查看表单的事件,通过设置this.Topthis.Left来实现这一点变得相当简单。 具体来说,你会想看看MouseDownMouseUpMouseMove

 public Point mouseLocation; private void frmInstallDevice_MouseDown(object sender, MouseEventArgs e) { mouseLocation = new Point(-eX, -eY); } private void frmInstallDevice_MouseMove(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { Point mousePos = Control.MousePosition; mousePos.Offset(mouseLocation.X, mouseLocation.Y); Location = mousePos; } } 

这可以解决你的问题….

对于.NET Framework 4,

您可以将this.DragMove()用于您正在使用的组件(此示例中为this.DragMove()MouseDown事件进行拖动。

 private void mainLayout_MouseDown(object sender, MouseButtonEventArgs e) { this.DragMove(); } 

我试图做一个可移动的无边框窗体,其中包含一个WPF元素主机控件和一个WPF用户控件。 我结束了在我的WPF用户控件中,名为StackPanel的堆栈面板,这似乎是合乎逻辑的尝试点击移动。 当我慢慢地移动鼠标时,尝试junmats的代码工作,但如果我更快地移动鼠标,鼠标将移动的forms和forms将卡在中间移动的某处。 这改善了他对我使用CaptureMouse和ReleaseCaptureMouse的情况的回答,现在,即使我快速移动鼠标,鼠标也不会移动窗体。

  private void StackPanel_MouseDown(object sender, MouseButtonEventArgs e) { _start_point = e.GetPosition(this); StackPanel.CaptureMouse(); } private void StackPanel_MouseUp(object sender, MouseButtonEventArgs e) { StackPanel.ReleaseMouseCapture(); } private void StackPanel_MouseMove(object sender, MouseEventArgs e) { if (StackPanel.IsMouseCaptured) { var p = _form.GetMousePositionWindowsForms(); _form.Location = new System.Drawing.Point((int)(pX - this._start_point.X), (int)(pY - this._start_point.Y)); } } //Global variables; private Point _start_point = new Point(0, 0); 

https://social.msdn.microsoft.com/Forums/vstudio/en-US/d803d869-68e6-46ff-9ff1-fabf78d6393c/how-to-make-a-borderless-form-in-c?forum=csharpgeneral

从上面的链接这一点的代码做了我的情况下的伎俩:)

 protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); if (e.Button == MouseButtons.Left) { this.Capture = false; Message msg = Message.Create(this.Handle, 0XA1, new IntPtr(2), IntPtr.Zero); this.WndProc(ref msg); } } 

另外,如果您需要使用DoubleClick并将表单放大/缩小,则可以使用“第一个答案”,创build一个全局的intvariables,每次用户单击用于拖动的组件时,都会添加1。 如果variable == 2那么让你的表单变大/变小。 每半秒或一秒钟使用一个计时器来使你的variable = 0 ;

最简单的方法是:

首先创build一个名为label1的标签。 去label1的事件>鼠标事件> Label1_Mouse移动和写这些:

 if (e.Button == MouseButtons.Left){ Left += eX; Top += eY;` } 

对不起,以恢复这样一个古老的线程,但..最好的方式发现(修改ofcoarse)

  // This adds the event handler for the control private void AddDrag(Control Control) { Control.MouseDown += new System.Windows.Forms.MouseEventHandler(this.DragForm_MouseDown); } public const int WM_NCLBUTTONDOWN = 0xA1; public const int HT_CAPTION = 0x2; [System.Runtime.InteropServices.DllImportAttribute("user32.dll")] public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); [System.Runtime.InteropServices.DllImportAttribute("user32.dll")] public static extern bool ReleaseCapture(); private void DragForm_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { ReleaseCapture(); SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0); // Checks if Y = 0, if so maximize the form if (this.Location.Y == 0) { this.WindowState = FormWindowState.Maximized; } } } 

应用拖动到一个控件只需在InitializeComponent()之后插入

 AddDrag(NameOfControl); 
Interesting Posts