Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Drawing a Custom Mainframe Window for MFC SDI Applications

0.00/5 (No votes)
21 Aug 2017 1  
How to completely take control of drawing a custom application window including the captionbar, menubar, toolbar, borders and statusbar in MFC Single document interface (SDI) applications using the MfcSkinSDI class.

Introduction

At times, you may need to deviate from the conventional look and feel of Windows MFC applications and be able to give your applications a customized appearance. This can be fairly tedious work especially for the beginner. The MfcSkinSDI class will serve as a base class for the Mainframe class in your MFC applications to allow you to customize and take full control of the appearance of the MFC SDI application's window including the Captionbar, Menubar, Toolbar, borders and Statusbar. The source download includes source files for the MfcSkinSDI and CustomStatusBar classes and an additional Word document file that contains function references for the methods used in these classes.

MfcSkinSDI demo application

Background

Sometime ago, I was looking for a way to customize the appearance of my MFC applications window. After learning that MFC doesn't out of the box make this task easier, I surfed the web to get the best solution. After looking at many articles including those on MSDN, I found out that unfortunately for me, most of them focus on specific elements of the application's window like the Captionbar, Menubar or the Toolbar, not to mention a few of them use a complicated implementation to achieve this goal. So I decided to write a class that would allow me to take some sort of broad control over the drawing of MFC application Mainframe window.

Using the Code

Before you begin, you should know this class works only for your SDI MFC applications. To use CMfcSkinSDI class to customize the appearance of your application, first extract the folder that contains the source files. In there, you will find four files (MfcSkinSDI.h, MfcSkinSDI.cpp, CustomStatusBar.h and CustomStatusBar.cpp).

Copy these files to your project folder and add them to your project by using the “Add Existing Item…” or some similar option from the “Project” menu in your Visual Studio IDE. Once you added these files to your project, you will see the class “CMfcSkinSDI” and “CCustomStatusBar” under Class View.

Include MfcSkinSDI.h and replace the base class from CFrameWnd to CMfcSkinSDI in the header file of your CMainFrame class (MainFrm.h):

// MainFrm.h : interface of the CMainFrame class
//
...
#include "MfcSkinSDI.h"

class CMainFrame : public CMfcSkinSDI
{
...

While you are at the header file, delete the m_wndToolBar and m_wndStatusBar member variables in your CMainFrame class.

//you need to remove these members from your Mainframe class
//because they are already included in the base CMfcSkinSDI class
protected:  // control bar embedded members
    CStatusBar  m_wndStatusBar;
    CToolBar    m_wndToolBar;
...

Go to the source file for your CMainFrame class (MainFrame.cpp) and replace all occurrences of CFrameWnd by CMfcSkinSDI. This includes base class calls inside the AppWizard generated functions of your CMainFrame class. The best way to do this is to use the “Replace” feature (usually found at the edit menu) of the Visual Studio IDE and replace all occurrences of CFrameWnd with CMfcSkinSDI.

IMPLEMENT_DYNCREATE(CMainFrame, CMfcSkinSDI)

BEGIN_MESSAGE_MAP(CMainFrame, CMfcSkinSDI)

//For example in the Oncreate() method of your mainframe class
//one occurrence of CFrameWnd is replace by CMfcSkinSDI class
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CMfcSkinSDI::OnCreate(lpCreateStruct) == -1)
        return -1;

//do this for all occurrences of CFrameWnd you find in the source file
...

At the bottom of the OnCreate() function of your CMainFrame class, add the following lines of code:

//these three lines of code should always be called from the OnCreate() method
InitilizeCustomDraw();
tbSetStyle();
ChangeMenuToCustomDraw(this->GetMenu());
...

That is it! Now your application’s MainFrame window is derived from the CMfcSkinSDI class and can use its customization functions. You can call additional functions to take full control of the drawing process for the application's window. For example, the following lines of code will make the menu items text capitalized, set a common background color for the Captionbar, Menubar, Toolbar and borders, set the border dimensions and so on. See the list of functions and the function reference in the FunctionRef.doc file which is included with the source download to see the available functions and how to use them.

//we are inside the OnCreate() method

CapMenuBarItems(true); //Capitalize the menubar item text
InitilizeCustomDraw();
tbSetStyle();
ChangeMenuToCustomDraw(this->GetMenu());
borderSetDimension(2,2,-1,2);          //set border dimension
SetMenuBarBottomMargin(5);             //set the space b/n the menubar and toolbar
SetCommonBkColor(RGB(239,239,242));    //set common bk color for the Captionbar, 
                                       //Menubar, Toolbar and borders
SetCaptionTextColor(RGB(100,100,100)); //set caption text color
SetSystemBtnColor(RGB(0,0,0));
SetMenuBarHoverColor(RGB(255,255,255));//set the highlight color for the
                                       //menu bar item when the mouse is hovering over it
SetMenuBarSelectColor(RGB(50,120,200));//set the color of the menubar item when it is selected
SetMenuTextColor(RGB(0,0,0));
m_wndStatusBar.SetBackgroundColor(RGB(1,120,208));
borderSetOutlineColor(RGB(1,120,208));

...

History

  • September 9th, 2014 - First release

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here