Related
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?
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.DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[System.Runtime.InteropServices.DllImport("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.
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;
}
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;
}
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);
}
}
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)
It worked for Me.
private Point _mouseLoc;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
_mouseLoc = e.Location;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
int dx = e.Location.X - _mouseLoc.X;
int dy = e.Location.Y - _mouseLoc.Y;
this.Location = new Point(this.Location.X + dx, this.Location.Y + dy);
}
}
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);
}
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);
}
}
}
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.
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....
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);
}
}
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);
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();
}
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;`
}
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);
I'm expanding the solution from jay_t55 with one more method ToolStrip1_MouseLeave that handles the event of the mouse moving quickly and leaving the region.
private bool mouseDown;
private Point lastLocation;
private void ToolStrip1_MouseDown(object sender, MouseEventArgs e) {
mouseDown = true;
lastLocation = e.Location;
}
private void ToolStrip1_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 ToolStrip1_MouseUp(object sender, MouseEventArgs e) {
mouseDown = false;
}
private void ToolStrip1_MouseLeave(object sender, EventArgs e) {
mouseDown = false;
}
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;
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();
Form1(): new Moveable(control1, control2, control3);
Class:
using System;
using System.Windows.Forms;
class Moveable
{
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();
public Moveable(params Control[] controls)
{
foreach (var ctrl in controls)
{
ctrl.MouseDown += (s, e) =>
{
if (e.Button == MouseButtons.Left)
{
ReleaseCapture();
SendMessage(ctrl.FindForm().Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
// Checks if Y = 0, if so maximize the form
if (ctrl.FindForm().Location.Y == 0) { ctrl.FindForm().WindowState = FormWindowState.Maximized; }
}
};
}
}
}
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();
}
This function only recognizes mouse's Left button. How can I make this program recognize mouse's right button in order to click this button with mouse's right button?.
private void button2_Click(object sender, EventArgs e)
{
MouseEventArgs me = (MouseEventArgs)e;
if (buttonwasclicked==false)
{
DrawLinesOnBitmap(button2.BackgroundImage);
button2.BackgroundImage= ToGrayscale(button2.BackgroundImage);
buttonwasclicked = true;
}
else {
button2.BackgroundImageLayout = ImageLayout.Stretch;
button2.BackgroundImage = Image.FromFile("C:\\Users\\rati\\Desktop\\ks.png");
buttonwasclicked = false;
}
if (me.Button == MouseButtons.Left)
{
mysum += md;
if (buttonwasclicked == true) md *= -1; else md *= -1;
label1.Text = mysum.ToString();
}
if (me.Button == MouseButtons.Right) {
enemysum += ed;
if (buttonwasclicked == true) ed *= -1; else ed *= -1;
label2.Text = enemysum.ToString();
}
}
Use the "MouseClick" event rather than the "Click" event, "Click" doesn't recognise right clicks of the mouse.
If you're using Visual Studio, simply go to the designer, click the button, go to properties and click the lightning icon. Then you find "MouseClick" and double click this.
You need to use the MouseDown and MouseUp actions together in order to interpret a click.
Your actions list should look similar to this:
Then interpret the actions as follows:
int prevMouseX;
int prevMouseY;
private void mouseDown(object sender, MouseEventArgs e)
{
prevMouseX = e.X;
prevMouseY = e.Y;
}
private void mouseUp(object sender, MouseEventArgs e)
{
if (prevMouseX == e.X && prevMouseY == e.Y)
mouseClick(sender, e);
}
private void mouseClick(object sender, MouseEventArgs e)
{
//Do Stuff
}
That should work for you!
My code interprets a click as when the mouse goes down and up in the same position.
Try this if you want to do something on Button's right click event.
=> Create one context menu and do not create any option in it.(Drag & Drop ContextMenuStrip from Toolbox)
=> Assign that context menu to that button from Button's ContextMenuStrip property in Properties panel.
Write following code on Context Menu's Opening Event
private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
{
MessageBox.Show("hii");
e.Cancel=true;
}
You should use MouseDown event. It has MouseEventArgs parameter which contains Button property. So you can check wich button was down.
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?
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.DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[System.Runtime.InteropServices.DllImport("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.
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;
}
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;
}
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);
}
}
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)
It worked for Me.
private Point _mouseLoc;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
_mouseLoc = e.Location;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
int dx = e.Location.X - _mouseLoc.X;
int dy = e.Location.Y - _mouseLoc.Y;
this.Location = new Point(this.Location.X + dx, this.Location.Y + dy);
}
}
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);
}
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);
}
}
}
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.
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....
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);
}
}
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);
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();
}
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;`
}
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);
I'm expanding the solution from jay_t55 with one more method ToolStrip1_MouseLeave that handles the event of the mouse moving quickly and leaving the region.
private bool mouseDown;
private Point lastLocation;
private void ToolStrip1_MouseDown(object sender, MouseEventArgs e) {
mouseDown = true;
lastLocation = e.Location;
}
private void ToolStrip1_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 ToolStrip1_MouseUp(object sender, MouseEventArgs e) {
mouseDown = false;
}
private void ToolStrip1_MouseLeave(object sender, EventArgs e) {
mouseDown = false;
}
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;
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();
Form1(): new Moveable(control1, control2, control3);
Class:
using System;
using System.Windows.Forms;
class Moveable
{
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();
public Moveable(params Control[] controls)
{
foreach (var ctrl in controls)
{
ctrl.MouseDown += (s, e) =>
{
if (e.Button == MouseButtons.Left)
{
ReleaseCapture();
SendMessage(ctrl.FindForm().Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
// Checks if Y = 0, if so maximize the form
if (ctrl.FindForm().Location.Y == 0) { ctrl.FindForm().WindowState = FormWindowState.Maximized; }
}
};
}
}
}
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();
}
I have a Window element that has WindowStyle="None" and AllowsTransparency="True", therefore it has no title bar and supports transparency.
I want the user to be able to move the Window to any position on the screen by left-clicking anywhere within the Window and dragging. The Window should drag along with the mouse as long as the left mouse button is pressed down.
I was able to get this functionality to work with one exception: when the mouse moves outside of the Window (such as when the left mouse button was pressed down near the edge of the Window and the mouse is moved quicly), the Window no longer captures the mouse position and does not drag along with the mouse.
Here is the code from the code-behind that I use to get the job done:
public Point MouseDownPosition { get; set; }
public Point MousePosition { get; set; }
public bool MouseIsDown { get; set; }
private void window_MyWindowName_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MouseDownPosition = e.GetPosition(null);
MouseIsDown = true;
}
private void window_MyWindowName_MouseMove(object sender, MouseEventArgs e)
{
if (MouseIsDown)
{
MousePosition = e.GetPosition(null);
Left += MousePosition.X - MouseDownPosition.X;
Top += MousePosition.Y - MouseDownPosition.Y;
}
}
private void window_MyWindowName_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
MouseIsDown = false;
}
I think you are looking for this: Processing Global Mouse and Keyboard Hooks in C#
Url: Processing Global Mouse and Keyboard Hooks in C#
This class allows you to tap keyboard and mouse and/or to detect their activity even when an application runs in the background or does not have any user interface at all.
This class raises common .NET events with KeyEventArgs and MouseEventArgs, so you can easily retrieve any information you need.
There is an example and explain and demo to use.
Great tutorial!
Example:
UserActivityHook actHook;
void MainFormLoad(object sender, System.EventArgs e)
{
actHook= new UserActivityHook(); // crate an instance
// hang on events
actHook.OnMouseActivity+=new MouseEventHandler(MouseMoved);
actHook.KeyDown+=new KeyEventHandler(MyKeyDown);
actHook.KeyPress+=new KeyPressEventHandler(MyKeyPress);
actHook.KeyUp+=new KeyEventHandler(MyKeyUp);
}
Now, an example of how to process an event:
public void MouseMoved(object sender, MouseEventArgs e)
{
labelMousePosition.Text=String.Format("x={0} y={1}", e.X, e.Y);
if (e.Clicks>0) LogWrite("MouseButton - " + e.Button.ToString());
}
I believe you are reinventing the wheel. Search for "Window.DragMove".
Example:
private void title_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.DragMove();
}
Try it this way:
// method to convert from 'old' WinForms Point to 'new' WPF Point structure:
public System.Windows.Point ConvertToPoint(System.Drawing.Point p)
{
return new System.Windows.Point(p.X,p.Y);
}
// some locals you will need:
bool mid = false; // Mouse Is Down
int x=0, y=0;
// Mouse down event
private void MainForm_MouseDown(object sender, MouseButtonEventArgs e)
{
mid=true;
Point p = e.GetPosition(this);
x = (int)p.X;
y = (int)p.Y;
}
// Mouse move event
private void MainForm_MouseMove(object sender, MouseButtonEventArgs e)
{
if(mid)
{
int x1 = e.GetPosition(this).X;
int y1 = e.GetPosition(this).Y;
Left = x1-x;
Top = y1-y;
}
}
// Mouse up event
private void MainForm_MouseUp(object sender, MouseButtonEventArgs e)
{
mid = false;
}
I am writing a game. Player can choose items (such as weapon) and drag them to the form. Items are on the side, in PictureBox controls. I have set Form.AllowDrop to True. When I drag one of the items pictureBoxes, the pictureBox doesn't drop, neither even drag.
I want to drag a pictureBox on the form, or at least know the position in the form which the player want to drag it in.
EDIT: look at the logo above. When you click it and drag (without release) it drags.
In Winforms you need to change the cursor. Here's a complete example, start a new forms project and drop a picturebox on the form. Set its Image property to a small bitmap. Click and drag to drop copies of the image on the form.
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.AllowDrop = true;
this.pictureBox1.MouseDown += pictureBox1_MouseDown;
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
var dragImage = (Bitmap)pictureBox1.Image;
IntPtr icon = dragImage.GetHicon();
Cursor.Current = new Cursor(icon);
DoDragDrop(pictureBox1.Image, DragDropEffects.Copy);
DestroyIcon(icon);
}
}
protected override void OnGiveFeedback(GiveFeedbackEventArgs e) {
e.UseDefaultCursors = false;
}
protected override void OnDragEnter(DragEventArgs e) {
if (e.Data.GetDataPresent(typeof(Bitmap))) e.Effect = DragDropEffects.Copy;
}
protected override void OnDragDrop(DragEventArgs e) {
var bmp = (Bitmap)e.Data.GetData(typeof(Bitmap));
var pb = new PictureBox();
pb.Image = (Bitmap)e.Data.GetData(typeof(Bitmap));
pb.Size = pb.Image.Size;
pb.Location = this.PointToClient(new Point(e.X - pb.Width/2, e.Y - pb.Height/2));
this.Controls.Add(pb);
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
extern static bool DestroyIcon(IntPtr handle);
}
For the draggable items, you need to call the DoDragDrop method in the MouseDown event. Make sure your form (or target) has the AllowDrop property set to true.
For your target, you need to wire the dragging events:
private void Form1_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
private void Form1_DragDrop(object sender, DragEventArgs e)
{
// Examine e.Data.GetData stuff
}