Is there a way to make a form that has no border (FormBorderStyle is set to \"none\") movable when the mouse is clicked down on the form just as if there was a border?
问题:
回答1:
This article on CodeProject details a technique. Is basically boils down to:
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);
}
}
This essentially does exactly the same as grabbing the title bar of a window, from the window manager\'s point of view.
回答2:
Let\'s not make things any more difficult than they need to be. I\'ve come across so many snippets of code that allow you to drag a form around (or another Control). And many of them have their own drawbacks/side effects. Especially those ones where they trick Windows into thinking that a Control on a form is the actual form.
That being said, here is my snippet. I use it all the time. I\'d also like to note that you should not use this.Invalidate(); as others like to do because it causes the form to flicker in some cases. And in some cases so does this.Refresh. Using this.Update, I have not had any flickering issues:
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) + e.X, (this.Location.Y - lastLocation.Y) + e.Y);
this.Update();
}
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
mouseDown = false;
}
回答3:
Another simpler way to do the same thing.
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;
}
回答4:
use MouseDown, MouseMove and MouseUp. You can set a variable flag for that. I have a sample, but I think you need to revise.
I am coding the mouse action to a panel. Once you click the panel, your form will move with it.
//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(e.X, e.Y);
}
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(p.X - this._start_point.X,p.Y - this._start_point.Y);
}
}
回答5:
WPF only
don\'t have the exact code to hand, but in a recent project I think I used MouseDown event and simply put this:
frmBorderless.DragMove();
Window.DragMove Method (MSDN)
回答6:
Ref. video Link
This is tested and easy to understand.
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);
}
回答7:
There\'s no property you can flip to make this just happen magically. Look at the events for the form and it becomes fairly trivial to implement this by setting this.Top
and this.Left
. Specifically you\'ll want to look at MouseDown
, MouseUp
and MouseMove
.
回答8:
public Point mouseLocation;
private void frmInstallDevice_MouseDown(object sender, MouseEventArgs e)
{
mouseLocation = new Point(-e.X, -e.Y);
}
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;
}
}
this can solve ur problem....
回答9:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/d803d869-68e6-46ff-9ff1-fabf78d6393c/how-to-make-a-borderless-form-in-c?forum=csharpgeneral
This bit of code from the above link did the trick in my case :)
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);
}
}
回答10:
Best way I\'ve found (modified of course)
// 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; }
}
}
To apply drag to a control simply insert this after InitializeComponent()
AddDrag(NameOfControl);
回答11:
For .NET Framework 4,
You can use this.DragMove()
for the MouseDown
event of the component (mainLayout in this example) you are using to drag.
private void mainLayout_MouseDown(object sender, MouseButtonEventArgs e)
{
this.DragMove();
}
回答12:
Also if you need to DoubleClick and make your Form bigger/smaller , you can use the First answer, create a global int variable, add 1 every time user clicks on the component you use for dragging. If variable == 2
then make your form bigger/smaller. Also use a timer for every half a sec or a second to make your variable = 0
;
回答13:
Easiest way is:
First create a label named label1. Go to label1\'s events > mouse events > Label1_Mouse Move and write these:
if (e.Button == MouseButtons.Left){
Left += e.X;
Top += e.Y;`
}
回答14:
I was trying to make a borderless windows form movable which contained a WPF Element Host control and a WPF User control.
I ended up with a stack panel called StackPanel in my WPF user control which seemed the logical thing to try click on to move. Trying junmats\'s code worked when I moved the mouse slowly, but if I moved the mouse faster, the mouse would move off the form and the form would be stuck somewhere mid move.
This improved on his answer for my situation using CaptureMouse and ReleaseCaptureMouse and now the mouse does not move off the form while moving it even if I move it quickly.
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)(p.X - this._start_point.X), (int)(p.Y - this._start_point.Y));
}
}
//Global variables;
private Point _start_point = new Point(0, 0);
回答15:
Since some answers do not allow for child controls to be draggable, I\'ve created a little helper class. It should be passed the top level form. Can be made more generic if desired.
class MouseDragger
{
private readonly Form _form;
private Point _mouseDown;
protected void OnMouseDown(object sender, MouseEventArgs e)
{
_mouseDown = e.Location;
}
protected void OnMouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
int dx = e.Location.X - _mouseDown.X;
int dy = e.Location.Y - _mouseDown.Y;
_form.Location = new Point(_form.Location.X + dx, _form.Location.Y + dy);
}
}
public MouseDragger(Form form)
{
_form = form;
MakeDraggable(_form);
}
private void MakeDraggable(Control control)
{
var type = control.GetType();
if (typeof(Button).IsAssignableFrom(type))
{
return;
}
control.MouseDown += OnMouseDown;
control.MouseMove += OnMouseMove;
foreach (Control child in control.Controls)
{
MakeDraggable(child);
}
}
}
回答16:
Adding a MouseLeftButtonDown
event handler to the MainWindow worked for me.
In the event function that gets automatically generated, add the below code:
base.OnMouseLeftButtonDown(e);
this.DragMove();
回答17:
I tried the following and presto changeo, my transparent window was no longer frozen in place but could be moved!! (throw away all those other complex solutions above...)
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
// Begin dragging the window
this.DragMove();
}