I need to get the position of the mouse on click in a form, and save the x and y coordinates. I made this simple function:
public void kokot (MouseEventArgs e)
{
x = e.X;
y = e.Y;
this.Invalidate();
}
How can I call it? When I try kokot() it doesn't work of course, because there are no arguments. So what arguments should I use in this case? Thanks in advance for any help.
public Form1()
{
InitializeComponent();
this.MouseClick += new MouseEventHandler(Form1_MouseClick);
}
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
int x = e.X;
int y = e.Y;
this.Invalidate();
}
Add overload to the function that accept two integers:
public void kokot (int X, int Y)
{
x = X;
y = Y;
this.Invalidate();
}
Then call it like this from anywhere in your code:
Point position = System.Windows.Forms.Cursor.Position;
kokot(position.X, position.Y);
You need to subcsribe to the forms MouseClick Event.
this.MouseClick += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseClick);
Related
So I basically have have a picturebox set to a certain location (61, 361) and I have the below code in a timer, so whenever it is enabled it will increment the location of the x and y axis with a certain amount. I just need help to code it so it will trace a path preferably like a dotted line if possible. Thanks in advance for the help. It moves in a parabolic shape btw.
private void SimulationTimer_Tick(object sender, EventArgs e)
{
Ball.Location = new Point(Ball.Location.X + x, Ball.Location.Y - y);
}
Hope this helps:
private void SimulationTimer_Tick(object sender, EventArgs e)
{
System.Drawing.Point current =new System.Drawing.Point();
current = Ball.Location;
Ball.Location = new Point(Ball.Location.X + x, Ball.Location.Y - y);
PictureBox dot = new PictureBox();
dot.BackColor = Color.Red;
dot.Location = current;
dot.Height= 5;
dot.Width = 5;
this.Controls.Add(dot);
}
you can just modify the dot above to what you need
To achieve a path following the changes you have applied to your picturebox you
save each point in a List
NOTE: As you wrote "pictureBox" i assumed you are using Forms and not WPF
public partial class Form1 : Form
{
private List<Point> _points; // List of Points
private Timer _timer; // The Timer
private Graphics _g; // The Graphics object which is responsible for drawing the anything onto the Form
public Form1()
{
_points = new List<Point>();
_timer = new Timer();
_timer.Tick += Timer_Tick;
InitializeComponent();
_g = CreateGraphics();
}
private void Form1_Load(object sender, EventArgs e)
{
_timer.Start();
}
private void Timer_Tick(object sender, EventArgs e)
{
_points.Add(pictureBox1.Location); // Add the current location to the List
// Invoke the GUI Thread to avoid Exceptions
pictureBox1.Invoke(new Action(() =>
{
pictureBox1.Location = new Point(pictureBox1.Location.X + 2, pictureBox1.Location.Y + 2);
}));
Pen blackPen = new Pen(Color.Black, 3);
Invoke(new Action(() =>
{
for (int i = 1; i < _points.Count; i++) // Start at 1 so if you hav less than 2 points it doesnt draw anything
{
_g.DrawLine(blackPen, _points[i - 1], _points[i]);
}
}));
}
}
For a dotted Line you could only draw every second segment of the Line, but that's something you can figure out yourself.
Preview:
I have a Windows Form, My task is to add drag function to the form. "VendorMasterList" is a label. I have added mouse move, mouse down and mouse up events to that label.
If i tried to drag, the form moves down and then only able to drag the way i want. My question is why its going down?This is my code
private Point startPoint = new Point(0, 0);
private bool isDragging = false;
private void lblHeader_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true; // _dragging is your variable flag
startPoint = new Point(e.X, e.Y);
}
private void lblHeader_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
}
private void lblHeader_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
Point p = PointToScreen(e.Location);
this.Location = new Point(p.X - this.startPoint.X, p.Y - this.startPoint.Y);
}
}
Is there any way to fix this?
Newly added image
I haven' tried your code, but what I see is only partially correct :-)
You save the initial coordinate, which is relative to the upper left corner of the control that's clicked, but you need to save screen coordinates.
Then the mouse is moved and again you get a point relative to that corner. You're missing a few relevant things:
You need to calculate a delta between the two points based on the screen coordinates, otherwise moving the window underneath the cursor gives you wrong values.
You need to add this delta to the form's current location
You need to save the new mouse position to calculate the next delta correctly
The current mouse position based on screen coordinates can be obtained through Cursor.Position.
So your code should read:
private void lblHeader_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true; // _dragging is your variable flag
startPoint = Cursor.Position;
}
private void lblHeader_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
}
private void lblHeader_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
Point p = Cursor.Position;
int deltaX = p.X - startPoint.X;
int deltaY = p.Y - startPoint.Y;
startPoint = p;
this.Left += deltaX;
this.Top += deltaY;
}
}
I just placed a panel on a form and implented the above, which worked.
#IInspector is right when he says that this approach is actually not very good, as it doesn't take into account that Windows can actually handle all this for you.
An alternative approach (and the better one) I'd take is:
Override the WndProc method as shown below
Done. No more mouse handling
The following is an example of how you could override WndProc to do what you need:
protected override void WndProc(ref Message m)
{
const UInt32 WM_NCHITTEST = 0x0084;
const UInt32 HTCAPTION = 0x2;
bool handled = false;
if (m.Msg == WM_NCHITTEST)
{
if (<cursor is within the caption area>)
{
m.Result = (IntPtr)HTCAPTION;
handled = true;
}
}
if (!handled)
base.WndProc(ref m);
}
To restrict the area in which the window can be moved, you could use the following. Of course, #IInspectable will disagree, but you went this road :-)
private void lblHeader_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
Point p = Cursor.Position;
int deltaX = p.X - startPoint.X;
int deltaY = p.Y - startPoint.Y;
startPoint = p;
int fX = this.Left + deltaX;
int fY = this.Top + deltaY;
if (fX >= 0 && fX + this.Width < Area.Width) this.Left = fX;
if (fY >= 0 && f> + this.Height < Area.Height) this.Top = fY;
}
}
I cannot fix my mistake : /
if (Cursor.Position = new Point(x, y)
I have an error on x,y, and I want to change to 50,99 for example
First of all you should trig mouseClick event. It's quite simple:
this.MouseClick += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseClick);
Then you should handle the event. Suppose your desired position is (x,y)=(100,100):
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
int xDesired = 100;
int yDesired = 100;
if (e.X == xDesired && e.Y == yDesired)
MessageBox.Show("Certain point clicked.");
}
Ok so please keep answers very direct and i must say i am very new to C#, i don't know a lot of stuff. Without further adieu my problem.
I am trying to move a picture box horizontally across the screen on a timer.The timer must go infinitely. I have tried all i currently know in C# and searched around quite a lot but nothing answered my exact question which is what i need because of my lesser knowledge of C#. For the last two weeks i worked on graphics mostly and the rest of that was trying to get this to work, So i have no code in my game. This is because for anything to work i need this part to be working. My game is 2D topdown. Any and all help is appreciated.
Thank you for taking the time to read.
Edit
No more answers needed, Thank you Odrai for the answer, it helped me a lot.
Use pictureBox.Location = new Point(x, y) or set pictureBox.Left/Top/Right. You can define x and y as variabels and initialize them with a default value. Increment x on timer tick.
Sample 1:
public partial class Form1 : Form
{
private Random _random
public Form1()
{
InitializeComponent();
_random = new Random();
}
private void timer1_Tick(object sender, EventArgs e)
{
int x = _random.Next(0, 500);
int y = _random.Next(0, 500);
pictureBox1.Top += y;
pictureBox1.Left += x;
}
}
Sample 2:
private void timer1_Tick(object sender, EventArgs e)
{
this.SuspendLayout();
pictureBox.Location = new Point(picust.Location.X + 10, picust.Location.Y);
this.ResumeLayout();
}
Add two buttons with title LEFT and RIGHT to a form and write the following code.
It might give you an idea, how to do simple moving animations.
public partial class Form1 : Form
{
int difference = 0;
Timer timer = new Timer();
public Form1()
{
InitializeComponent();
timer.Interval = 15;
timer.Tick += timer_Tick;
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
pictureBox1.Left += difference;
}
private void btnLeft_Click(object sender, EventArgs e)
{
difference = -2;
}
private void btnRight_Click(object sender, EventArgs e)
{
difference = 2;
}
}
Try This Code it will work :
private void timer1_Tick(object sender, EventArgs e)
{
int width = this.Width; // get the width of Form.
if(pictureBox1.Location.X > width - pictureBox1.Width) //to check condition if pic box is touch the boundroy of form width
{
pictureBox1.Location = new Point(1, pictureBox1.Location.Y); // pic box is set to the new point. here 1 is indicate of X coordinate.
}
else
{
pictureBox1.Location = new Point(pictureBox1.Location.X + 100, pictureBox1.Location.Y); // to move picture box from x coordinate by 100 Point.
}
}
//Try This //
picturebox1.Location = 0,0;
I am trying to move a drawn line by grabbing it with the mouse.
The line have already been drawn with Graphics.DrawLine(Pen P, Point A, Point B).
There is absolutely no problems with creating the Line and drawing it on the form.
I've tried:
Adding the line to a GraphicsPath - This does not even draw the line OnPaint.
Checking if MouseEventArgs e.Location is on the line with some basic algebra (calculations which I have thrown away as of now)
So to sum it up: I want to grab the line and drag it somewhere but I can't even check if e.Location even is on the Line, how do I do this?
EDIT: This is how the code looks when I'm using the GraphicsPath.
When I don't use the GraphicsPath I have:
if (s.thisShape == ShapeType.Line) {
g.DrawLine(pen, s.p1, s.p2);
} else { ... }`
in the drawingShapes method.
From the drawStuff : Usercontrol class:
private void drawStuff_MouseDown(object sender, MouseEventArgs e)
{
pointRegion = e.Location;
for (int i = 0; i < Shapes.Count; i++)
{
if (Shapes[i].Region.IsVisible(pointRegion))
{
isDragging = true;
count = i;
break;
}
}
}
private void drawStuff_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
Shapes[count].moveWithDiff(pointRegion, e.Location);
pointRegion = e.Location;
Refresh();
}
}
private void drawStuff_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
Refresh();
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
drawShapes(e.Graphics);
}
private void drawShapes(Graphics g)
{
temporaryPen = pennaLeft;
foreach (Shape s in Shapes)
{
g.FillRegion(temporaryPen, s.Region);
}
}
From the Shape : Usercontrol class:
public void moveWithDiff(Point pr, Point mp)
{
Point p = new Point();
if (this.thisShape == ShapeType.Line)
{
p.X = mp.X - pr.X;
p.Y = mp.Y - pr.Y;
this.p1.X += p.X;
this.p1.Y += p.Y;
this.p2.X += p.X;
this.p2.Y += p.Y;
}
RefreshPath();
}
private void RefreshPath()
{
gPath = new GraphicsPath();
switch (thisShape)
{
case ShapeType.Line:
gPath.AddLine(this.p1, this.p2);
break;
}
this.Region = new Region(gPath);
}
Now this doesn't even draw the line, however with said if statement in drawingShapes() It draws perfectly but I can not drag it somewhere else.
Let's start with the basics, getting a line on the screen. I created a custom class to handle some of the functions I want available to me for this process:
public class MyLine
{
public Pen pen { get; set; }
public Point Start { get; set; }
public Point End { get; set; }
public MyLine(Pen p, Point p1, Point p2)
{
pen = p;
Start = p1;
End = p2;
}
public float slope
{
get
{
return (((float)End.Y - (float)Start.Y) / ((float)End.X - (float)Start.X));
}
}
public float YIntercept
{
get
{
return Start.Y - slope*Start.X;
}
}
public bool IsPointOnLine(Point p, int cushion)
{
float temp = (slope * p.X + YIntercept);
if (temp >= (p.Y-cushion) && temp <=(p.Y+cushion))
{
return true;
}
else
{
return false;
}
}
}
This class provides a few helper functions that will make our life easier. We have properties that return the slope and the Y-intercept, so we can determine if a certain point is on the line. We then provide a helper function IsPointOnLine() that takes a point and a cushion. The cushion is used to simply allow for a user to click close enough to the line to get it to return true.
Next I am going to instantiate the line and draw it in the Form's paint event:
MyLine m;
private void Form1_Load(object sender, EventArgs e)
{
m= new MyLine(Pens.Black, new Point(20, 20), new Point(40, 40));
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawLine(m.pen, m.Start, m.End);
}
Now you should be able to run your application and see a line that goes from 20,20 to 40,40 on the screen.
Now I want to handle the mouse interaction with the line, so on MouseDown, we will see if the click point intersects the line and if it is set a flag and keep our deltas from the endpoints. On the MouseMove event, we will see if the line has been clicked but not released and reset the coordinates appropriately. In the MouseUp event, we simple reset our flag:
Point deltaStart;
Point deltaEnd;
bool dragging = false;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left && m.IsPointOnLine(e.Location, 5))
{
dragging = true;
deltaStart = new Point(m.Start.X - e.Location.X, m.Start.Y - e.Location.Y);
deltaEnd = new Point(m.End.X - e.Location.X, m.End.Y - e.Location.Y);
}
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (dragging && deltaStart != null && deltaEnd != null )
{
m.Start = new Point(deltaStart.X + e.Location.X, deltaStart.Y + e.Location.Y);
m.End = new Point(deltaEnd.X + e.Location.X, deltaEnd.Y + e.Location.Y);
this.Refresh();
}
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
dragging = false;
}
Now you should be able to click within 5 pixels of the line and have it move with your mouse.
Note, there are some spots in the code that need additional error handling, especially to handle division by 0 errors.
I suggest you create a rectangle that is the width of the line and the length of the line, then you can use
if(rectangle.Contains(Point p))
{
// do your move
}
You can also inflate the rectangle to make it easier to grab with:
rectangle.Inflate(1, 1);