- Table of Contents
- Copyright
- About the Authors
- About the Contributors
- Acknowledgments
- Tell Us What You Think!
- Introduction
- How to Use This Book
- What You Need to Use This Book
- What's New in Visual C++ 6.0
- Contacting the Main Author
- Part I: Introduction
- Chapter 1. The Visual C++ 6.0 Environment
- Part II: MFC Programming
- Chapter 2. MFC Class Library Overview
- Chapter 3. MFC Message Handling Mechanism
- Chapter 4. The Document View Architecture
- Chapter 5. Creating and Using Dialog Boxes
- Chapter 6. Working with Device Contexts and GDI Objects
- Chapter 7. Creating and Using Property Sheets
- Chapter 8. Working with the File System
- Chapter 9. Using Serialization with File and Archive Objects
- Part III: Internet Programming with MFC
- Chapter 10. MFC and the Internet Server API (ISAPI)
- Chapter 11. The WinInet API
- Chapter 12. MFC HTML Support
- Part IV: Advanced Programming Topics
- Chapter 13. Using the Standard C++ Library
- Chapter 14. Error Detection and Exception Handling Techniques
- Chapter 15. Debugging and Profiling Strategies
- Chapter 16. Multithreading
- Chapter 17. Using Scripting and Other Tools to Automate the Visual C++ IDE
- Part V: Database Programming
- Chapter 18. Creating Custom AppWizards
- Chapter 19. Database Overview
- Chapter 20. ODBC Programming
- Chapter 21. MFC Database Classes
- Chapter 22. Using OLE DB
- Chapter 23. Programming with ADO
- Part VI: MFC Support for COM and ActiveX
- Chapter 24. Overview of COM and Active Technologies
- Chapter 25. Active Documents
- Chapter 26. Active Containers
- Chapter 27. Active Servers
- Chapter 28. ActiveX Controls
- Part VII: Using the Active Template Library
- Chapter 29. ATL Architecture
- Chapter 30. Creating COM Objects Using ATL
- Chapter 31. Creating ActiveX Controls Using ATL
- Chapter 32. Using ATL to Create MTS and COM+ Components
- Part VIII: Finishing Touches
- Chapter 33. Adding Windows Help
- Part IX: Appendix
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().
-
IntersectRect()
makes the current CRect object the intersection rectangle of two source rectangles (where they overlap), as shown in Figure 6.2; the resulting CRect object is shaded.
Figure 6.2 Determining the intersection of two rectangles.
-
UnionRect()
makes the CRect object the union of two source rectangles (the smallest rectangle that encloses both), as shown in Figure 6.3; the resulting CRect object is shaded.
Figure 6.3 Determining the union of two rectangles.
-
SubtractRect()
sets its first RECT parameter's coordinates to the smallest rectangle that is not intersected by two overlapping rectangles (where the second rectangle encloses the first), as shown in Figure 6.4; the resulting CRect object is shaded.
Figure 6.4 Subtracting one rectangle from another.
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.
Working with Fonts | Next Section

Account Sign In
View your cart