The thing is I have some graphics shown in a form, rectangle for example, and I want to capture when the point gets over thees fields. So I Thoght I try to find the corrrdinates for thees rectangles, but as thay are the coords in the form it dose not match the ones with the mouse location.
So I wonder is there a way to find what coord on the screen a Point has on the screen and not in the form or controller?
Each control hs PointToFoo methods for conversion. Note that you should call this from the parent of the object who's location you want:
Point scrPos = this.PointToScreen(panel1.Location);
Alternatively, you can get the panel's screen coordinates with:
Point scrPos = panel1.PointToScreen(new Point(0,0));
Note that the above two examples could gve different result due to the border-size of the panel.
If you are using the graphics object for the form by calling this.CreateGraphics() within the form, then the coordinates used when you draw the rectangle should be exactly the same as those returned by the click event on the form.
Do you know what coordinates your pointer is in? You can get the coordinates for your window with a call to GetWindowRect() and subtract the top/left from your mouse cursor to get client coordinates.
I seem to remember there being a function to do that for you in fact, but it's been some time since I dabbled in custom GUI controls.
Related
If I create a Form, Size=(300,300),
then its .ClientRectangle property returns {X=0,Y=0,Width=292,Height=266}
From the Rectangle that we receive, it seems that we get the Size of the Client Area, but not the Location inwhich it starts relative to the form's Top-Left corner(above th title bar and border)..
The X and Y values are always 0,0,
yet we know that there is an offset between the Form's top-left corner, and its Client Area..
(because there is the Title Bar, and form Border)
So how can I get the actual starting point for it?
Going over Control's properties, I couldn't find one,
and as written above, the X,Y part of the .ClientRectangle property always returns 0,0..
The reason I ask this, is because If you want to use the Control.DrawToBitmap() method,
then you need to supply it with a Bitmap object with some size.
If you create a Bitmap in the size of Form.Size, then you can capture the whole form.
It will look like this:
Yet if you want to capture only the client area of the form,
then you can create a Bitmap object with size=Form.ClientRectangle,
but then you need to know at which point the client rectangle starts..
or else, your capture will look like this:
As can be seen, it's indeed in the size of the client area, but it doesn't start at the right location..
So when wanting to capture only the Client Area of the form, we need to know where the client area starts, relative to the Form's real starting point
(the top-left point, at which the border corner is, right above the title bar)
Are you looking for that:
// -8, -30 at my workstation
// so 30 is a size of caption and top border
// 8 is a left border size
Point leftTopShift = PointToClient(this.Location);
I created simple form and now I want to draw single objects (rectangle, circle, lines..) in relative coordinates.
Main problem for me here is to create 2D cartesian coordinate system in middle of the form.Is it possible and how to do it??
Main question is how to efficiently transform absolute coordinates to relative? How to create my own system so I get results in numbers (negative, positive depending on quadrant) and not in pixel?
.
Currently I made MouseMove event to display current location of mouse with Cursor.Position.X, Cursor.Position.Y and display it in label. Displayed coordinates are pixels, how to change that? I've read something about converting with PointToClient method but I don't really understand it.
I am tied to windows forms becouse I already made a program in win forms and now I just want to add this feature to it.
Thanks
What you're most likely looking for are Graphics.TranslateTransform and Graphics.ScaleTransform.
private void Transform(PaintEventArgs e)
{
e.Graphics.ScaleTransform(width, height);
e.Graphics.TranslateTransform(xOffset, yOffset);
}
You'll also need to make sure that whatever drawing method you're using has an overload for either PointF structures or Singles.
Of course, you could also just handle all of this on your end. Scaling your input/output coordinates by the width and height of the form and then translating by half of that will give you the same results.
Edit- To add some clarity, Windows always expects your coordinates to be in pixel form. You can use the above transformations to do your work at a different scale and then transform into the form that Windows expects.
Setting the translation should be straightforward. If you want the middle of the form, you simply want to translate by half the width and half the height. How you choose to scale your coordinates is going to depend on the range that you need to work in (ie, -1.0 to 1.0, -0.5 to 0.5, etc.).
In a WinForm application, when subscribing to OnPaint() event, PaintEventArgs provide a ClipRectangle property that define the region to be drawn.
When the form is resized vertically or horizontally, it gives the minimum rectangle to be draw.
But when window is resized in both directions, there several regions that need to be draw (one on right, one at bottom) and OnPaint event merge them. It results in a rectangle having same size as Form (thus everything is redraw). What i'd like to have is individual regions separately (the two rectangles on the picture)
I know that GDI+ automatically clips what doesn't need to be draw (things are outside the two rectangles, not just ClipRectangle) but i'd like to minimize GDI+ calls at maximum (i already have performance issues when drawing in OnPaint event because of many GDI+ calls, this is not premature optimisation)
Painting in Windows is initiated by the WM_PAINT message handler. It must call BeginPaint() to get info about what needs to be painted. Which returns a struct of type PAINTSTRUCT, it looks like this:
typedef struct tagPAINTSTRUCT {
HDC hdc;
BOOL fErase;
RECT rcPaint; // <=== here
BOOL fRestore;
BOOL fIncUpdate;
BYTE rgbReserved[32];
} PAINTSTRUCT, *PPAINTSTRUCT;
The rcPaint member is the one that you get from Graphics.ClipRectangle. The Graphics.Clip and Graphics.ClipBounds properties are not relevant, they only work if you intentionally clip yourself by assigning the Clip property.
Clearly Windows itself does not let you find out what you are asking for. rcPaint is a RECT, a simple rectangle. Windows only keeps track of a dirty rectangle, not a region. New rectangles added by InvalidateRect() are merged with the existing one and you'll indeed easily end up with the entire client area.
The only reasonable way to tackle this problem is to pay attention to the ResizeBegin and ResizeEnd events. When you get ResizeBegin then you know that the user is dragging a window edge or corner. Knowledge that you can use to optimize the painting, skipping expensive bits that make the modal resizing loop work poorly.
I am making a form which has a ListView. I want to show a "Picture Window" whenever mouse hovers above one of the listView Item in the ListView. I implemented this by using "ListView"'s "ItemMouseHover" event. I want to show this "Picture Window" just near to the mouse position. But , I couldn't get the mouse position from the itemmousehover event. Can anybody say how to achieve this?
Note: I am using .Net 4.0
EDIT:
"Danbystrom" gave the exact answer. But I found the root cause is some other. See my answer for that.
The static method Control.MousePosition will give you the coordinates in screen space. Then you can convert that into client coordinates with the Control.PointToClient instance method.
var pt = listView.PointToClient( Control.MousePosition );
The new window will be placed on your will, only if you choose "Manual" instead of "WindowsDefaultLocation" in the Property "StartPosition". Otherwise "OS" will try to put your new window's location somewhere near to the mouse position. If the new window hides the mouse in that position, then it will try through some nearby points which will result in flickering.
I can get the coordinates of a windows entire area, and the coordinates of the client area using the GetClientRect and GetWindowRect Win32 calls. My problem is that the GetClientRect always returns 0,0 for the top left. How do I figure out what the actual client region is relative to the window rect?
You can use ClientToScreen to get the coordinates of the upper left (0,0) point in screen coordinates. The RECT returned by GetClientRect will be appropriate to get you the lower right corner (just add to the POINT set by ClientToScreen).
Use ClientToScreen to convert the client coordinates to screen coordinates. The window rect (GetWindowRect) is already in screen coordinates, and includes the non-client area (borders, caption, etc)
And if you are working with WinForms then you can use PointToScreen instead of ClientToScreen for solution proposed by Reed Copsey.
The relation between window rect (with borders etc) and the client rect (inside borders) is most easily found using AdjustWindowRectEx(). Get the window style and ex style of the window, and call that function, to see how much border is on each side.
You can also use the MapWindowPoints function to convert an entire RECT to screen coordinates at once.