so I have this Window Application that simulates mouse movement, I made a few tests and managed to "record" mouse movement and play it once recorded. Now I wanna make a Viewlist with 2 columns ("X" and "Y) containing the coords of the route I want my mouse to follow. Coordinates can be added throught "ycoord" and "xcoord" textlabels and can be added with "button1" button to the viewlist. There's also a "button2" that works as a "toggle" button to turn it on and off. So, I want is that, every time I press left click form mouse (LButton) the movement runs as long as I hold this button, and, if I hold it again it starts over again. I already managed the textlabels to place content into the viewlist, but I don't know how to read the viewlist and convert them into mouse movement coords.
Thanks in advance for the help!
You have to save the X,Y coords in a List, so you can create a list of points, then you have to iterate it and use it with:
Look at the object Cursor here
Also you have the code:
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);
}
Try this:
public partial class Form1 : Form
{
private List<Point> _points = null;
public Form1()
{
InitializeComponent();
_points = new List<Point>();
this.MouseMove += Form1_MouseMove;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
//Save the point
_points.Add(new Point(e.X, e.Y));
}
private void PerformRecord()
{
foreach (var point in _points)
{
this.Cursor = new Cursor(Cursor.Current.Handle);
Cursor.Position = new Point(point.X, point.Y);
}
}
private void button1_Click(object sender, EventArgs e)
{
PerformRecord();
}
}
Related
I'm developing a basic GUI Windows Form Application. It allows the user to change colors using sliding bars, change the size of shapes using scroll bars, and click a check box to determine if the shape should be filled, clear the screen if the clear button is clicked, and switch between shapes with buttons. I'm currently using the MouseMove event to cause the shape to follow the mouse around inside of the panel. I also have an event for a MouseClick. When there is a mouseclick, I want it to "place" that shape so that the graphic persists. I've been able to move a single shape to where the user clicks and make it follow the mouse, I just don't know how to combine both.
This is what I have so far:
void DrawShape()
{
//g.Clear(Color.White);
p.Color = Color.FromArgb(r, gr, b);
if (IsChecked) // If checkbox is checked for fill
{
if (IsRect)
{
g.FillRectangle(myBrush, left, top, wid, ht); // Filled Rectangle
}
else if (IsEllipse)
{
g.FillEllipse(myBrush, left, top, wid, ht); // Filled Ellipse
}
}
else // not filled
{
if (IsRect)
{
g.DrawRectangle(p, left, top, wid, ht); // empty rectangle
}
else if (IsEllipse)// empty ellipse
{
g.DrawEllipse(p, left, top, wid, ht);
}
}
}
private void panel1_MouseMove(object sender, MouseEventArgs e) // when mouse moves
{
left = e.X;
top = e.Y;
DrawShape();
}
private void panel1_MouseClick(object sender, MouseEventArgs e) //when mouse clicks
{
left = e.X;
top = e.Y;
IsClick = true;
DrawShape();
IsClick = false;
}
the user should be able to draw a straight line on a panel similar to drawing a straight line in paint .
the user clicks on the panel and when he moves the mouse the line should also move along with the mouse (i.e similar to drawing a staright line in paint) and when the user releases the mouse the line should have been drawn from the original point of click to this release point .
i.e not a free hand line.
is there any animation for this ?
How about this? :
public class LinePanel : Panel
{
public LinePanel()
{
this.MouseDown += (src, e) => { LineStartPos = LineEndPos = e.Location; Capture = true; Invalidate(); };
this.MouseMove += (src, e) => { if (Capture) { LineEndPos = e.Location; Invalidate(); } };
this.MouseUp += (src, e) => { if (Capture) { LineEndPos = e.Location; } Capture = false; Invalidate(); };
}
private Point LineStartPos, LineEndPos;
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (LineStartPos != LineEndPos)
e.Graphics.DrawLine(new Pen(Color.Black, 2), LineStartPos, LineEndPos);
}
}
To test you can just add a new LinePanel() to the Controls collection of your form, and set location/size or anchor / dock paramaters to size it.
I have an X-Y plot in a .NET 4.0 WinForms chart control. I am trying to implement rubber-band selection, so that the user could click and drag the mouse to create a rectangle on the plot, thus selecting all the points that lie within this rectangle.
While I was able to code up the drawing of the rectangle, I am now trying to identify the Datapoints that lie within this rectangle. Here is the relevant code:
public partial class Form1 : Form
{
System.Drawing.Point _fromPosition;
Rectangle _selectionRectangle;
public Form1()
{
InitializeComponent();
}
private void chart1_MouseMove(object sender, MouseEventArgs e)
{
// As the mouse moves, update the dimensions of the rectangle
if (e.Button == MouseButtons.Left)
{
Point p = e.Location;
int x = Math.Min(_fromPosition.X, p.X);
int y = Math.Min(_fromPosition.Y, p.Y);
int w = Math.Abs(p.X - _fromPosition.X);
int h = Math.Abs(p.Y - _fromPosition.Y);
_selectionRectangle = new Rectangle(x, y, w, h);
// Reset Data Point Attributes
foreach (DataPoint point in chart1.Series[0].Points)
{
point.BackSecondaryColor = Color.Black;
point.BackHatchStyle = ChartHatchStyle.None;
point.BorderWidth = 1;
}
this.Invalidate();
}
}
private void chart1_MouseDown(object sender, MouseEventArgs e)
{
// This is the starting position of the rectangle
_fromPosition = e.Location;
}
private void chart1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawRectangle(new Pen(Color.Blue, 2), _selectionRectangle);
foreach (DataPoint point in chart1.Series[0].Points)
{
// Check if the data point lies within the rectangle
if (_selectionRectangle.Contains(???))))
{
// How do I convert DataPoint into Point?
}
}
}
}
What I am trying to do is query each DataPoint in the series and check if it lies within the Rectangle. Here, I am unable to transform each DataPoint into its corresponding Point. It seems pretty straightforward, so I am either missing something basic here or approaching the problem incorrectly.
I should also add that I referred to similar questions here and here, but they do not talk about how to actually identify DataPoints within the rectangle.
Any direction would be appreciated!
I have shown how to cheat the Chart into helping to get at the coordinates of DataPoints in the Paint event here.
But as you want to pick them up in the Paint event anyway, no cheating is needed..:
I define a List to collect the lassoed DataPoints:
List<DataPoint> dataPoints = new List<DataPoint>();
And I clear it on each new selection:
void chart1_MouseDown(object sender, MouseEventArgs e)
{
_fromPosition = e.Location;
dataPoints.Clear();
}
At the end I can write out the results:
void chart1_MouseUp(object sender, MouseEventArgs e)
{
foreach(DataPoint pt in dataPoints)
Console.WriteLine("found:" + pt.ToString() +
" at " + chart1.Series[0].Points.IndexOf(pt));
}
And in the Paint event we make use of the ValueToPixelPosition method of the two axes:
void chart1_Paint(object sender, PaintEventArgs e)
{
using (Pen pen = new Pen(Color.Blue, 2) // dispose of my Pen
{DashStyle = System.Drawing.Drawing2D.DashStyle.Dot})
e.Graphics.DrawRectangle(pen, _selectionRectangle);
foreach (DataPoint point in chart1.Series[0].Points)
{ // !! officially these functions are only reliable in a paint event!!
double x = chart1.ChartAreas[0].AxisX.ValueToPixelPosition(point.XValue);
double y = chart1.ChartAreas[0].AxisY.ValueToPixelPosition(point.YValues[0]);
PointF pt = new PointF((float)x,(float)y);
// Check if the data point lies within the rectangle
if (_selectionRectangle.Contains(Point.Round(pt)))
{
if (!dataPoints.Contains(point)) dataPoints.Add(point);
}
}
}
In For1 i have this code:
private void timer1_Tick(object sender, EventArgs e)
{
try
{
this.pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox1.Load(file_array_satellite[file_indxs_satellite]);
file_indxs_satellite = file_indxs_satellite - 1;
if (file_indxs_satellite < 0)
{
file_indxs_satellite = file_array_satellite.Length - 1;
}
}
catch
{
timer1.Enabled = false;
}
}
private void satellitesToolStripMenuItem_Click(object sender, EventArgs e)
{
file_array_satellite = Directory.GetFiles(UrlsPath, "RainImage*.*");
if (file_array_satellite.Length > 0)
{
DateTime[] creationTimes8 = new DateTime[file_array_satellite.Length];
for (int i = 0; i < file_array_satellite.Length; i++)
creationTimes8[i] = new FileInfo(file_array_satellite[i]).CreationTime;
Array.Sort(creationTimes8, file_array_satellite);
file_indxs_satellite = 0;
file_indxs_satellite = file_array_satellite.Length - 1;
timer1.Enabled = true;
}
}
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
this.pictureBox1.Size = new Size(500, 500);
pictureBox1.Location = new Point(this.Bounds.Width / 2,
this.Bounds.Height / 2);
this.pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox1.BringToFront();
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
this.pictureBox1.Size = new Size(100, 100);
pictureBox1.Location = new Point(12,
27);
}
In the original the picturebox1 size is 100x100 and each image i stretch to fit in the pictureBox.
When it's 100x100 everything is ok i see the animation of each image in the pictureBox.
Now i did an event that when i enter with the mouse to the pictureBox area it should move to the center of the form resize to 500x500 stretch the images and show the same animation.
And when i leave the pictureBox area it should return to it's original size and location.
When i enter with the mouse to the pictureBox1 area the pictureBox just vanish i don't see it anywhere once i leave the pictureBox area i see it 100x100 in it's original place and size.
Why when i enter with the mouse to the pictureBox1 area it's vanish i don't see it in the center of the form on size 500x500 ?
file_array_satellite is string[] and file_indxs_satellite is int.
RainImage*.* are the files names on the hard disk after downloaded them.
The idea is not to convert/change the files sizes on the hard disk each time i enter or leave so i wanted that once i enter the pictureBox1 area it will stretch the current image in the pictureBox and show it . It's working when it's 100x100 but not on 500x500.
When you mouse over the PictureBox and move it to the center of the form, you are moving it out from under the mouse cursor. This causes the MouseLeave event to immediately trigger, which places it back under your mouse cursor again, which causes the MouseEnter event to trigger again, etc.
You can do something like this:
bool suppressMouseLeave;
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
suppressMouseLeave = true;
this.pictureBox1.Size = new Size(500, 500);
pictureBox1.Location = new Point(this.Bounds.Width / 2,
this.Bounds.Height / 2);
this.pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox1.BringToFront();
//point the cursor to the new Position so that it's still kept on the pictureBox1
//This is important because it makes your idea acceptable.
//Otherwise you have to move your mouse onto your pictureBox and leave the
//mouse from it then to restore the pictureBox
Cursor.Position = PointToScreen(new Point(pictureBox1.Left + 250, pictureBox1.Top + 250));
suppressMouseLeave = false;
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
if(suppressMouseLeave) return;
this.pictureBox1.Size = new Size(100, 100);
pictureBox1.Location = new Point(12, 27);
}
I would venture a guess that this.Bounds.Width and this.Bounds.Height are not what you expect them to be, so the PictureBox isn't vanishing, you are just setting it to some location that is offscreen/off your form. Run Visual Studio in Debug mode and put a breakpoint around that line and see what this.Bounds is equal to. This may give you a clue as to the proper location you need to set.
How about in "in place" zoom like this?
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
Rectangle rc = pictureBox1.Bounds;
rc.Inflate(200, 200);
pictureBox1.Bounds = rc;
pictureBox1.BringToFront();
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
Rectangle rc = pictureBox1.Bounds;
rc.Inflate(-200, -200);
pictureBox1.Bounds = rc;
}
I want to click inside a square and then an "X" should appear, but I'm not sure what to put inside the Form1_MouseDown, Form1_Paint and Form1_MouseUp events. How can I implement this is C#?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace VTest
{
public partial class Form1 : Form
{
Rectangle rect; // single rect
int sqsize, n;
int margin;
public Form1()
{
n = 3;
margin = 25;
sqsize = 50;
rect = new Rectangle(10, 10, 150, 150);
InitializeComponent();
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
// what goes here?
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
// what goes here?
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
// what goes here?
}
// ...
In your MouseDown event, determining whether the click has occurred within your rectangle is easy:
if (rect.Contains(e.Location))
{
// the user has clicked inside your rectangle
}
Drawing the "X" on the form is also easy:
Graphics g = this.CreateGraphics();
g.DrawString("X", this.Font, SystemBrushes.WindowText,
(float)e.X, (float)e.Y);
However, the "X" in this case will not be persistent, meaning that if you drag another form over your form and then move it away, the "X" will not be there anymore. To draw a persistent "X", create a form-level Point variable like this:
private Point? _Xlocation = null;
Use your MouseDown event to set this variable if the user clicks in your Rectangle:
if (rect.Contains(e.Location))
{
_Xlocation = e.Location;
this.Invalidate(); // this will fire the Paint event
}
Then, in your form's Paint event, draw the "X":
if (_Xlocation != null)
{
e.Graphics.DrawString("X", this.Font, SystemBrushes.WindowText,
(float)e.X, (float)e.Y);
}
else
{
e.Graphics.Clear(this.BackColor);
}
If you want the "X" to then disappear when the user lets go of the mouse button, just put this code in the MouseUp event:
_Xlocation = null;
this.Invalidate();
You can make this as much more complicated as you like. With this code, the "X" will be drawn just below and to the right of wherever you click on the form. If you want the "X" to be centered on the click location, you can use the Graphics object's MeasureString method to determine how high and how wide the "X" will be, and offset the DrawString location accordingly.
You don't need both a mousedown and mouseup event handler.
Pick one to react to, I tend to react to the MouseDown event instead.
But, when you will want to look at the MouseEventArgs properties and you should be able to determine if you are inside the square.
You will probably want to call:
System.Diagnostics.Debug.WriteLine(...)
using the x and y properties in MouseEventArgs, so you can see where the mouse clicks are, and determine when you are in the square.
Once you are there, then you can draw the X.
You may want to write a function to draw an X and test it by having it draw an X at 300,300 so that you can ensure it looks as you want, while you are experimenting with MouseDown.
Update: I like the Rectangle.contains(location) method demonstrated by MusiGenesis.
public partial class formDemo : Form
{
Rectangle rec;
public formDemo() => InitializeComponent();
private void formDemo_Load(object sender, EventArgs e) =>
rec = new Rectangle(150,100,100,100);
private void frmDemo_Paint(object sender, PaintEventArgs e)
{
var p = new Pen(Color.Blue);
var g = e.Graphics;
g.DrawRectangle(p, rec);
}
private void formDemo_MouseMove(object sender, MouseEventArgs e) =>
Cursor = rec.Contains(e.Location) ? Cursors.Cross : Cursors.Default;
private void formDemo_MouseDown(object sender, MouseEventArgs e)
{
if (rec.Contains(e.Location))
{
// Mouse position adjust for window postion and border size.
// You may have to adjust the borders depending your
// Windows theme
int x = MousePosition.X - this.Left - 4;
int y = MousePosition.Y - this.Top - 29;
var g = this.CreateGraphics();
var p = new Pen(Color.Black);
var p1 = new Point(x - 10, y - 10);
var p2 = new Point(x + 10, y + 10);
var p3 = new Point(x - 10, y + 10);
var p4 = new Point(x + 10, y - 10);
g.DrawLines(p, new Point[] { p1, p2 });
g.DrawLines(p, new Point[] { p3, p4 });
}
}
}