mfc >> CDC::Rectangle and client area

by KidLogik » Sun, 23 Nov 2003 10:52:47 GMT

Hello,

Lets say that place a rectangle border on the client area at
10,10,45,45. And lets say that client area is 200x200 or so. How can
I make the recangle border resize itself in proportion to the changes
of the client area? In other words, lets say I resize the client to
250x200 etc. How can I adjust the border of the rectangle to widen
itself? What would the formula look like to figure out the percentage
of adjustment?


mfc >> CDC::Rectangle and client area

by Joseph M. Newcomer » Sun, 23 Nov 2003 17:06:56 GMT


This is pretty simple arithmetic.

You have a rectangle which is 10,10, 45, 45. Therefore it is a 35x35 rectangle. It
represents 35/200 of the area, and it starts 10/200 from the top and left.

If you double the size to 400x400, you would increase the coordinates by 2, that is, you
would start at 20,20 and run to 90,90, for a 70x70 rectangle.

Note that you really need to keep an "abtract" value of the coordinate in some normalized
coordinate system, and do the placement computations using ONLY this reference value. The
reason is that if you choose values which are not integral multiples of the size, you will
get roundoff errors, which will accumulate, so you will keep losing precision. Eventually,
your drawing will lose coherency.

So rather than think of it as 10, 10, 45, 45 in 200x200, think of it as something like
50,50,225,255 in a 1000x1000 coordinate system, and adjust accordingly in your WM_PAINT
handler based on the current client size.

Of course, you could also use mapping modes to eliminate any need to do these computations
yourself, or transformation matrices.
joe




Joseph M. Newcomer [MVP]
email: XXXX@XXXXX.COM
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm



mfc >> CDC::Rectangle and client area

by KidLogik » Mon, 24 Nov 2003 05:07:03 GMT

Hello Joseph:

I've been messing around with SetMapMode(), SetWindowExt() etc. with
no success. I've read through the MSDN docs about mapping modes and
feel ill right now. I guess I my question is this...Lets say I have a
window, and it holds a bitmap of a human face covering the entire
client area. I then draw a rectangle around the eye of the face. If
the user resizes the client area (bigger or smaller) I want the
rectangle to still cover only the dimensions of the eye in the bitmap.
Is this going to become a huge experiment or is this a trivial task
with the GDI mapping modes etc.?


Similar Threads

1. FillSolidRect fills dropdown combo box area and not CView client area

My application overrides the CView::OnEraseBkgnd function and simply returns
a value of TRUE (i.e. my application is responsible for clearing the client
area each time the display is refreshed).   To clear the screen, I call
CDC::FileSolidRect from within the CView::OnDraw function.   This works well
until I click on a combox box in the toolbar.  After making a selection from
the combo-box, it appears that FileSolidRect only clears the area that was
occupied by the drop down list box associated with the combox-box and not
the client area in the CView.  It is almost as if the device context is
associated with combo box and not the CView.   The problem is corrected the 
next time that CView::OnDraw is called.  But each time I click
on the combo box, the problem reoccurs.  If this statement of the problem is
not to vague, does anyone have an idea of what might be happening and how to
resolve it?

Many thanks,


Ian





2. drawing a rectangle with CDC

3. Draw rounded rectangle inside a specific area

Hi, how can i draw a rounded rectange, with a border within a specified 
area?

i.e. if i have a Rectangle with width and height of 100, how can i draw 
a rectange with 2 pixel border inside of the original one? (the current 
attempts all draw the border just outside of the original rectangle).

At the moment im using the following code, but it allows the rectangle 
to grow - which i definately dont want!

			m_edgePath = new GraphicsPath();

			Point topLeft		= new Point(this.ClientRectangle.Left + 
m_borderWidth,						this.ClientRectangle.Top + m_borderWidth);
			Point topRight		= new Point(this.ClientRectangle.Right - 
m_curveSize.Width - m_borderWidth,	this.ClientRectangle.Top + 
m_borderWidth);
			Point bottomRight	= new Point(this.ClientRectangle.Right - 
m_curveSize.Width - m_borderWidth,	this.ClientRectangle.Bottom - 
m_curveSize.Height - m_borderWidth);
			Point bottomLeft	= new Point(this.ClientRectangle.Left + 
m_borderWidth,						this.ClientRectangle.Bottom - m_curveSize.Height - 
m_borderWidth);

			m_edgePath.AddArc(topLeft.X, topLeft.Y, m_curveSize.Width, 
m_curveSize.Height, 180, 90);
			m_edgePath.AddArc(topRight.X, topRight.Y, m_curveSize.Width, 
m_curveSize.Height, 270, 90);
			m_edgePath.AddArc(bottomRight.X, bottomRight.Y, m_curveSize.Width, 
m_curveSize.Height, 0, 90);
			m_edgePath.AddArc(bottomLeft.X, bottomLeft.Y, m_curveSize.Width, 
m_curveSize.Height, 90, 90);
			m_edgePath.CloseFigure();

			Region preWidenRegion = new Region(m_edgePath);

			m_edgePath.Widen(new Pen(Color.Black, m_borderWidth));

			Region postWidenRegion = new Region(m_edgePath);

			m_edgeRegion = new Region();
			m_edgeRegion.MakeEmpty();

			m_edgeRegion.Union(preWidenRegion);
			m_edgeRegion.Union(postWidenRegion);




Thanks,

4. About get the client rectangle

5. PointToScreen (Client vs screen coordinates) trap for rubber rectangles

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);


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





6. Reserving an area of client form - CSharp/C#

7. How to get _true_ client area of datagrid

I need to get the actual client area of the datagrid.

DataGrid.ClientSize doesn't seem to take into account: borders and scrollbars
(if visible).

What I need is a way to get the visible width, excluding borders and
scrollbars.

Any clues?

8. client area hidden by toolbar - CSharp/C#