How to get coordinates of a Mouse when it's Clicked - c#

I'm beginner in c# and need some help. After loading Form I want to display on Form coordinates of a Mouse when it's Clicked. Click can be made outside of the Form. For example in Browser. Can someone help me with this.

Maybe the most simple way is setting Capture property of a form to true, then handle click event and convert the position (that is position related to top left point of form) to screen position using PointToScreen method of form.
For example you can put a button on form and do:
private void button1_Click(object sender, EventArgs e)
{
//Key Point to handle mouse events outside the form
this.Capture = true;
}
private void MouseCaptureForm_MouseDown(object sender, MouseEventArgs e)
{
this.Activate();
MessageBox.Show(this.PointToScreen(new Point(e.X, e.Y)).ToString());
//Cursor.Position works too as RexGrammer stated in his answer
//MessageBox.Show(this.PointToScreen(Cursor.Position).ToString());
//if you want form continue getting capture, Set this.Capture = true again here
//this.Capture = true;
//but all clicks are handled by form now
//and even for closing application you should
//right click on task-bar icon and choose close.
}
But more correct (and slightly difficult) way is using global hooks.
If you really need to do it, you can take a look at this links:
Processing Global Mouse and Keyboard Hooks in C#
Low-Level Mouse Hook in C#
Application and Global Mouse and Keyboard Hooks .Net Libary in C#

I think you can't handle the mouse click outside your Form at least easily.
inside the form using MouseEventArgs it can simply be handled.
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
// e.Location.X & e.Location.Y
}
Learn more about this topic at Mouse Events in Windows Forms.
I hope it helps.

Cursor.Position and Control.MousePosition both return the position of the mouse cursor in screen coordinates.
The following articles deal with capturing Global mouse click events:
Processing Global Mouse and Keyboard Hooks in C#
Global Windows Hooks

You need a global mouse hook.
See this question

Related

Moving Borderless Forms

I need your help with some code I found on the web a long time ago. Sadly I don't remember from where it is :( To move the borderless forms in my project I use this code snipped:
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
this.Capture = false;
Message msg = Message.Create(this.Handle, 0XA1, new IntPtr(2), IntPtr.Zero);
this.WndProc(ref msg);
}
}
My problem is that I don't completely understand how the code works. As far as I understand the event gets activated when a mouse button is clicked on the forms. Then follows the query, if the mouse click is a left click. And from there I don't know what the following code does :(
The this.Capture=false tells the OS to stop capturing mouse events. The Message.Create creates a new message to be send to the message loop of the current application. 0xA1 is WM_NCLBUTTONDOWN; which is a non-client left-button down message. Meaning it simulated clicking the left mouse button on the missing border.
Windows then picks up the rest of the process.
At a basic level, you are sending a message to your window and having it handle it.
You are giving it a 0xA1 (WM_NCLBUTTONDOWN) and by sending a 0x02 as the parameter (HTCAPTION) you fool the process into thinking you are on the caption bar. Drags on a caption bar move the window around, hence you can drag the window by using your code.
Samples of doing this at:
C#: How to drag a from by the form and it's controls?
http://www.catch22.net/tuts/win32-tips-tricks
You're basically posting a message to the window. A little MSDN research uncovers that the message you're posting is WM_NCLBUTTONDOWN. Basically, you're telling the underlying window that the left mouse button is being held down and it needs to respond to that. That response typically happens to be dragging the window about.

Object stops tracking mouse position when hovering over other objects C#

I have a program which uses the mouse's .X position (relative to the form boundaries) to change the .Left value of a button Object.
The problem is that I have this button over the top of other objects like Picture Boxes, Buttons, TrackBar's etc. and when I hove over these other elements, the button stops tracking the mouse's .X position.
How can I make the button track the mouse movement regardless of the mouse doing other stuff on the form too? (I also need to interact with the other elements at the same time too).
My Code:
/* i create the mousemove tracking event */
this.MouseMove += new MouseEventHandler(btnBat1_MouseMove);
/* and use it by making a new method */
public void btnBat1_MouseMove(Object sender, MouseEventArgs e)
{
// I use the variable mouseXCo to change the button1.Left value.
mouseXCo = e.X;
}
Thanks in advance guys :-)

When exactly is the MouseLeave event triggered?

According to this MSDN Article : "The MouseLeave event is raised in response to a touch event occurring outside the object's bounding area.". But in implementation am finding it being triggered while releasing a tap on the object's bounding area (precisely like OnMouseLeave).
So how do I get it to fire while tapping outside the UI Object's boundary?
I am new to C# and StackOverflow, but I thought I might contribute what I found. I did a quick Google search of "" and found this article about detecting clicks outside of a GUI.
Here is a quick method/description (found in link) which detects the clicks outside of a rectangle drawn over the GUI. "When you use a GUI window or group / area, you can use its Rect to check if the mouse is inside."
Rect windowPos = new Rect(10,10,200,150);
void OnGUI()
{
Event e = Event.current;
windowPos = GUI.Window(0, windowPos, drawWindow, "MyWindow");
if (e.type == EventType.MouseDown && !windowPos.Contains(e.mousePosition))
{
// Click was outside of the GUI window
}
}
void drawWindow(int aID)
{
// draw the window content
}
Just go read on that page. It seemed to answer their question before.
Good luck!

Is it possible to catch Win7 multitouch events, convert them to mouse and keyboard events and send them to another application?

I have following Situation: I have a special 3D program which I need to make able to react on multi-touch events without changing the program itself. Therefore I need a mapper program, which receives the multi-touch events of Windows 7, converts them in corresponding mouse and keyboard events and send this emulated events to the 3D program, so that it can process those events.
I have already read and tried a lot and my current approach is to have an almost transparent overlay window over the 3D programm to catch multi-touch events. But this is also the problem, I'm unable to manage to forward the generated mouse events to the underlying 3D programm in a usable way. Right now I used pinvoke functions like mouse_event, SendMessage and so on, but none of them worked for me. Since I always had to bring the 3D program to front, send the event and afterwards I needed to put my mapper programm to front again. This works quite crappy.
So my question is more or less, is there a nice working approach to do the things I mentioned above? Or at least a nice way to send mouse and keyboard events to processes in the background?
Hope anyone could give me a hint or suggestion....
Here are the way I simulate mouse clicks right now:
private void OnMouseDown(object sender, MouseEventArgs e)
{
Point position = this.PointToScreen(new Point(e.Location.X, e.Location.Y));
//Simulate the mouse event on the given position
this.Visible = false;
Cursor.Position = position;
mouse_event(Convert.ToUInt16(MouseEventFlags.LEFTDOWN), 0, 0, 0, 0);
}
private void OnMouseUp(object sender, MouseEventArgs e)
{
Point position = this.PointToScreen(new Point(e.Location.X, e.Location.Y));
//Simulate the mouse event on the given position
Cursor.Position = e.Location;
mouse_event(Convert.ToUInt16(MouseEventFlags.LEFTUP), 0, 0, 0, 0);
this.Visible = true;
}
//Get a handle to the mouse event manager
[DllImport("user32.dll")]
private static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, int dwExtraInfo);
maybe have a look at InfoStrat.VE - Bing Maps 3D for WPF and Microsoft Surface.
They made the Bind maps control usable for touch.
Maybe that helps.
There isn't a way to direct mouse/keyboard events to a particular process in Win32. That being said, however, you might be able to get this approach to work:
Register your mapper window as a touch window to get touch events.
Add a handler for WM_NCHITTEST in your message loop, call DefWindowProc() to get the default handler, and then convert any HTCLIENT returns to HTTRANSPARENT. This will cause Windows to pass any mouse events through your window, onto the underlying window.
This probably won't work if your mapper window lives in a separate process from your client program; if that's the case, you'll have to do some hacking with AttachThreadInput. I don't recommend this, incidentally, as merged thread queues are very prone to bugs.

WPF drag distance threshold

I have a program with two WPF treeviews that allow dragging and dropping between the two. The problem is, it can be annoying to open / close items on the treeviews because moving the mouse just one pixel while holding the left mouse button triggers the drag / drop functionality. Is there some way to specify how far the mouse should move before it's considered a drag / drop?
There's a system parameter for this. If you have
Point down = {where mouse down event happened}
Point current = {position in the MouseMove eventargs}
then the mouse has moved the minimum drag distance if
Math.Abs(current.X - down.X) >= SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(current.Y - down.Y) >= SystemParameters.MinimumVerticalDragDistance
Just build a little buffer into your code that determines when the drag starts.
flag mouse down
on mouse move - check for mouse down.. if yes, check to see if its moved farther than whatever buffer you specify (3 pixels is probably good)
if it has, start the drag.
Following this article for Drag and Drop implementation, you would have to handle 2 mouse events in order to delay the dragging until the mouse has moved a certain distance. First, add a handler for PreviewMouseDown which stores the initial mouse position relative to your control. Don't use the MouseDown event because it is a bubbling event and may have been handled by a child control before reaching your control.
public class DraggableControl : UserControl
{
private Point? _initialMousePosition;
public DraggableControl()
{
PreviewMouseDown += OnPreviewMouseDown;
}
private void OnPreviewMouseDown(object sender, MouseButtonEventArgs e) {
_initialMousePosition = e.GetPosition(this);
}
Additionally, handle MouseMove to check the moved distance and eventually initiate the drag operation:
...
public DraggableControl()
{
...
MouseMove += OnMouseMove;
}
...
private void OnMouseMove(object sender, MouseEventArgs e)
{
// Calculate distance between inital and updated mouse position
var movedDistance = (_initialMousePosition - e.GetPosition(this)).Length;
if (movedDistance > yourThreshold)
{
DragDrop.DoDragDrop(...);
}
}
}

Categories