Click here to Skip to main content
15,892,161 members
Articles / Desktop Programming / MFC

Enhancements for Jim Koornneef 's CGradientMenu Class

Rate me:
Please Sign up or sign in to vote.
2.10/5 (4 votes)
27 Oct 20041 min read 41.6K   700   12   3
Enhancements for Jim Koornneef 's GradientMenu class on CodeProject

Introduction

This is a sizeable GradientMenu with settings for Menu -Textcolor, -Backgroundcolor and support for the MFC-Framework. Messages it handles are CCmdUI, WM_...MESSAGESTRING, etc.

Background

The CGradientMenu class of Jim Koornneef doesn’t automatically update the states of the menu entries. I decided to write a class based on his adding some new features to it.

Using the Code

Because Jim Koornneef described all necessary things to use his GradientMenu class, I give here only some additional comments about the changes and enhancements.

Changes

  • CGradientMenu::CGradientMenu -> set Menu-Fontsize
  • CGradientMenu::OnPaint -> uses Menu-Fontsize, removing Ampersand's
  • CGradientMenu::PopupSubMenu -> uses SetMenuColors()
  • CGradientMenu :: TrackPopupMenu -> only WM_INITMENUPOPUP to get update info for the menu (CCmdUI)
  • MenuToolBar::OnCreate -> uses Menu-Fontsize
  • MenuToolBar::OnCustomDrawNotify -> uses Menu- and HighLight-Colors, handling of TABs
  • MenuToolBar::OnMouseMove -> send MessageString

New

  • CGradientMenu::ChangeState -> set state (gray / check) of MenuItem
  • CGradientMenu::SetMenuColors -> set colors for Menu-Text, -GrayText, -BackGround, -Highlights
  • MenuToolBar::OnEraseBkgnd -> uses Menu-Background

Sample

C++
// Create a Menu which size is nearly independent of the screen resolution
 
MainFrame.h
[otected:  
 
   CToolBar m_wndMenuBar;
   CFont    dfont;
   int      iFontHight;
   int      iMenuFontHight;
   int      iGradientWidth;
]
 
MainFrame.cpp
[
.
.
.
#include "afxadv.h" // for AFX_IDM_FIRST_MDICHILD
#include "GradientMenu.h"
 
CMainFrame::~CMainFrame()
{
  dfont.DeleteObject ();
} 
 
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
  int _scx, _scy;
  HDC hdc;
 
  hDC = ::GetDC (NULL); 
  _scx = GetDeviceCaps(hDC, HORZRES);
  _scy = GetDeviceCaps(hDC, VERTRES);
  _scb = GetDeviceCaps(hDC, BITSPIXEL);
  ::ReleaseDC (NULL, hDC); 
 
// resolution dependent font size for the menubar
  iFontHight = 16 * _scy / 768;
// resolution dependent font size for the popup menus
  iMenuFontHight = 14 * _scy / 768;
  iGradientWidth = iMenuFontHight + 8;
 
  dfont.CreateFont (
   iFontHight,      // nHeight
   0,         // nWidth
   0,         // nEscapement
   0,         // nOrientation
   FW_BOLD,       // nWeight
   FALSE,       // bItalic
   FALSE,       // bUnderline
   0,         // cStrikeOut
   ANSI_CHARSET,      // nCharSet
   OUT_DEFAULT_PRECIS,    // nOutPrecision
   CLIP_DEFAULT_PRECIS,   // nClipPrecision
   DEFAULT_QUALITY,     // nQuality
   DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
   "Arial");      // lpszFacename
 
  // Create Menu Toolbar
  if (!m_wndMenuBar.CreateEx(this, TBSTYLE_FLAT | TBSTYLE_WRAPABLE, 
       WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP
       | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC,
       CRect(0,0,_scx, 0), CG_ID_VIEW_MENUBAR))
  {
   AfxMessageBox ("Failed to create menubar");
   return -1;   // fail to create
  }
// no Bitmaps
   m_wndMenuBar.GetToolBarCtrl ().SetBitmapSize(CSize (0, 0)); 
// necessary for the button text, the exact button
// size is later calculate automatic
   m_wndMenuBar.GetToolBarCtrl ().SetButtonSize (
     CSize (90, 8 + iFontHight));
// set the resolution dependant font
   m_wndMenuBar.GetToolBarCtrl ().SetFont (&dfont, TRUE);
  
  TBBUTTON   tbb; 
  int    nStr;
 
  memset(&tbb, 0, sizeof(TBBUTTON));
 
  tbb.fsState = TBSTATE_ENABLED;
  tbb.fsStyle = TBSTYLE_BUTTON|TBSTYLE_AUTOSIZE;
  tbb.iBitmap = -1;
  tbb.dwData = NULL;
 
  // Add Menu-Buttons
  nStr =  m_wndMenuBar.GetToolBarCtrl ().AddStrings(IDString (IDS_MB_FILE));
  tbb.iString = nStr;
  tbb.idCommand = ID_MB_FILE;
  m_wndMenuBar.GetToolBarCtrl ().AddButtons(1, &tbb);
.
.
.
  nStr =  m_wndMenuBar.GetToolBarCtrl ().AddStrings(IDString (IDS_MB_WINDOW));
  tbb.iString = nStr;
  tbb.idCommand = ID_MB_WINDOW;
  m_wndMenuBar.GetToolBarCtrl ().AddButtons(1, &tbb);
 
  // Dock the Menu-Bar on top of the window
  EnableDocking(CBRS_ALIGN_ANY);
  m_wndMenuBar.EnableDocking(CBRS_ALIGN_TOP);
  DockControlBar(&m_wndMenuBar);
.
.
}
.
.
.
void CMainFrame::OnFile()
{
  RECT rec;
  POINT pnt;
 
  m_wndMenuBar.GetToolBarCtrl ().GetRect (ID_MB_FILE, &rec);
  ClientToScreen(&rec);
  pnt.y = rec.bottom - 1;
  pnt.x = rec.left;
  
  // Set up the colours.. Might want these in program options
  COLORREF rgb1(RGB(128, 255, 128));
  COLORREF rgb2(RGB(0, 0, 0));
  COLORREF rgbText(RGB(255, 255, 255));
  COLORREF rgbMText(RGB(0, 0, 90));
  COLORREF rgbMGray = GetSysColor(COLOR_GRAYTEXT);
  COLORREF rgbMBack (RGB(255, 255, 230));
  
  // Create a menu, set the width of gradient
  CGradientMenu oMenu(iGradientWidth, TRUE, iMenuFontHight);
  oMenu.LoadMenu(IDR_BEARBEITEN);
  
  // Select colours and set the title for the 1st menu
  // sub menus will take the name of the item selected in the parent.
  oMenu.SetGradientColors(rgb1, rgb2, rgbText);
  oMenu.SetMenuColors(rgbMText, rgbMGray, rgbMBack);
  oMenu.SetTitle((CString)IDString (IDS_MB_FILE)); 
    // i do this for easier changing language in rc-file
  
  // Show the menu!
  oMenu.TrackPopupMenu(0, pnt.x, pnt.y, this);
}
//   P.S.
//   if you include the following lines in your file-menu you 
//   can get the last used files in your GradientMenu
//
//   MENUITEM SEPARATOR
//   MENUITEM "Last File",   ID_FILE_MRU_FIRST, GRAYED
 
.
.
.
// including the list of views to window-menu
// i have already made a enumeration of the shown windows
// iImgCnt = count of shown windows
// iImgAct = number of window that has actually the focus
// pImgDoc[i] = array with pointers to Doc-Objects
 
void CMainFrame::OnWindow()
{
  RECT rec;
  POINT pnt;
  int i;
  UINT flags;
  CMedGrf32Doc* pDoc;
  POSITION pos;
  CWnd* pFrame;
  CMyView* pView;
  char buf[1024], bff[_MAX_PATH];
 
  m_wndMenuBar.GetToolBarCtrl ().GetRect (ID_MB_FENSTER, &rec);
  ClientToScreen(&rec);
  pnt.y = rec.bottom - 1;
  pnt.x = rec.left;
  
  // Set up the colours.. Might want these in program options
  COLORREF rgb1(RGB(128, 255, 128));
  COLORREF rgb2(RGB(0, 0, 0));
  COLORREF rgbText(RGB(255, 255, 255));
  COLORREF rgbMText(RGB(0, 0, 90));
  COLORREF rgbMGray = GetSysColor(COLOR_GRAYTEXT);
  COLORREF rgbMBack (RGB(255, 255, 230));
  
  // Create a menu, set the width of gradient
  CGradientMenu oMenu(iGradientWidth, TRUE, iMenuFontHight);
  oMenu.LoadMenu(IDR_FENSTER);
 
  oMenu.AppendMenu (MFT_SEPARATOR, 0, "");
  for (i = 0; i < iImgCnt; i++)
  {
   flags = MF_STRING | MF_ENABLED;
   if (i == iImgAct)
     flags |= MF_CHECKED;
   *bff = 0;
   if (pImgDoc[i] != NULL)
   {
     pDoc = (CMyDoc*)pImgDoc[i];
     pos = pDoc->GetFirstViewPosition();
     pView = (CMyView*)pDoc->GetNextView(pos);
     pFrame = pView->GetParentFrame ();
     pFrame->GetWindowText (bff, sizeof (bff));
   }
   sprintf (buf, "%d %s", i + 1, bff);
   oMenu.AppendMenu (flags, AFX_IDM_FIRST_MDICHILD + i, buf);
  }
  
  // Select colours and set the title for the 1st menu
  // sub menus will take the name of the item selected in the parent.
  oMenu.SetGradientColors(rgb1, rgb2, rgbText);
  oMenu.SetMenuColors(rgbMText, rgbMGray, rgbMBack);
  oMenu.SetTitle((CString)IDString (IDS_MB_FENSTER));
  
  // Show the menu!
  oMenu.TrackPopupMenu(0, pnt.x, pnt.y, this);
}
]

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.


Written By
Chief Technology Officer
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralHelp me Pin
noom28-Mar-06 22:19
noom28-Mar-06 22:19 
QuestionIs this VC6 compatible? Pin
WREY23-Oct-04 1:22
WREY23-Oct-04 1:22 
I ask that because I substituted both implementation and header files downloaded, for the respective ones in Jim Koornneef's sample, and obtained 5 errors (ranging from one function with the incorrect number of arguments, to another not being a member of CString, a couple others requiring 'l-values' and an undeclared identifier).

Koornneef's sample ran fine. It's when I substituted your files that it didn't compile.

I'd first like to see the sample run with your changes before casting my vote.


William

Fortes in fide et opere!
AnswerRe: Is this VC6 compatible? Pin
Michael Heber24-Oct-04 1:58
Michael Heber24-Oct-04 1:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.