Introduction
Regions are a resource in windows that are very useful. They are device independent,
which means that a device context (DC) is not need to create or use one. However, there
are many functions in the WIN32 GDI that require a region.
Some of the useful places for a region are:
- Update Region, Paint
- Clipping, Paint
- Hit Testing
- Define window shape, Irregular Shaped Windows
Many of the functions that relate to regions are very simple, and need very little
explanation, in fact the definition from MSDN is adequate enough to explain these functions.
However, some of the functions are a little more difficult to understand and master, therefore
extra details have been added to explain these functions. A few diagrams may accompany
the explanation as well.
Region Creation
There are a number of ways to create a region. There are a number of functions
that can be used create a region, from a simple shape such as a rectangle or an ellipse,
to a complicated shape such as the outline of a string of text. Listed below is a table
that describes each of the creation functions.
Function |
Description |
CreateEllipticRgn |
Creates an elliptical region. As with drawing ellipses, elliptic regions are very large, and may slow your program down if you use a large number of them. |
CreateEllipticRgnIndirect |
Creates an elliptical region from a RECT structure. As with drawing ellipses, elliptic regions are very large, and may slow your program down if you use a large number of them. |
CreatePolygonRgn |
Creates a polygonal region. |
CreatePolyPolygonRgn |
Creates a region consisting of a series of polygons. |
CreateRectRgn |
Creates a rectangular region. |
CreateRectRgnIndirect |
Creates a rectangular region from a RECT structure. |
CreateRoundRectRgn |
Creates a rectangular region with rounded corners. |
ExtCreateRegion |
Creates a region from the specified region and transformation data. |
PathToRegion |
Creates a region from a WIN32 Path created in a DC. |
Operations
There are a few operations that can be performed on a region in order to query, modify
test its data.
CombineRgn
After a few basic regions are created, it is possible to perform boolean operations on
the regions in order to create more complex regions with CombineRgn
. This
function has five operations that can be performed in order to combine two different
regions. Shown below is an example of each of the boolean operations that can be
performed in CombineRgn
:
Value |
Description |
Result |
RGN_AND |
Creates the intersection of the two combined regions.
CombineRgn(hrgnDest, hrgnSrc1, hrgnSrc2, RGN_AND); |
|
RGN_COPY |
Creates a copy of the region identified by hrgnSrc1.
CombineRgn(hrgnDest, hrgnSrc1, NULL, RGN_COPY); |
No Image |
RGN_DIFF |
Combines the parts of hrgnSrc1 that are not part of hrgnSrc2.
CombineRgn(hrgnDest, hrgnSrc1, hrgnSrc2, RGN_DIFF); |
|
RGN_OR |
Creates the union of two combined regions.
CombineRgn(hrgnDest, hrgnSrc1, hrgnSrc2, RGN_OR); |
|
RGN_XOR |
Creates the union of two combined regions except for any overlapping areas.
CombineRgn(hrgnDest, hrgnSrc1, hrgnSrc2, RGN_XOR); |
|
One more thing to point out is that the destination region in CombineRgn
can be
one of the source regions. Therefore, if you continually modify a region by adding or
subtracting a different region from it, you can perform one combine operation rather than
worrying about copying the adjusted region. Here is an example:
HRGN hCacheRgn;
HRGN hUpdateRgn;
...
HRGN hTemp = ::CreateRectRgn(0,0,0,0);
::CombineRgn(hTemp, hCacheRgn, hUpdateRgn, RGN_DIFF);
::CombineRgn(hCacheRgn, hTemp, NULL, RGN_COPY);
::DeleteObject(hTemp);
::CombineRgn(hCacheRgn, hCacheRgn, hUpdateRgn, RGN_DIFF);
EqualRgn
The EqualRgn
function checks the two specified regions
to determine whether they are identical. The function considers two regions
identical if they are equal in size and shape.
BOOL EqualRgn(
HRGN hSrcRgn1,
HRGN hSrcRgn2
);
PtInRegion
The PtInRegion function determines whether the specified point is inside the
specified region. This function is very useful for creating a hit-test region
on your control. Such as a bitmap that has a hot-region that can be clicked
by the user.
BOOL PtInRegion(
HRGN hrgn,
int X,
int Y
);
RectInRegion
The RectInRegion
function is very similar to PtInRegion
,
except that it will determines whether any part of the specified rectangle is within
the boundaries of a region.
BOOL RectInRegion(
HRGN hrgn,
CONST RECT *lprc
);
GetRgnBox
The GetRgnBox
function retrieves the bounding rectangle of the specified region.
int GetRgnBox(
HRGN hrgn,
LPRECT lprc
);
OffsetRgn
The OffsetRgn function moves a region by the specified offsets.
int OffsetRgn(
HRGN hrgn,
int nXOffset,
int nYOffset
);
SetRectRgn
The SetRectRgn
function converts a region into a rectangular region
with the specified coordinates.
BOOL SetRectRgn(
HRGN hrgn,
int nLeftRect,
int nTopRect,
int nRightRect,
int nBottomRect
);
Paint Functions
WIN32 provides a number of functions that will allow a region handle to be used for
painting affects. These effects include filling with a brush, outlining, and inverting the
current contents
FillRgn
The FillRgn
function fills a region by using the specified brush.
BOOL FillRgn(
HDC hdc,
HRGN hrgn,
HBRUSH hbr
);
FrameRgn
The FrameRgn
function draws a border around the specified region by using the specified brush.
BOOL FrameRgn(
HDC hdc,
HRGN hrgn,
HBRUSH hbr,
int nWidth,
int nHeight
);
InvertRgn
The InvertRgn
function inverts the colors in the specified region.
BOOL InvertRgn(
HDC hdc,
HRGN hrgn
);
PaintRgn
The PaintRgn
function is similar to the FillRgn
function,
except that this function paints the specified region by using the brush currently
selected into the device context.
BOOL PaintRgn(
HDC hdc,
HRGN hrgn
);
GetRegionData
The GetRegionData
function fills the specified buffer with data desc
DWORD GetRegionData(
HRGN hRgn,
DWORD dwCount,
This data includes the dimensions of the rectangles that make up the region.
LPRGNDATA lpRgnData
);
Region Data
A WIN32 region is really a set of rectangles managed in one object. The RGN_DATA
structure manages this set of rectangles as well as some of the other data that is
required to maintain the region. The RGN_DATA structure is accessible through the
GetRegionData
function. A region object can be created with a
RGN_DATA structure with the ExtCreateRgn
function. Here is a diagram
to show the internal representation of a HRGN object. Each rectangle in the region
is painted with an alternating colored brush.
ExtCreateRgn
The ExtCreateRegion
function creates a region from the specified region
and transformation data.
HRGN ExtCreateRegion(
CONST XFORM *lpXform,
DWORD nCount,
CONST RGNDATA *lpRgnData
);
Something to be aware of, is that Windows 2000 will accept a region that has overlapping
rectangles. If you try to create a region with data that contains overlapping rectangles
on Windows NT4, this function will fail. Therefore if you create one of these regions on
a Windows 2000 machine, and store the RGN_DATA of a region in a file or send the data
across the network to a Windows NT4 machine, when you try to call ExtCreateRgn
on the structure, it will fail.
The Windows 9x kernel dpes not support world transforms that involve either
shearing or rotations. ExtCreateRegion
fails if the transformation (XFORM)
matrix has a scaling or translation of the region.
Demonstration
The program that has been created to demonstrate some of the possibilities for
regions is an interactive window that allows the user to create two regions. The user can
add new portions to either one of the source regions with a rectangle, ellipse or round rectangle
tool. The polygon has been left out simply because of extra work related to the UI that would
be required to incorporate this tool, however, a polygon is completely possible.
Here are the directions for creating a source region:
- Select the desired draw mode shape from the menu or the tool bar. There are three
choices, Rectangle , Ellipse , or Round Rectangle .
- Select and area on the main window, and start dragging the region. A rubber-banding effect
will show where the region will appear.
- Use the Left mouse button to draw a shape for the Source 1 region.
Use the Right mouse button to draw a shape for the Source 2 region.
- At any time, you can hit the Escape key to cancel the drawing operation.
- Let go of the mouse button to update the region with the new shape that you have created.
- The Source 1 region will be drawn in RED, the Source 2 region will be drawn in Blue.
On the right-hand side of the window where the regions are drawn, there are four sub-views,
where the different combine modes: RGN_AND, RGN_DIFF, RGN_OR, RGN_XOR
are all
demonstrated. As each source region is modified, these sub-views are updated. It is possible
to replace one of the current source regions with one of the sub-view results simply by dragging the
region to the window where the source regions are displayed. The Source 1 and Source 2
regions are displayed in Red and Blue respectively, just as in the main view, and the new
combine region will be displayed in purple.
Here are the directions for moving the combine region to the source region.
- Simply decide which of the four sub-views that you would like to use.
- Click in the sub-view and drag the mouse to the main window. An icon will appear indicating
that the item is being dragged.
- Use the Left mouse button to replace the combine region for the Source 1 region.
Use the Right mouse button to replace the combine region for the Source 2 region.
- At any time, you can hit the Escape key to cancel the replace operation.
- Let go of the mouse button to replace the region with the combine region that you dragged..
You can delete the Source1, Source2 or both of the regions by selecting the appropriate menu item.
You can choose to view either the Source1 region, the Source2 region, or all of the regions by selecting
the appropriate view from the menu. View All is the default selection.
One last operation in the RgnGuide program is to view the rectangles that compose the
region in breakdown mode. You can do this by simply checking either the BreakDown Src 1
or BreakDown Src 2 menu item. The view will then show the selected region broken down
into each of the rectangles that creates that region. Each rectangle will be painted with an
alternating color. A plain reactangle will be pretty boring with one solid colored rectangle.
An ellipse on the otherhand will contain a new rectangle on just about every other scanline.
Conclusion
Regions are a very powerful OS resource that you can use in your program. The demo program
simply illustrates how to manage your resources, there are many other uses than the ones that
have been described. WIN32 provides a rich set of functions that allows you to manage and
manipulate your regions.