65.9K
CodeProject is changing. Read more.
Home

Simple way to create non-rectangular shaped dialogs

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.81/5 (37 votes)

Dec 7, 2003

1 min read

viewsIcon

157134

downloadIcon

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