private void MoveCursor()
{
// Set the Current cursor, move the cursor's Position,
// and set its clipping rectangle to the form.
this.Cursor = new Cursor(Cursor.Current.Handle);
Cursor.Position = new Point(Cursor.Position.X - 50, Cursor.Position.Y - 50);
Cursor.Clip = new Rectangle(this.Location, this.Size);
}
I am using the above code to Restrict the movement but still I am able to move the mouse outside the form?
Can I restrict the mouse movement to a specified area in the form? Please advise...
Updated answer:
ClipCursor is the API function you require. You will need to supply screen-based coordinates.
BOOL WINAPI ClipCursor(RECT *lpRect);
take a look at this link for the Win32 API code, and this one for pinvoke from C#.
There is pair of Win32 API functions called SetCapture/ReleaseCapture that will restrict the mouse to a certain window bounds.
You will need to use PInvoke to use them, but this will work.
[DllImport("user32.dll")]
static extern IntPtr SetCapture(long hWnd);
SetCapture(Control.Handle);
One thing to bear in mind, is that if used incorrectly, it's possible that the user will not be able to click the [X] to shut down your application because the mouse will not be able to get to the title bar.
Related
I have a Windows store app that draws an image under the system's cursor. I capture all the cursor movements using:
var window = Window.Current .Content;
window .AddHandler(PointerMovedEvent, new PointerEventHandler (window_PointerMoved), true);
And this is working fine if I use my mouse to move the cursor.
However, I have another application - a desktop application -, that changes the position of the system's cursor. I'm using this method to set the position of the cursor programatically:
[DllImport("user32")]
private static extern int SetCursorPos(int x, int y);
However, when the cursor is moved programatically, the PointerMovedEvent on the store app does not fire!
Does anyone know how I can solve this problem?
I thought I could not use System.Runtime .InteropServices on Windows store apps, but it is allowed. Therefore, I've managed to achieve the desired behavior by having a thread that actively checks the cursor's current position using:
[ DllImport("user32.dll" )]
private static extern bool GetCursorPos(ref Win32Point pt);
It's not the most elegant solution, but it works!
I need to make a small system tray app which monitors the cursor position systemwide and displays or hides the onscreen keyboard depending on the cursor handle ID. if the cursor is in a textbox (position equals IBeam) in IE,for example, the keyboard pops up.
I have code for the the system tray app (formless app) but cannot find a way of making it monitor the system. Any help with a function to monitor the system for cursor position would be welcome. thanks.
Monitor the system cursor position:
private void Pos()
{
for (; ; )
{
Thread.Sleep(10);
Point position = Cursor.Position;
//You can use these to pass to your system tray or whereever you need it.
somePublicXVar = position.X;
somePublicYVar = position.Y;
}
}
public void PointPosition()
{
Thread pointThread = new Thread(new ThreadStart(Pos));
pointThread.Start();
}
To be event-driven you'll need to use SetWindowsHookEx. You cannot do it directly through .NET, but must inject a DLL. Here is a MSDN article on making a mouse hook. This is done using System.Runtime.InteropServices to import user32.dll. The MSDN article gives step-by-step instructions on calling SetWindowsHookEx, CallNextHookEx, and UnhookWindowsHookEx from C#. CodeProject also has an article on making system-wide hooks in .NET.
In a UserControl I want to change the mouse cursor from the arrow, to a hand icon.
What I currently do is this:
this.Cursor = Cursors.Hand;
This is very nice, it gives me a mouse cursor looking like this:
But here comes my problem... this shows a hand with a pointing finger.
What I need is a "grabbing" hand, more like this one:
How do I do this?, How can I load an icon file (.ico), a cursor file (.cur), or image file (.png), and use it as the mouse cursor?
If you have a cursor file:
Cursor myCursor = new Cursor("myCursor.cur");
myControl.Cursor = myCursor;
otherwise you have to create one:
some more information about custom cursors
A caveat to using custom cursors with the WinForms Cursor class is that when using the stream, filename, and resource constructor overloads the supplied .cur file must be black and white in color.
Meaning that this will not work if the .cur files contains any colors besides black and white.
Cursor myCursor = new Cursor("myCursor.cur");
myControl.Cursor = myCursor;
There is a way around this limitation by using the Windows handle constructor overload:
Create the handle by using the Windows API:
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern IntPtr LoadCursorFromFile(string fileName);
Then pass it to the appropriate Cursor constructor like this:
IntPtr handle = LoadCursorFromFile("myCursor.cur");
Cursor myCursor = new Cursor(handle);
myControl.Cursor = myCursor;
I hope this prevents others from scratching their heads to an ArgumentException being thrown stating: Image format is not valid. The image file may be corrupted. when using the other Cursor constructor overloads with a .cur file that contains color.
Have you tried System.Windows.Forms.Cursor curs = new System.Windows.Forms.Cursor(file_name); ?
I tested this method. It's OK. This is my apply:
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern IntPtr LoadCursorFromFile(string fileName);
Cursor myCursor;
private void tsbtn_ZoomIn_Click(object sender, EventArgs e)
{
IntPtr handle = LoadCursorFromFile("view_zoom_in.cur");
myCursor = new Cursor(handle);
zg1.Cursor = myCursor;
}
Hi I have been using code similar to this in a piece of automation I have been working on
public static void LeftClick(int x, int y)
{
Cursor.Position = new System.Drawing.Point(x, y); //<= fails without this
mouse_event((int)(MouseEventFlags.LEFTDOWN), 0, 0, 0, 0);
mouse_event((int)(MouseEventFlags.LEFTUP), 0, 0, 0, 0);
}
However unless I am being dumb this move the mouse to the x,y from the top left of the screen which causes me problems if the active window isn't where Im expecting it to be, can anyone suggest a way of achieving the same functionality with moving the mouse to a point relative to the active window.
Thanks
You need to pinvoke GetWindowRect() to find out where the window is located. So you can adjust x and y by the window position. Visit pinvoke.net for the declarations.
Just subtract the location (relative to the screen) of the window you are targeting.
What you're seeing is indeed the expected behavior. The Cursor.Position property describes the cursor's location in screen coordinates, not relative to your form.
However, every control exposes two handy methods that you can take advantage of to convert between screen coordinates and control coordinates:
The Control.PointToClient method computes the location of the specified screen point into client coordinates. Use this to convert from screen coordinates into client coordinates (i.e., those relative to your control, such as a form).
The Control.PointToScreen method computes the location of the specified client point into scren coordinates. Use this to convert from client coordinates into screen coordinates.
try PointToClient and PointToScreen of the control you are trying to find relative points to.
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.