|
This is really cool thanks, but I have one problem.
In my source code I disabled some menu items using the following code:
CMenu* pMenu = GetMenu();
m_bAutoMenuEnable=FALSE;
CMenu* subMenu = pMenu->GetSubMenu(4);
subMenu->EnableMenuItem(0, MF_GRAYED | MF_BYPOSITION);
DrawMenuBar();
It no longer works properly with your new class. How can I disable a menu item programically?
Thanks
Kevin Smith
|
|
|
|
|
I played around with the class to get the disabling working for me. Here's what I did.
Disclaimer: this may not be in line with what the author intended, and it may have
broken something else - but it works for me - I'm using VC 6.
1) I added a bDisabled param to CMenuItem::Draw() as follows:
void CMenuItem::Draw (CDC* pDC, LPCRECT pRect, bool bSelected, bool bDisabled) const
2) In CMenuXP::OnDrawItem(), I updated the call to item.Draw() to provide the param:
item.Draw(
&cDC,
&pDrawItemStruct->rcItem,
(pDrawItemStruct->itemState & ODS_SELECTED)!=0,
(pDrawItemStruct->itemState & ODS_DISABLED)!=0
);
3) I changed a lot of the GetDisabled() checks in void CMenuItem::Draw() to use the new bDisabled param.
Here's the whole new function.
///////////////////////////////////////////////////////////////////////////////
void CMenuItem::Draw (CDC* pDC, LPCRECT pRect, bool bSelected, bool bDisabled) const
{
COLORREF crBackImg = CLR_NONE;
if ( bSelected && !bDisabled )
{
COLORREF crHighLight = ::GetSysColor (COLOR_HIGHLIGHT);
CPenDC pen (*pDC, crHighLight);
// CBrushDC brush (*pDC, crBackImg = GetDisabled() ? HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), +73, 0) : HLS_TRANSFORM (crHighLight, +70, -57));
CBrushDC brush (*pDC, crBackImg = HLS_TRANSFORM (crHighLight, +70, -57) );
pDC->Rectangle (pRect);
}
else
{
CRect rc (pRect);
rc.right = IMGWIDTH+IMGPADDING;
pDC->FillSolidRect (rc, crBackImg = HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), +20, 0));
rc.left = rc.right;
rc.right = pRect->right;
pDC->FillSolidRect (rc, HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), +75, 0));
}
if ( GetSeparator() )
{
CPenDC pen (*pDC, HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), -18, 0));
pDC->MoveTo (pRect->left+IMGWIDTH+IMGPADDING+TEXTPADDING, (pRect->top+pRect->bottom)/2);
pDC->LineTo (pRect->right-1, (pRect->top+pRect->bottom)/2);
}
else
{
CRect rc (pRect);
CString sCaption;
if ( GetCaption (sCaption) > 0 )
{
// pDC->SetTextColor (GetDisabled() ? HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), -18, 0) : ::GetSysColor (COLOR_MENUTEXT));
pDC->SetTextColor ( bDisabled ? HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), -18, 0) : ::GetSysColor (COLOR_MENUTEXT));
pDC->SetBkMode (TRANSPARENT);
CBoldDC bold (*pDC, GetDefault());
rc.left = IMGWIDTH+IMGPADDING+TEXTPADDING;
pDC->DrawText (sCaption, rc, DT_SINGLELINE|DT_VCENTER|DT_LEFT);
CString sShortCut;
if ( GetShortCut (sShortCut) > 0 )
{
rc.right -= TEXTPADDING+4;
pDC->DrawText (sShortCut, rc, DT_SINGLELINE|DT_VCENTER|DT_RIGHT);
}
if ( GetChecked() )
{
COLORREF crHighLight = ::GetSysColor (COLOR_HIGHLIGHT);
CPenDC pen (*pDC, crHighLight);
CBrushDC brush (*pDC, crBackImg = GetDisabled() ? HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), +73, 0) :
(bSelected ? HLS_TRANSFORM (crHighLight, +50, -50) : HLS_TRANSFORM (crHighLight, +70, -57)));
pDC->Rectangle (CRect (pRect->left+1, pRect->top+1, pRect->left+20, pRect->bottom-1));
}
if ( m_ImgDesc.m_hImgList != NULL && m_ImgDesc.m_nIndex != -1 )
{
bool bOver = !GetDisabled() && bSelected;
if ( GetDisabled() || (bSelected && !GetChecked()) )
{
HICON hIcon = ImageList_ExtractIcon (NULL, m_ImgDesc.m_hImgList, m_ImgDesc.m_nIndex);
pDC->DrawState (CPoint (pRect->left + ( bOver ? 4 : 3 ), rc.top + ( bOver ? 4 : 3 )),
CSize (IMGWIDTH, IMGHEIGHT), hIcon, DSS_MONO,
CBrush (bOver ? HLS_TRANSFORM (::GetSysColor (COLOR_HIGHLIGHT), +50, -66) : HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), -27, 0)));
DestroyIcon (hIcon);
}
// if ( !GetDisabled() )
if ( !bDisabled )
{
::ImageList_Draw (m_ImgDesc.m_hImgList, m_ImgDesc.m_nIndex, pDC->m_hDC,
pRect->left+( (bSelected && !GetChecked()) ? 2 : 3 ), rc.top+( (bSelected && !GetChecked()) ? 2 : 3 ), ILD_TRANSPARENT);
}
}
else if ( GetChecked() )
{
// Draw the check mark
rc.left = pRect->left+5;
rc.right = rc.left + IMGWIDTH+IMGPADDING;
pDC->SetBkColor (crBackImg);
HBITMAP hBmp = LoadBitmap (NULL, MAKEINTRESOURCE(OBM_CHECK));
pDC->DrawState (CPoint (rc.left,rc.top+3), CSize(rc.Size()), hBmp, DSS_NORMAL, (HBRUSH)NULL);
DeleteObject (hBmp);
}
}
}
}
|
|
|
|
|
Thanks...
I should have replied earlier, that the author of the article wrote to me and informed me that using MF_GRAYED & MF_DISABLED instead of just MF_GRAYED flags should work. I tried his suggestion and it worked.
Thanks anyway.
|
|
|
|
|
Thank you very much, i have been looking for this grayed thing for quite some time now..;)
|
|
|
|
|
If other ownerdrawn controls coexist with your menus, CMenuXP will handle their OnOwnerDraw calls and assert if they're not menus.
Fix:
in CMenuXP.h:
...
void theClass::OnDrawItem (int i, LPDRAWITEMSTRUCT lpDrawItemStruct) \
{ \
if(lpDrawItemStruct->CtlType == ODT_MENU) \
CMenuXP::OnDrawItem (lpDrawItemStruct); \
else \
baseClass::OnDrawItem (i, lpDrawItemStruct); \
} \
...
Apart from that, it's a really great and easy-to-use class. Beau boulot!
Cheers, Marc Click to see my *real* signature
|
|
|
|
|
Nice job. How to have Office xp type toolbar
Alfred
|
|
|
|
|
Thanks!
|
|
|
|
|
A new version is available.
|
|
|
|
|
Menu doesn't work in NT... 1st Menu item is blanked out and is disable... Any help or suggestions, please?
|
|
|
|
|
Replying to my own thread -
Running VC 7.0...
I put the debug version of my executable in my NT box.
I get assertion on
VERIFY (::GetMenuItemInfo (hMenu, uItem, fByPosition, &m_miInfo)
Any ideas?
|
|
|
|
|
hi did you manage to find a solution to the xpmenu problem in NT?
regards
Bryce
|
|
|
|
|
I am having the same problem
bryce
|
|
|
|
|
Solution :
Insert line
#define WINVER 0x0400
before
#include <afxwin.h>
That's all !!!
P. Vitali
|
|
|
|
|
Oups...
Insert line
#define WINVER 0x0400
before
#include <afxwin.h>
in your stdafx.h file
Works fine for me
P. Vitali
|
|
|
|
|
Gah! I was trying to fix this problem yesterday and eventually came to the same conclusion. The problem only occurs if you're using the platform SDK rather than the headers that come with VC6.
|
|
|
|
|
|
Hi
Can anyone help with this? I'm using this menu for right-click popup menus as well as my main menus. I want to be able to have icons/bitmaps in my right-click popups. How do I do this????
Regards
M
|
|
|
|
|
Very simple:
1- Add a toolbar resource which contains all wanted images.
2- Add a CToolbar object in your mainframe window:
CToolbar m_wndAnotherBar; 3- Add the creation code in the CMainFrame::OnCreate handler (without the WS_VISIBLE flag):
if (!m_wndAnotherBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndAnotherBar.LoadToolBar(IDR_ANOTHERBAR))
{
TRACE0("Failed to create toolbar\n");
return -1;
} And that's all !
The toolbar will be used to display images in menus but will never be visible.
|
|
|
|
|
Your method shown in the previous reply using the toolbars doesn't seem to make sense. How do we set which menu item gets which icon the toolbar. I noticed in the code that there is an extra class which seems to work a CImageList, could we use this instead?
Thanks,
-Matt
|
|
|
|
|
The association between menu item and toolbar item is made by their command IDs. You must set the same ID to the toolbar item and to the menu item. Then, the image of the toolbar item will be displayed in the menu item.
JMLF
|
|
|
|
|
but... in a dialog-based app this wont work.
Cheers, Marc Click to see my *real* signature
|
|
|
|
|
To solve this, I added a static CToolBar member to CMenuXP, that SetWinXPStyle would use instead of going through the frames toolbars.
Cheers, Marc Click to see my *real* signature
|
|
|
|
|
This makes no sense. There is no way to identify the icons in the toolbar, so how can I associate them with a menu item?
|
|
|
|
|
If there is no relation between ID and image it is possible in application class set image position with SetMenuItemInfo. Bitmap is loaded in CMenuXP with CImageList.
|
|
|
|
|
Bonjour Jean-Michel. Je suis développeur d'un logiciel freeware de gestion de médiathèque et collections et je souhaiterais y incorporer le style XP.
Auriez-vous un exemple de code incluant l'ensemble des exemples présents sur ce site (menus + barres d'outils) et d'autres éventuels contrôles XP ? Je recherche un squelette d'application MFC Vc++ 6.x incluant ces fonctions.
Merci d'avance.
Stephane.
|
|
|
|
|