Visual C++ 6 Unleashed

Visual C++ 6 Unleashed

By MICKEY WILLIAMS and David Bennett

MFC Classes for GDI Operations

Many of the GDI functions use sophisticated MFC helper classes that let you specify coordinates in a two-dimensional coordinate system. These classes also let you manipulate and perform arithmetic operations on sets of coordinates.

The CPoint, CSize, and CRect classes can hold point coordinates, size coordinates, or rectangles, respectively. They wrap POINT, SIZE, and RECT structures and can be cast into each of these structures. Overloaded operator functions accept these structures as parameters, so arithmetic between the various classes can be performed interchangeably.

This section examines these MFC coordinate-manipulation and storage classes in more detail.

The CPoint Class

The CPoint class wraps a POINT structure to hold a single two-dimensional coordinate specified by its x and y member variables. Many of the drawing functions can use CPoint objects as parameters.

You can construct a CPoint object from two integers specifying the x and y coordinates, another CPoint object, a SIZE structure, or a DWORD value (using the low and high words). You can call the OffSet() function to add an offset value to move the specified coordinates passing x and y coordinates, another CPoint object, or a SIZE structure.

Mostly, however, you probably would use the CPoint's operator overloads to add, subtract, or compare two CPoint objects. Many of these operators let you specify POINT, SIZE, or RECT structures as parameters and return SIZE, POINT, or BOOL values as appropriate.

Table 6.5 lists the available CPoint operator functions.

Table 6.5. CPoint Operator Overload Functions

Operator Description
= Copies the POINT.
+= Adds a POINT or SIZE value to the CPoint object.
-= Subtracts a POINT or SIZE value from the CPoint object.
+ Adds POINT, SIZE, or RECT values.
- Subtracts POINT, SIZE, or RECT values.
== Compares for equality with another POINT or CPoint.
!= Compares for inequality with another POINT or CPoint.

The CSize Class

The CSize class wraps a SIZE structure. This structure stores a two-dimensional size as cx and cy integer members, which are declared as public accessible members. You can construct a CSize object from two integers, a SIZE structure, a POINT structure, or a DWORD value.

You will find that many of the CPoint and CRect functions and operators can take SIZE structure objects as parameters for arithmetic manipulation. Some of the GDI and Windows functions require SIZE structures—usually to specify the size of an object (such as a window).

The CSize class implements the operators listed in Table 6.6.

Table 6.6. CSize Operator Overload Functions

Operator Description
= Copies the SIZE.
+= Adds a SIZE value.
-= Subtracts a SIZE value.
+ Adds POINT, SIZE, or RECT values.
- Subtracts POINT, SIZE, or RECT values.
== Compares for equality with another SIZE or CSize object.
!= Compares for inequality with another SIZE or CSize object.

The CRect Class

CRect is probably the most sophisticated of the coordinate storing classes. CRect wraps a RECT structure that exposes its coordinates as two coordinate pairs. These pairs correspond to the top-left and bottom-right points in a rectangle and are accessible from the RECT structure as the top, left, bottom,and right member integers.

You also can obtain these coordinates as CPoint objects returned by the TopLeft() and BottomRight() functions. The CenterPoint() function is quite useful, because it returns a CPoint object representing the center of the rectangle. You can find the width and height of the rectangle by using the Width() and Height() functions, and you can find the size represented as the CSize object returned from the Size() function.

You can increase and decrease the size of the rectangle by using the InflateRect() and DeflateRect() functions, which are overloaded to take a variety of parameter types. The OffsetRect() function lets you move the position of the rectangle by an amount specified by a SIZE, POINT, or pair of integers.

Intersection, union, and subtraction functions also are provided by IntersectRect(), UnionRect(), and SubtractRect().

Each of these functions requires that you previously called NormalizeRect(). NormalizeRect() ensures that the top-left point coordinates are lower than the bottom-right coordinates; if they are not, it sets them to be so. You may find that some operations leave the coordinates in a condition where the width or height calculations may give negative results. If this is the case, you can call NormalizeRect() to fix them.

If you are implementing drag and drop or want to perform bounds checking, you will find the PtInRect() member function useful. This returns TRUE if the specified point lies within the rectangle.

Several operator overload functions are available, as Table 6.7 shows.

Table 6.7. CRect Operator Overload Functions

Operator Description
= Copies the RECT.
+= Offsets the rectangle by a POINT or SIZE value, or inflates each side by the coordinates of a RECT.
-= Offsets or deflates the rectangle.
+ Offsets or inflates the rectangle, returning a RECT result.
- Offsets or deflates the rectangle, returning a RECT result.
&= Sets the rectangle to the intersection of the rectangle's current value, and another RECT or CRect.
|= Sets the rectangle to the union of the rectangle's current value, and another RECT or CRect.
& Returns the intersection.
| Returns the union.
== Compares for equality with another RECT or CRect.
!= Compares for inequality with another RECT or CRect.

The CRgn Class and Clipping

The CRgn class is another CgdiObject-derived GDI object wrapper class that wraps the HRGN GDI handle. You can retrieve the HRGN handle by casting a CRgn object.

Regions are used primarily for clipping; you can select a region into a device context by using the device context's SelectObject() or SelectClipRegion() function. Thereafter, all GDI-rendering functions performed in the device context are clipped to the specified region.

You can specify complex regions that have overlapped borders, simple regions that do not have overlapping borders, or null regions where there is no specified region data. Many of the functions use and return the type of region specified by the COMPLEXREGION, SIMPLEREGION, and NULLREGION flag values. If an error occurs when combining or selecting regions, the ERROR flag is returned.

To create an initialized CRgn object, you must construct it by using the default CRgn constructor and then use one of the creation functions, such as CreateRectRgn() for rect angles, CreateEllipticRgn() for ellipses, CreatePolygonRgn() for polygons, or CreateRoundRgn() for rounded rectangles. Other functions are available that initialize from structures or create multiple polygons.

You can combine two regions by using the CombineRgn() function. The two source regions specified by pointers to CRgn objects are combined using a logic operation specified by a flag as the last parameter. This flag value can be any one of the following: RGN_AND, RGN_OR, RGN_XOR, RGN_COPY, or RGN_DIFF (the non-overlapping areas).

By using the PtInRegion() or RectInRegion() function, you can perform complex bound checking.

You can use the OffsetRgn() function to move a region and CopyRgn() to copy one region from another. You can test for equivalence between two regions with the EqualRegion() function.

Share ThisShare This

Informit Network