Simple way to create non-rectangular shaped dialogs






4.81/5 (37 votes)
Dec 7, 2003
1 min read

157134

3341
This article outlines a simple way to create dialogs which are not rectangular in shape
Introduction
Normally Dialog Boxes are rectangular in shape. Various methods can be adopted to make them non-rectangular in shape. However, most of these methods are complicated and suited for application that uses skinning to create dialogs with the shape of a skin or image. If the required shape of the dialog is simple like a rectangle with rounded corners or an ellipse, then a much simpler method can be used. In this method multiple CRgn
objects are created and then combined (union of regions) to create a compound region. The dialog is then given the shape of the compound region.
The Code
All the required code is in the OnInitDialog
method of the dialog
Step 1: Set Dialog style
To change the shape of the dialog, in the OnInitDialog
of the dialog the Caption and the Border of the dialog is removed.
...
// Remove caption and border
SetWindowLong(m_hWnd, GWL_STYLE, GetWindowLong(m_hWnd, GWL_STYLE)
& (~(WS_CAPTION | WS_BORDER)));
...
Step 2: Create individual regions
Individual elliptic regions are then created using the coordinates of the dialog's window
// Get the rectangle CRect rect; GetWindowRect(&rect); int w = rect.Width(); int h = rect.Height(); CRgn rgn1; CRgn rgn2; // Create the top ellipse rgn1.CreateEllipticRgn(1, 1, w, h/2 + 30); // Create the bottom ellipse rgn2.CreateEllipticRgn(1, h/2 - 30, w, h);
Step 3: Combine the regions into one
The regions are combined to create a single region. The combination is actually a UNION of all the individual regions
// Combine the two ellipses
CombineRgn(rgn1, rgn1, rgn2, RGN_OR);
Step 4: Change the shape of the dialog to the region
The dialogs shape is changed using the following code
// Set the window region SetWindowRgn(static_cast<HRGN>(rgn1.GetSafeHandle()), TRUE);
Step 5: Cleaning up
The CRgn
object needs to be detached from the region, or else the CRgn
destructor closes the HRGN
handle when rgn objects go out of scope
rgn1.Detach(); rgn2.Detach();
History
- Initial version