Where The Streets Have No Name

Creating a Property Sheet Inside a Dialog 본문

Developement/C, C++, C#

Creating a Property Sheet Inside a Dialog

highheat 2008. 5. 25. 14:47

출처 : http://www.codeguru.com/Cpp/controls/propertysheet/article.php/c583/

Although you can resize the property sheet and place other controls in it, sometimes its just easier to create a dialog with
 all the controls in place and then create a property sheet inside the dialog. You can layout the controls at design time and
also the property sheet need not be on the left top side of the dialog.

Step 1: Create a dialog template with space for the property sheet


When a property sheet is created, it is automatically sized so that the tallest as well as the widest page fits in it. Therefore,
when designing the dialog in the resource editor, you can use a picture box as a place holder for the property sheet. The
size of the picture box will need some tweaking so that it matches the size of the property sheet at run time.

Here is a suggestion on how you can get an appropriate size for the picture box. In the resource editor, open up the tallest
property page that will be included in the property sheet. Draw a picture box in it so that the picture completely fills it. Pull
the middle grips outwards to make sure that the picture is the same size as the client area of the property page. Since the
property sheet displays the tab above the property page extend the top edge of the picture to the top edge of the page
caption. You can do this by dragging the top middle grip point while holding the Alt key down. Cut the picture to the
clipboard (Ctrl-X) and then paste it in the dialog in which we want to create the property sheet. Change the ID of the picture to something like IDC_PROPSHEET.

Now open the resource file in text mode. The resource file has the same name as the project and the extension 'rc'. You
can either open the resource file in notepad or in DevStudio by specifying 'Open as Text' in the Open dialog. Search for the widest property page. You will encounter a line like

IDD_FONTPAGE DIALOG DISCARDABLE  13, 54, 264, 133

The third numeric value (264) is the width of the property page. Now search for the IDC_PROPSHEET and set its width to 3
more than the width of the property page and increase its height by 3. The height is the last number on the line. We
increase the width and height by 3 because the property sheet adds a margin around the property page and this increase
should account for that. Now the picture box is about the same size as the property sheet when it displays. Place the
picture box where you want the property sheet to display.

Step 2: Add variable for Property Sheet and Property Pages

Add member variables to the CDialog derived class for the property sheet and all the property pages that it will contain.
Although the sampe code uses plain variables, you may want to use pointer variables and use 'new' to allocate the object
when its needed.

Note that the sample code uses a generic property sheet object and three custom property page objects. This is dependent on your applications needs.

protected:	
    CPropertySheet m_dlgPropSheet;
CStylePage m_stylePage;
CColorPage m_colorPage;
CFontPage m_fontPage;

Step 3: Create the property sheet in OnInitDialog()

Override the OnInitDialog() function and add the code to create the property sheet. We use the position of the picture box -
IDC_PROPSHEET - to position the property sheet at the proper place.

After creating the property sheet, this function changes the style of the property sheet by adding the
WS_EX_CONTROLPARENT flag. This is needed by the dialog so that it can avoid an endless loop when searching for the
next tab item. The WS_EX_CONTROLPARENT flag for the property sheet tells the dialog that it should look at the it should
look at the children controls of the property sheet as well when searching for the control with focus. We also set a tab stop
to the property sheet so that the user can tab to the property sheet.

Note that the call to SetWindowPos() subtracts 7 from the x as well as the y position. This is again to account for the
margin that the property sheet uses. The value 7 works fine for the default font used by the resource editor. If you use a
different font, then this value would have to be adjusted accordingly.

BOOL CMyDlg::OnInitDialog(){
CDialog::OnInitDialog();
m_dlgPropSheet.AddPage(&m_stylePage);
m_dlgPropSheet.AddPage(&m_colorPage);
m_dlgPropSheet.AddPage(&m_fontPage);
m_dlgPropSheet.Create(this, WS_CHILD | WS_VISIBLE, 0);
m_dlgPropSheet.ModifyStyleEx (0, WS_EX_CONTROLPARENT);
m_dlgPropSheet.ModifyStyle( 0, WS_TABSTOP );
CRect rcSheet;
GetDlgItem( IDC_PROPSHEET )->GetWindowRect( &rcSheet );
ScreenToClient( &rcSheet );
m_dlgPropSheet.SetWindowPos( NULL, rcSheet.left-7, rcSheet.top-7, 0, 0,
SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE );
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}