Frames

Win32++

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.