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.