5,696,038 members and growing! (14,042 online)
Email Password   helpLost your password?
Desktop Development » Miscellaneous » Windows Forms     Intermediate

Using the Windows Forms 2.0 MenuStrip and ToolStrip controls to give your MFC applications a new look and feel

By Nishant Sivakumar

This article demonstrates how to use the Windows Forms 2.0 MenuStrip and ToolStrip controls in an MFC SDI application, using C++/CLI, to get the Office 2003 style menu and toolbar
C++/CLI, Windows, .NET, Visual Studio, Dev

Posted: 15 Feb 2006
Updated: 21 Feb 2006
Views: 54,738
Bookmarked: 24 times
Announcements
Loading...



Search    
Advanced Search
Sitemap
16 votes for this Article.
Popularity: 5.08 Rating: 4.22 out of 5
1 vote, 6.3%
1
1 vote, 6.3%
2
1 vote, 6.3%
3
2 votes, 12.5%
4
11 votes, 68.8%
5

Introduction

In this article, I'll demonstrate how to use the Windows Forms 2.0 MenuStrip and ToolStrip controls in an MFC SDI application, using C++/CLI, to get the Office 2003 style menu and toolbar. I assume that you already know how to use these new Forms controls introduced in Whidbey, that you are familiar with C++/CLI syntax, and that you know about the new Windows Forms interop helper classes that have been added to MFC 8.

Step-by-step guide

This is a step by step guide to adding the Forms controls to an existing application. For the example, just use a default SDI app that's generated by VC++ 8. Note that, the same techniques can be more or less used the same way for an MDI application too - except you need to change the classes used accordingly.

Step 1 : Remove the MFC toolbar creation code

Comment out or delete the MFC toolbar creation code, and any references to it. For a default app, the following lines are to be commented out (or removed).

//if (!m_wndToolBar.CreateEx(this, 

//  TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP

//  | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | 

//  CBRS_SIZE_DYNAMIC) ||

//  !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))

//{

//  TRACE0("Failed to create toolbar\n");

//  return -1; // fail to create

//}


//m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);

//DockControlBar(&m_wndToolBar);

Step 2 : Destroy the MFC menu

You can do this in PreCreateWindow, but for this example, out of personal choice, we'll do this in OnCreate - very early on. The idea is that you can do the same thing if you want to swap the MFC menu for the Forms menu, in response to a user action.

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;

    GetMenu()->DestroyMenu();
    SetMenu(NULL);

Step 3 : Add MenuStrip and ToolStrip members to the frame window class

We use the CWinFormsControl which provides functionality to host a Forms control in MFC.

CWinFormsControl<System::Windows::Forms::MenuStrip> m_MenuStrip;
CWinFormsControl<System::Windows::Forms::ToolStrip> m_ToolStrip;

Step 4 : Create and initialize the MenuStrip and ToolStrip controls

We do this in OnCreate. The code below shows what I've done, and there are a few comments explaining what's being done. It's mostly standard Windows Forms code in there.

using namespace System::Windows::Forms;

//Create the Forms controls and set the frame window as parent

m_MenuStrip.CreateManagedControl(WS_VISIBLE|WS_CHILD, 
    CRect(0,0,0,25),this, 1001);
m_ToolStrip.CreateManagedControl(WS_VISIBLE|WS_CHILD, 
    CRect(0,25,0,75),this, 1002);

//Create and initialize the menu strip


ToolStripMenuItem^ topitem = gcnew ToolStripMenuItem();
ToolStripMenuItem^ item = gcnew ToolStripMenuItem();

topitem->Text = "File";
m_MenuStrip->Items->Add(topitem); 

item->Text = "Open";
//We load the icon using LoadImage, and convert the HICON

//to a Bitmap using the FromHicon method. LoadImage was

//preferred to support higher color icons. The CWinApp LoadIcon

//isn't as flexible or functional, and always treats icons as 32x32.

item->Image = System::Drawing::Bitmap::FromHicon((System::IntPtr)
    LoadImage(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_OPEN),
    IMAGE_ICON,0,0,LR_DEFAULTCOLOR));
//Maps the C++ class method to the event handler

item->Click += MAKE_DELEGATE(System::EventHandler,File_Open_Click);

topitem->DropDownItems->Add(item);

item = gcnew ToolStripMenuItem();
item->Text = "Exit";
item->Image = System::Drawing::Bitmap::FromHicon((System::IntPtr)
    LoadImage(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_EXIT),
    IMAGE_ICON,0,0,LR_DEFAULTCOLOR));
item->Click += MAKE_DELEGATE(System::EventHandler,File_Exit_Click);

topitem->DropDownItems->Add(item);

topitem = gcnew ToolStripMenuItem();
topitem->Text = "Help";
m_MenuStrip->Items->Add(topitem);

item = gcnew ToolStripMenuItem();
item->Text = "About";
item->Image = System::Drawing::Bitmap::FromHicon((System::IntPtr)
    LoadImage(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_HELP),
    IMAGE_ICON,0,0,LR_DEFAULTCOLOR));
item->Click += MAKE_DELEGATE(System::EventHandler,Help_About_Click);

topitem->DropDownItems->Add(item);

//Create and initialize the tool strip


ToolStripButton^ tbutton;

tbutton = gcnew ToolStripButton();
tbutton->Size = System::Drawing::Size(50,50);
tbutton->Text = "Open";
tbutton->TextAlign = System::Drawing::ContentAlignment::BottomCenter;
tbutton->ToolTipText = tbutton->Text; 
tbutton->Image = System::Drawing::Bitmap::FromHicon((System::IntPtr)
    LoadImage(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_OPEN),
    IMAGE_ICON,0,0,LR_DEFAULTCOLOR));
tbutton->ImageScaling = ToolStripItemImageScaling::None;
tbutton->ImageTransparentColor = 
    System::Drawing::Color::FromArgb(220,220,220);
tbutton->ImageAlign = System::Drawing::ContentAlignment::TopCenter;
tbutton->TextImageRelation = TextImageRelation::ImageAboveText;
tbutton->Click += MAKE_DELEGATE(System::EventHandler,File_Open_Click);
tbutton->Padding = Padding(5,0,5,0);

m_ToolStrip->Items->Add(tbutton);

tbutton = gcnew ToolStripButton();
tbutton->Size = System::Drawing::Size(50,50);
tbutton->Text = "About";
tbutton->TextAlign = System::Drawing::ContentAlignment::BottomCenter;
tbutton->ToolTipText = tbutton->Text;
tbutton->Image = System::Drawing::Bitmap::FromHicon((System::IntPtr)
    LoadImage(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_HELP),
    IMAGE_ICON,0,0,LR_DEFAULTCOLOR));
tbutton->ImageScaling = ToolStripItemImageScaling::None;
tbutton->ImageTransparentColor = 
    System::Drawing::Color::FromArgb(220,220,220);
tbutton->ImageAlign = System::Drawing::ContentAlignment::TopCenter;
tbutton->TextImageRelation = TextImageRelation::ImageAboveText;
tbutton->Click += MAKE_DELEGATE(System::EventHandler,Help_About_Click);
tbutton->Padding = Padding(5,0,5,0);

m_ToolStrip->Items->Add(tbutton);

tbutton = gcnew ToolStripButton();
tbutton->Size = System::Drawing::Size(50,50);
tbutton->Text = "Exit";
tbutton->TextAlign = System::Drawing::ContentAlignment::BottomCenter;
tbutton->ToolTipText = tbutton->Text;
tbutton->Image = System::Drawing::Bitmap::FromHicon((System::IntPtr)
    LoadImage(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_EXIT),
    IMAGE_ICON,0,0,LR_DEFAULTCOLOR));
tbutton->ImageScaling = ToolStripItemImageScaling::None;
tbutton->ImageTransparentColor = 
    System::Drawing::Color::FromArgb(220,220,220);
tbutton->ImageAlign = System::Drawing::ContentAlignment::TopCenter;
tbutton->TextImageRelation = TextImageRelation::ImageAboveText;
tbutton->Click += MAKE_DELEGATE(System::EventHandler,File_Exit_Click);
tbutton->Padding = Padding(5,0,5,0);

m_ToolStrip->Items->Add(tbutton);

Step 5 : Handle OnSize in your frame window

We need to prevent the view window from showing itself on top of the menu strip and the tool strip controls we have added. This is done on OnSize.

void CMainFrame::OnSize(UINT nType, int cx, int cy)
{
    CFrameWnd::OnSize(nType, cx, cy);       

    // If the menu strip is created

    if(m_MenuStrip.GetSafeHwnd())
    {
        CRect rect;
        // Need to figure out the required rect that accounts

        // for any other control bars (like the status bar)

        RepositionBars(AFX_IDW_CONTROLBAR_FIRST,
            AFX_IDW_CONTROLBAR_LAST,0,CWnd::reposQuery,&rect);
        // Adjust rect so we have enough space to show

        // the menu and tool strips

        m_MenuStrip->Size = System::Drawing::Size(
            rect.Width(),m_MenuStrip->Size.Height);
        m_ToolStrip->Size = System::Drawing::Size(
            rect.Width(),m_ToolStrip->Size.Height);
        rect.top += (m_MenuStrip->Size.Height + 
            m_ToolStrip->Size.Height);
        CView* pView = GetActiveView();
        if(pView)
        {
            // resize the view window

            pView->MoveWindow(rect);
        }
    }
}

Step 6 : Add delegate maps

These have to be added to the public section in your class declaration. They essentially map event handlers to class methods.

BEGIN_DELEGATE_MAP( CMainFrame )
    EVENT_DELEGATE_ENTRY( File_Exit_Click, 
        System::Object^, System::EventArgs^)
    EVENT_DELEGATE_ENTRY( Help_About_Click, 
        System::Object^, System::EventArgs^)
    EVENT_DELEGATE_ENTRY( File_Open_Click, 
        System::Object^, System::EventArgs^)
END_DELEGATE_MAP()

Step 7 : Add event handlers

Just write the event handlers that are called when a tool strip button or a menu is clicked.

void CMainFrame::File_Exit_Click(System::Object^ sender,
    System::EventArgs^ e)
{
    PostMessage(WM_CLOSE);
}

void CMainFrame::File_Open_Click(System::Object^ sender, 
    System::EventArgs^ e)
{
    PostMessage(WM_COMMAND,ID_FILE_OPEN);
}

void CMainFrame::Help_About_Click(System::Object^ sender, 
    System::EventArgs^ e)
{
    ReleaseCapture(); // Needed as the ToolStrip captures the mouse

    CAboutDlg aboutDlg;
    aboutDlg.DoModal();
}

History

  • Feb 21 2006 - Fixed an issue with showing modal dialogs from a toolbar item click handler.
  • Feb 15 2006 - Article first published.

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

About the Author

Nishant Sivakumar


Sitebuilder, Mvp
Nish is a real nice guy living in Atlanta, who has been coding since 1990, when he was 13 years old. Originally from sunny Trivandrum in India, he recently moved to Atlanta from Toronto and is a little sad that he won't be able to play in snow anymore.

Nish has been a Microsoft Visual C++ MVP since October, 2002 - awfully nice of Microsoft, he thinks. He maintains an MVP tips and tricks web site - www.voidnish.com where you can find a consolidated list of his articles, writings and ideas on VC++, MFC, .NET and C++/CLI. Oh, and you might want to check out his blog on C++/CLI, MFC, .NET and a lot of other stuff - blog.voidnish.com

Nish loves reading Science Fiction, P G Wodehouse and Agatha Christie, and also fancies himself to be a decent writer of sorts. He has authored a romantic comedy Summer Love and Some more Cricket as well as a programming book – Extending MFC applications with the .NET Framework.

Nish's latest book C++/CLI in Action published by Manning Publications is now available for purchase. You can read more about the book on his blog.

Despite his wife's attempts to get him into cooking, his best effort so far has been a badly done omelette. Some day, he hopes to be a good cook, and to cook a tasty dinner for his wife.
Location: United States United States

Other popular Miscellaneous articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 13 of 13 (Total in Forum: 13) (Refresh)FirstPrevNext
GeneralNice article..How to access Parent?memberRajgkk23:33 3 May '07  
GeneralAccess Keys?memberDSmith19741:26 18 Feb '07  
GeneralVertical ToolbarmemberSunil_Cool1:34 23 Jan '07  
QuestionVisual Studio.Net 2003 , mfc 7.1 ?memberfiversen23:27 8 Jan '07  
AnswerRe: Visual Studio.Net 2003 , mfc 7.1 ?memberThe Dogcow Farmer9:59 23 Sep '08  
QuestionYou reduce the MFC functionalitymemberAlexey Shalnov0:15 17 May '06  
GeneralMenu Access and Shortcut Keysmemberr0nen9:48 28 Feb '06  
GeneralNice ArticlememberMajid Shahabfar0:47 22 Feb '06  
GeneralRe: Nice ArticlestaffNishant Sivakumar14:26 22 Feb '06  
GeneralWindows Forms Control class Problem?memberhotsri11:21 21 Feb '06  
GeneralRe: Windows Forms Control class Problem?staffNishant Sivakumar12:46 21 Feb '06  
GeneralIf only I had this a month ago...memberoshah7:39 18 Feb '06  
GeneralRe: If only I had this a month ago...staffNishant Sivakumar12:44 21 Feb '06  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 21 Feb 2006
Editor: Nishant Sivakumar
Copyright 2006 by Nishant Sivakumar
Everything else Copyright © CodeProject, 1999-2008
Web11 | Advertise on the Code Project