Disclosure: This is my first WPF app. Please be accepting of my ignorance.
In my WPF application, I have a ControlTemplate with a Grid and various children beneath that. In the code-behind, I am dynamically adding a custom ContentControl element using the ControlTemplate.
When the new Control is created, it is intended to capture the mouse and allow dragging capabilities. The code for the dragging calculations is fine if the Grid has already been loaded on the window and I have the start Point set to MouseButtonEventArgs.GetPosition(window). But when the event is fired when the Grid is initially loaded, the Point is equal to the inverse position of the window. E.g. if my window is at (350,250), my start Point is (-350,-250).
private void GridLoaded(object sender, EventArgs e) { // fires MouseLeftButtonDown event for grid}
private void MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
...
m_start = e.GetPosition(this); // 'this' is the current window; returns the inverse coordinates of 'this'
...
}
Is there a more appropriate method to get the x,y coordinates of my mouse position. I could work with screen coordinates if necessary, but all code I've found uses what would be PointToScreen(m_start). This is useless as m_start is incorrect.
Any help is greatly appreciated.
Can you try, I snagged this some time ago and it worked well for me:
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
public static implicit operator Point(POINT point)
{
return new Point(point.X, point.Y);
}
}
[DllImport("user32.dll")]
public static extern bool GetCursorPos(out POINT lpPoint);
public static Point GetCursorPosition()
{
POINT lpPoint;
GetCursorPos(out lpPoint);
//bool success = User32.GetCursorPos(out lpPoint);
// if (!success)
return lpPoint;
}
Related
public MainWindow()
{
InitializeComponent();
_hook = Hook.GlobalEvents();
_hook.MouseMove += DrawMouseMove;
}
private void DrawMouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
Point GetMousePos() => Mouse.GetPosition(DrawCanvas);
Point pos = GetMousePos();
CoordinateLabel.Content = $"{Math.Ceiling(pos.X)}, {Math.Ceiling(pos.Y)}px";
//... code down here is draw a shape with pos, a relative position to DrawCanvas
}
I'm using hook for global event, but i stuck at getting relative position to DrawCanvas when the mouse is outside of my application window. The thing I want to achive is just like mspaint, you can still draw shape even when the mouse moved out of the window
I'm using .Net c# winforms. I want to move my mouse over another application and see the cusor X,Y position as I move the mouse over it's interface. Displaying the X,Y on my forms title bar is ok. I want to see the X,Y location for a specific spot on this app's form.
The reason I want to do this is because there are controls on this app's interface that I can mouse click on to turn a knob, one mouse click per knob turn. I want to write an app that I can position the mouse cursor to that specific X,Y position on this app form and then do a software mouse click to turn that same knob one turn. But I want to do this from my app, kind of like remote control I guess you could say. The other app knobs responds to mouse clicks when you are over the correct X,Y location.
Thanks for any pointers in the right direction.
Add a Label to your Form and wire up its MouseMove() and QueryContinueDrag() events. Use the WindowFromPoint() and GetAncestor() APIs to get a handle to the main window containing the cursor position, then use the ScreenToClient() API to convert the screen coordinate to the client coordinate of that Form. Run the app and left drag the Label in your Form over to the knobs in your target application. The title bar should update with the client coords of the current mouse position relative to the app it is over:
private const uint GA_ROOT = 2;
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern IntPtr WindowFromPoint(int xPoint, int yPoint);
[System.Runtime.InteropServices.DllImport("user32.dll", ExactSpelling = true)]
private static extern IntPtr GetAncestor(IntPtr hwnd, uint gaFlags);
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint);
private void label1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
label1.DoDragDrop(label1, DragDropEffects.Copy);
}
}
private void label1_QueryContinueDrag(object sender, QueryContinueDragEventArgs e)
{
Point pt = Cursor.Position;
IntPtr wnd = WindowFromPoint(pt.X, pt.Y);
IntPtr mainWnd = GetAncestor(wnd, GA_ROOT);
POINT PT;
PT.X = pt.X;
PT.Y = pt.Y;
ScreenToClient(mainWnd, ref PT);
this.Text = String.Format("({0}, {1})", PT.X.ToString(), PT.Y.ToString());
}
It works within a specific control, but it doesn't work out the specific control.
How to get mouse position and use mouse events independently of any control just directly from screen (without Platform Invoke)?
2 needed points:
Mouse events when mouse is not within a control, but on a screen.
Mouse position when mouse is not within a control, but on a screen.
It should be solved without using Platform Invoke.
Next two don't work:
System.Windows.Input.Mouse.GetPosition(this)
Doesn't get mouse position out a specific control.
System.Windows.Forms.Cursor.Position.X
System.Windows.Forms.Cursor.Position doesn't work because it has no types in a WPF app, but it works in a Windows Forms app.
IntelliSense gets System.Windows.Forms.Cursor.Position, but it doesn't get any type of Position, hence I can't get:
Position.X
Position.Y
and
Point pointToWindow = Mouse.GetPosition(this);
Point pointToScreen = PointToScreen(pointToWindow);
Doesn't get mouse position out a specific control.
Using MouseDown event of a control you can try this:
var point = e.GetPosition(this.YourControl);
EDIT:
You can capture mouse event to a specific control using Mouse.Capture(YourControl); so it will capture the mouse events even if it is not on that control. Here is the link
You can use PointToScreen
Converts a Point that represents the current coordinate system of the
Visual into a Point in screen coordinates.
Something like this:
private void MouseCordinateMethod(object sender, MouseEventArgs e)
{
var relativePosition = e.GetPosition(this);
var point= PointToScreen(relativePosition);
_x.HorizontalOffset = point.X;
_x.VerticalOffset = point.Y;
}
Do note that Mouse.GetPosition returns a Point, and PointToScreen converts the point to the screen coordinate
EDIT:
You can use the Mouse.Capture(SepcificControl);. From MSDN
Captures mouse input to the specified element.
I have little new found,
Code is below, fisrt build and run the Window ,
then just wheel your mouse one time on the window to invoke the endless screen detect of the Mouse Position.
(Thus I didn't find the way to detect mouse event out of the control in the second point of the question, but similar use an endless thread.)
But I just use a little skill to enable Windows.Forms in WPF Project, by simply use the Forms code in pure method, then refer that method in the Event Code Block.
.
Here's the Code:
Add two references to project:
System.Drawing
System.Windows.Forms
Xaml part:
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:g="clr-namespace:Gma.UserActivityMonitor;assembly=Gma.UserActivityMonitor"
Title="MainWindow" Height="350" Width="525"
MouseWheel="MainWindow_OnMouseWheel">
<Grid>
<TextBlock Name="TBK" />
</Grid>
</Window>
Class Code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public void KeepReportMousePos()
{
//Endless Report Mouse position
Task.Factory.StartNew(() =>
{
while(true){
this.Dispatcher.Invoke(
DispatcherPriority.SystemIdle,
new Action(() =>
{
GetCursorPos();
}));
}
});
}
public void GetCursorPos()
{
//get the mouse position and show on the TextBlock
System.Drawing.Point p = System.Windows.Forms.Cursor.Position;
TBK.Text = p.X + " " + p.Y;
}
private void MainWindow_OnMouseWheel(object sender, MouseWheelEventArgs e)
{
//invoke mouse position detect when wheel the mouse
KeepReportMousePos();
}
}
Why complicate things? Just pass null to get screen coordinates:
private void MouseCordinateMethod(object sender, MouseEventArgs e)
{
var screenPos = e.GetPosition(null);
// ...
}
this question is about a tooltip that you can implement very easy in order
to track mouse location via it's coordinates
the only problem for me is to add the ability to track the coordinates on a specific
window after setting it to foreground ... and it's not a form , but a 3rd party
application .
the code which works for me on the visual studio windows form is
ToolTip trackTip;
private void TrackCoordinates()
{
trackTip = new ToolTip();
this.MouseMove += new MouseEventHandler(Form1_MouseMove);
}
void Form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
String tipText = String.Format("({0}, {1})", e.X, e.Y);
trackTip.Show(tipText, this, e.Location);
}
//thats a code i have seen somewhere on the web and then again after some more googling
found the msdn source at the url :
msdn source url
so the question remains if you'll be kind to answer :
how do i get tool tip coordinates of a 3rd party (other than Vs winform window)
subsclass the target window and listen for WM_MOUSEMOVE messages.
Or
Use a timer and grab the mouse screen coordinates.
You need to use one of the following (as it is explained in this question):
1.Using Windows Forms. Add a reference to System.Windows.Forms
public static Point GetMousePositionWindowsForms()
{
System.Drawing.Point point = Control.MousePosition;
return new Point(point.X, point.Y);
}
2.Using Win32
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetCursorPos(ref Win32Point pt);
[StructLayout(LayoutKind.Sequential)]
internal struct Win32Point
{
public Int32 X;
public Int32 Y;
};
public static Point GetMousePosition()
{
Win32Point w32Mouse = new Win32Point();
GetCursorPos(ref w32Mouse);
return new Point(w32Mouse.X, w32Mouse.Y);
}
I have this Windows Forms application with a simple balloon tooltip. Depending on the application's window location on the desktop and the mouse cursor location, the balloon 'tip' (or balloon pointing arrow) may or may not be pointing to the location I want.
For instance, my app snaps to the desktop sides and when it's snapped to the right side, if the mouse cursor is below 100px of the right side, the balloon 'tip' will point to the wrong place. But if the mouse cursor is anywhere else, it will point to the right place.
In this situation I wanted to fake the mouse cursor position (without actually changing the mouse cursor position) to be somewhere else so the the problem wouldn't occur.
Is this possible? How can I achieve this?
private void noteTitleInput_KeyPress(object sender, KeyPressEventArgs e) {
if(e.KeyChar == Convert.ToChar(Keys.Return, CultureInfo.InvariantCulture) && noteTitleInput.Text.Length > 0) {
e.Handled = true;
noteInputButton_Click(null, null);
} else if(!Char.IsControl(e.KeyChar)) {
if(Array.IndexOf(Path.GetInvalidFileNameChars(), e.KeyChar) > -1) {
e.Handled = true;
System.Media.SystemSounds.Beep.Play();
noteTitleToolTip.Show("The following characters are not valid:\n\\ / : * ? < > |",
groupNoteInput, 25, -75, 2500);
return;
}
}
noteTitleToolTip.Hide(groupNoteInput);
}
I'm not quite sure why do you need to set cursor position, because you can set tool tip to appear where you tell it, and not necessarily where the mouse is.
For example:
tooltip1.Show("My tip", controlOnWhichToShow, 15, 15);
would display the tip at upper left corner of the controlOnWhichToShow, 15 points away from edges.
If I misunderstood you, than please specify at which point in time is the mouse position being used.
If you sync the MouseHover event, you can create the Tooltip as veljkoz describes. In this way you can place the tooltip as you like. The code would look smething like this:
protected override void OnMouseHover(EventArgs e)
{
ToolTip myToolTip = new ToolTip();
myToolTip.IsBalloon = true;
// TODO The x and y coordinates should be what ever you wish.
myToolTip.Show("Helpful Text Also", this, 50, 50);
base.OnMouseHover(e);
}
Hope that helps.
In Windows Forms the mouse is captured by the control when the user presses a mouse button on a control, and the mouse is released by the control when the user releases the mouse button.
The Capture property of the Control class specifies whether a control has captured the mouse. To determine when a control loses mouse capture, handle the MouseCaptureChanged event.
Only the foreground window can capture the mouse. When a background window attempts to capture the mouse, the window receives messages only for mouse events that occur when the mouse pointer is within the visible portion of the window. Also, even if the foreground window has captured the mouse, the user can still click another window, bringing it to the foreground. When the mouse is captured, shortcut keys do not work.
More here. Mouse Capture in Windows Forms
You can do what you say with a Class. You can do it in a very simple way.
one create class and
namespace MousLokasyonbulma
{
class benimtooltip : ToolTip
{
[System.Runtime.InteropServices.DllImport("User32.dll")]
static extern bool MoveWindow(IntPtr h, int x, int y, int width, int height, bool redraw);
public benimtooltip()
{
this.OwnerDraw = true;
this.Draw += Benimtooltip_Draw;
}
private void Benimtooltip_Draw(object sender, DrawToolTipEventArgs e)
{
e.DrawBackground();
e.DrawBorder();
e.DrawText();
var t = (ToolTip)sender;
var h = t.GetType().GetProperty("Handle",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
var handle = (IntPtr)h.GetValue(t);
var location = new Point(650, 650);
var ss= MoveWindow(handle, location.X, location.Y, e.Bounds.Width, e.Bounds.Height, false);
}
}
}
full Code MyGithup
Example Project image
https://i.hizliresim.com/1pndZG.png
https://i.hizliresim.com/Lvo3Rb.png