PointToScreen (Client vs screen coordinates) trap for rubberrectangles

R

raylopez99

keywords: logical coordinates, page coordinates, world coordinates,
device coordinates, physical coordinates, screen coordinates, client
coordinates. offset rectangle. WYSIWYG rubber rectangle problem,
bounded rectangle problem. PointToClient, PointToScreen

Beware this newbie trap for the unwary. It goes by various names (in
some old MFC literature I saw some of the keywords above). Whenever
doing comparisons between points, especially using rubber or bounded
rectangles, you want to convert into screen coordinates (aka logical
coordinates, page coordinates, world coordinates) from client
coordinates (aka device coordinates, physical coordinates).

Below is the pseudocode. If you don't do this, whenever you use a
'rubber rectangle' (also called a bounding rectangle, it's something
you create with a mouse to define an area on your screen), you will be
off by an offset, and you rubber rectangle won't quite be capturing
the area on the screen you think it's at. The offset depends on how
small your client window is relative to the full sized window. So, if
you expand you client window to full size, you'll never have this
problem, but if the user doesn't expand the window, the problem
remains unless you use the solution below. The solution is to employ
PointToScreen method, but it has to be done in the manner shown
below. A quick and dirty workaround to the below, which is nasty IMO,
is simply to require the form be always maximized (I've seen programs
do this, but it's not user friendly IMO).

BTW, as an aside, whenever using a rubber rectangle always "normalize
it" meaning whether the user creates it from left to right or right to
left, it gives the same coordinates, otherwise, if it's not
normalized, you'll only capture the screen when you create the rubber
rectangle a certain way (say dragging left to right). Keyword search
"normalize rectangle". In MFC they used to have a function to do
this, but in C# you have to do it yourself. Also you should search
the web for how to do a rubber rectangle; there's lots of examples.

RL

//pseudocode

public void DoSomethingWithABoundedRectangle (Rectangle boundedRect,
object sender, MouseEventArgs e)
{

Control control = (Control)sender; //required for
PointToScreen!

// Calculate points always using the PointToScreen
method.


foreach (Point Y in MyPointList)
{
Point myfirstPoint = new Point();
myfirstPoint.X = Y.X; myfirstPoint.Y=Y.Y; //etc.etc
myfirstPoint = control.PointToScreen(myfirstPoint); //
prevents offset

if (boundedRect.Contains(myfirstPoint))
{
//Do Something //now the bounded rectangle will not be
offset
}
}

/////////////////// the above function was called by the below event
handler

private void Form1_MouseUp(object sender, MouseEventArgs e)
{

// myRubberR; //create a rubber rectangle, should exist here

DoSomethingWithABoundedRectangle (myRubberR, sender,e);


}
//////////////////////////
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top