|
Frames |
Description
Frames provides application developers with a standard way of presenting their applications to users. Frames usually display a menu, and often also display a toolbar and status bar.
There are two styles of frames used in Microsoft Windows. The Single Document Interface (SDI) frame allows the application to display a single view window. The Multiple Document Interface (MDI) frame allows the application to manage and display multiple view windows at the same time. The frames described in this section are SDI frames.
Refer to CFrame in the Class library section for a description of its member functions.
Frame components
The following diagram illustrates a typical frame application.

The toolbar and menubar are used to accept input from the user. The status bar is used to display status information. The view window is a child window of the frame, positioned over the area that is not occupied by the menu, toolbar and status bar.
Defining the Frame
To create a CMainFrame class, override Win32++'s CFrame class as follows:
// Declaration of the CMainFrame class
class CMainFrame : public CFrame
{
public:
CMainFrame(void);
virtual ~CMainFrame();
protected:
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
virtual void OnCreate();
virtual void OnInitialUpdate();
virtual LRESULT OnNotify(WPARAM wParam, LPARAM lParam);
virtual void SetupToolBar();
virtual LRESULT WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
private:
CView m_View; // The view window
};
The View Window
Every frame must be provided with a view window. The view window can be any sort of window, providing it is a child window, and it is capable of being resized. The types of windows that might be used as view windows include simple windows, rich edit controls, tree view controls, list view controls, tab controls, modeless dialogs, Win32++ dockers, etc.
The view is a window class inherited from CWnd. The view window must be set before the frame window is created. This is usually done in the constructor as follows:
CMainFrame::CMainFrame()
{
//Set m_View as the view window of the frame
SetView(m_View);
}
Incidentally, other parts of Win32++ use view windows as well. View windows are used in:
- Frames
- MDI children
- Tab controls
- TabbedMDIs
- Dockers
- Dock containers
Each of these use view windows in the same way.
Customising the Frame's Creation
The OnCreate function determines how the frame will be created. It is this function which creates the various child windows used by the frame, namely the status bar, toolbar, rebar, menu bar, and the view window. Override OnCreate if you wish to modify the creation of the various child windows.
There are several member variables used in OnCreate that affect the appearance of the frame. The following code is part of the generic starter for a frame application. The appearance of the frame can be altered by removing the comment from in front of one or more of the member variables listed.
void CMainFrame::OnCreate()
{
// OnCreate controls the way the frame is created.
// Overriding CFrame::Oncreate is optional.
// The default for the following variables is TRUE
// m_ShowIndicatorStatus = FALSE; // Don't show statusbar indicators
// m_ShowMenuStatus = FALSE; // Don't show toolbar or menu status
// m_UseReBar = FALSE; // Don't use rebars
// m_UseThemes = FALSE; // Don't use themes
// call the base class function
CFrame::OnCreate();
}
Defining the Toolbar Buttons
The bitmap image (or images) associated with the toolbar buttons is specified in the resource script file (Resource.rc). To modify the images displayed on the toolbar buttons, the bitmaps associated with the toolbar will need to be edited accordingly. If the programming environment doesn't include a resource editor for this purpose, a free resource editor such as ResEdit might prove useful. By default, the frame uses the bitmap resource associated with IDW_MAIN when displaying the toolbar. The entry in Resource.rc that associates the bitmap with the resource ID looks like this.
IDW_MAIN BITMAP "res\\toolbar.bmp"
The following code demonstrates how configure the commands issued by the toolbar when the button is pressed. This code should be placed in CMainFrame::SetupToolBar. This is an typical exanple SetupToolBar.
void CMainFrame::SetupToolBar()
{
// Set the Resource IDs for the toolbar buttons
AddToolBarButton( IDM_FILE_NEW );
AddToolBarButton( IDM_FILE_OPEN );
AddToolBarButton( IDM_FILE_SAVE );
AddToolBarButton( 0 ); // Separator
AddToolBarButton( IDM_EDIT_CUT, FALSE ); // disabled button
AddToolBarButton( IDM_EDIT_COPY, FALSE ); // disabled button
AddToolBarButton( IDM_EDIT_PASTE, FALSE ); // disabled button
AddToolBarButton( 0 ); // Separator
AddToolBarButton( IDM_FILE_PRINT );
AddToolBarButton( 0 ); // Separator
AddToolBarButton( IDM_HELP_ABOUT );
}
Refer to the tutorial for a demonstration of customising the toolbar buttons.
Responding to Menu and Toolbar Input
When a menu item is selected or a toolbar button is pressed, a WM_COMMAND message is sent to the frame window. Override OnCommand to respond to these commands as demonstrated in the following code.
BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM /*lParam*/)
{
// OnCommand responds to menu and and toolbar input
switch(LOWORD(wParam))
{
case IDM_FILE_EXIT:
// End the application when exit is selected from the menu
PostQuitMessage(0);
return TRUE;
case IDM_HELP_ABOUT:
// Display the help dialog
OnHelp();
return TRUE;
}
return FALSE;
}
Customising the Toolbar
Various aspects of the toolbar can be configured. The image list associated with normal, hot, and disabled toolbar buttons are set by the SetToolBarImages function. The following code demonstrates the use of the SetToolBarImages function, and shows how to add text to toolbar buttons.
void CMainFrame::SetupToolBar()
{
// Set the Resource IDs for the toolbar buttons
AddToolBarButton( IDM_FILE_NEW );
AddToolBarButton( IDM_FILE_OPEN );
AddToolBarButton( IDM_FILE_SAVE );
AddToolBarButton( 0 ); // Separator
AddToolBarButton( IDM_EDIT_CUT, FALSE ); // disabled button
AddToolBarButton( IDM_EDIT_COPY, FALSE ); // disabled button
AddToolBarButton( IDM_EDIT_PASTE, FALSE ); // disabled button
AddToolBarButton( 0 ); // Separator
AddToolBarButton( IDM_FILE_PRINT );
AddToolBarButton( 0 ); // Separator
AddToolBarButton( IDM_HELP_ABOUT );
// Use larger buttons
SetToolBarImages(RGB(192,192,192), IDB_TOOLBAR_NORM, IDB_TOOLBAR_HOT, IDB_TOOLBAR_DIS);
// Add some text to the buttons
CToolBar& TB = GetToolBar();
TB.SetButtonText(IDM_FILE_NEW, _T("New"));
TB.SetButtonText(IDM_FILE_OPEN, _T("Open"));
TB.SetButtonText(IDM_FILE_SAVE, _T("Save"));
TB.SetButtonText(IDM_EDIT_CUT, _T("Cut"));
TB.SetButtonText(IDM_EDIT_COPY, _T("Copy"));
TB.SetButtonText(IDM_EDIT_PASTE, _T("Paste"));
TB.SetButtonText(IDM_FILE_PRINT, _T("Print"));
TB.SetButtonText(IDM_VIEWMENU, _T("View Menu"));
TB.SetButtonText(IDM_HELP_ABOUT, _T("About"));
}
Customising Menu Items
Menus are typically defined in the program's resource script (resource.rc). A menu definition might look like this:.
IDW_MAIN MENU
BEGIN
POPUP "&File;"
BEGIN
MENUITEM "New...", IDM_FILE_NEW
MENUITEM "&Open...;", IDM_FILE_OPEN
MENUITEM "&Save;", IDM_FILE_SAVE
MENUITEM "Save &As...;", IDM_FILE_SAVEAS
MENUITEM SEPARATOR
MENUITEM "&Print;", IDM_FILE_PRINT
MENUITEM SEPARATOR
MENUITEM "E&xit;", IDM_FILE_EXIT
END
POPUP "&Edit;"
BEGIN
MENUITEM "Undo\tCtrl+Z", IDM_EDIT_UNDO, GRAYED
MENUITEM "Redo\tShift+Ctrl+Z", IDM_EDIT_REDO, GRAYED
MENUITEM SEPARATOR
MENUITEM "Cut\tCtrl+X", IDM_EDIT_CUT, GRAYED
MENUITEM "Copy\tCtrl+C", IDM_EDIT_COPY, GRAYED
MENUITEM "Paste\tCtrl+V", IDM_EDIT_PASTE, GRAYED
MENUITEM "Delete\tDel", IDM_EDIT_DELETE, GRAYED
END
POPUP "&View;"
BEGIN
MENUITEM "&Tool; Bar", IDW_VIEW_TOOLBAR, CHECKED
MENUITEM "&Status; Bar", IDW_VIEW_STATUSBAR, CHECKED
END
POPUP "&Help;"
BEGIN
MENUITEM "&About;", IDM_HELP_ABOUT
END
END
Menu items defined with the "GRAYED" flag are initially disabled. Menu items defined with the "CHECKED" flag are displayed with a check box.
Menu items can also be displayed with an image. The framework will automatically add images for those menu items defined with the same command ID as those used in the Toolbar. We can add icons for other menu items as well. The AddMenuIcons function adds a group of icons for menu items, and the AddMenuIcon function adds icons for individual menu items. Code like this can be added to CMainFrame::SetupToolBar to add icons for menu items.
// Add some extra icons for menu items AddMenuIcon(IDM_FILE_NEWSIMPLE, GetApp()->LoadIcon(IDI_SIMPLE)); AddMenuIcon(IDM_FILE_NEWRECT, GetApp()->LoadIcon(IDI_RECT)); AddMenuIcon(IDM_FILE_NEWTEXT, GetApp()->LoadIcon(IDI_TEXT)); AddMenuIcon(IDM_FILE_NEWLIST, GetApp()->LoadIcon(IDI_FILEVIEW)); AddMenuIcon(IDM_FILE_NEWTREE, GetApp()->LoadIcon(IDI_CLASSVIEW));
Themes
Themes provide an opportunity to set the colour and styles of various parts of the frame, namely the menu, the toolbar and the rebar. By default, the frame will call the SetTheme function from inside OnCreate to set these various colours and styles. SetTheme can be overridden to modify these. This is example shows how set the theme to grey.
void CMainFrame::SetTheme()
{
BOOL T = TRUE;
BOOL F = FALSE;
MenuTheme mt = {T, RGB(182, 189, 210), RGB( 182, 189, 210), RGB(200, 196, 190), RGB(200, 196, 190), RGB(100, 100, 100)};
ReBarTheme rbt = {T, RGB(212, 208, 200), RGB(212, 208, 200), RGB(230, 226, 222), RGB(220, 218, 208), F, F, T, T, T, F};
StatusBarTheme sbt = {T, RGB(212, 208, 200), RGB(212, 208, 200)};
ToolBarTheme tbt = {T, RGB(182, 189, 210), RGB(182, 189, 210), RGB(133, 146, 181), RGB(133, 146, 181), RGB(10, 36, 106)};
SetMenuTheme(&mt;); // Sets the theme for popup menus and MenuBar
SetReBarTheme(&rbt;);
SetStatusBarTheme(&sbt;);
SetToolBarTheme(&tbt;);
}
The definition of the various theme structures are as follows:
struct ReBarTheme
{
BOOL UseThemes; // TRUE if themes are used
COLORREF clrBkgnd1; // Colour 1 for rebar background
COLORREF clrBkgnd2; // Colour 2 for rebar background
COLORREF clrBand1; // Colour 1 for rebar band background. Use NULL if not required
COLORREF clrBand2; // Colour 2 for rebar band background. Use NULL if not required
BOOL FlatStyle; // Bands are rendered with flat rather than raised style
BOOL KeepBandsLeft; // TRUE if we always keep bands left
BOOL LockMenuBand; // Lock MenuBar's band up top, without gripper
BOOL RoundBorders; // Use rounded band borders
BOOL ShortBands; // Allows bands to be shorter than maximum available width
BOOL UseLines; // Displays horizontal lines between bands
};
struct MenuTheme
{
BOOL UseThemes; // TRUE if themes are used
COLORREF clrHot1; // Colour 1 for hot button
COLORREF clrHot2; // Colour 2 for hot button
COLORREF clrPressed1; // Colour 1 for pressed button
COLORREF clrPressed2; // Colour 2 for pressed button
COLORREF clrOutline; // Colour for border outline
};
struct StatusBarTheme
{
BOOL UseThemes; // TRUE if themes are used
COLORREF clrBkgnd1; // Colour 1 for statusbar background
COLORREF clrBkgnd2; // Colour 2 for statusbar background
};
struct ToolBarTheme
{
BOOL UseThemes; // TRUE if themes are used
COLORREF clrHot1; // Colour 1 for hot button
COLORREF clrHot2; // Colour 2 for hot button
COLORREF clrPressed1; // Colour 1 for pressed button
COLORREF clrPressed2; // Colour 2 for pressed button
COLORREF clrOutline; // Colour for border outline
};
Refer to the themes sample application for a demonstration of the different sorts of effects that can be achieved by altering a frame's theme.
Using the Registry
Modern applications are expected to save their settings in the registry. To enable the loading and saving of program settings use the LoadRegistrySettings function in CMainFrame's constructor. If you also wish to load and save a list of Most Recently Used (MRU) files, call the LoadRegistryMRU function settings as well.
CMainFrame::CMainFrame()
{
// Set m_View as the view window of the frame
SetView(m_View);
// Set the registry key name, and load the initial window position
// Use a registry key name like "CompanyName\\Application"
LoadRegistrySettings(_T("Win32++\\Scribble Sample"));
// Load the settings from the registry with 4 MRU entries
LoadRegistryMRUSettings(4);
}
By default CFrame saves the frame size and position in the registry. To load and save other settings, override the LoadRegistyrSettings and SaveRegistrySettings functions in CMainFrame.