|
Also congratulations, very good and useful extension! I tried it and it works great!
But when you also using CToolBarXP (also from Michel le Fol) you have to change some lines in CToolBarXP::OnPaint() because the grayed and hot bitmaps are not shown correctly.
I made the two following changes and it worked:
At the beginning of OnPaint() replace the line
<br />
HIMAGELIST m_hImageList = (HIMAGELIST)DefWindowProc (TB_GETIMAGELIST, 0, 0);<br />
with the three lines
<br />
HIMAGELIST m_hImageListTC = (HIMAGELIST)DefWindowProc (TB_GETIMAGELIST, 0, 0);<br />
HIMAGELIST m_hImageListHT = (HIMAGELIST)DefWindowProc (TB_GETHOTIMAGELIST,0,0);<br />
HIMAGELIST m_hImageListGR = (HIMAGELIST)DefWindowProc (TB_GETDISABLEDIMAGELIST,0,0);<br />
and at the end on OnPaint() replace
<br />
if ( !IS_ENABLED(tbbutton) || (bOver && !bPressed) )<br />
{<br />
HICON hIcon = ImageList_ExtractIcon (NULL, m_hImageList, tbbutton.iBitmap);<br />
cDC.DrawState (CPoint (rcButton.left + ( bOver ? 4 : 3 ), rcButton.top + ( bOver ? 4 : 3 )), m_sizeImage, hIcon, DSS_MONO, CBrush (bOver ? (IS_INDETERMINATE(tbbutton) ? HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), -20, 0) : HLS_TRANSFORM (::GetSysColor (COLOR_HIGHLIGHT), +50, -66)) : HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), -27, 0)));<br />
DestroyIcon (hIcon);<br />
}<br />
if ( IS_ENABLED(tbbutton) )<br />
{<br />
::ImageList_Draw (m_hImageList, tbbutton.iBitmap, cDC.m_hDC,<br />
rcButton.left + ( (bOver && !bPressed) ? 2 : 3 ), rcButton.top + ( (bOver && !bPressed) ? 2 : 3 ), ILD_TRANSPARENT);<br />
}<br />
with
<br />
if ( !IS_ENABLED(tbbutton) || (bOver && !bPressed))<br />
{<br />
HICON hIcon = ImageList_ExtractIcon (NULL, (!IS_ENABLED(tbbutton)) ? m_hImageListGR : m_hImageListHT, tbbutton.iBitmap);<br />
cDC.DrawState (CPoint (rcButton.left + ( bOver ? 4 : 3 ), rcButton.top + ( bOver ? 4 : 3 )), m_sizeImage, hIcon, DSS_NORMAL,(CBrush*)NULL);<br />
DestroyIcon (hIcon);<br />
}<br />
else if ( IS_ENABLED(tbbutton) )<br />
{<br />
::ImageList_Draw (m_hImageListTC, tbbutton.iBitmap, cDC.m_hDC,<br />
rcButton.left + ( (bOver && !bPressed) ? 2 : 3 ), rcButton.top + ( (bOver && !bPressed) ? 2 : 3 ), ILD_TRANSPARENT);<br />
}<br />
That's it!
Greeting from Frank
|
|
|
|
|
When I run the demo on Windows 98 the menu bar items (File, Edit, etc.) are not highlighted as the mouse passes over them. Once you click on a menu to open it, everything is drawn correctly. This isn't a problem under Windows XP.
|
|
|
|
|
Indeed, this behavior is not available under Win98 and NT4. As these systems are now rather old, I do not project to implement it.
|
|
|
|
|
I like it~~ Thanks a lot
I am a student!
|
|
|
|
|
If run sdi-exe, he run minimized.
If run sdi(or mdi), then press preview, close preview. Appear small uncontrollable bar with undo & find.
|
|
|
|
|
It was an excellent article, mr. "Cought in the headlights" (your picture, i mean) , i'm definitely gonna use your code in my applications. I tried to write something like this long ago, but gave up in the end Instead, i wrote XP-Style menus which look like "Start" menu in Windows XP , when you can have two-three lines of text in just one menu item, and big beatiful icons 48x48;P. It's all here: www.tooltips.net
Thank you again for such excellent code
Cheers
Vitaly
|
|
|
|
|
When you're running WinXP with shadows enabled, you got two shadows, i'll see if i find a fix for this, but i think that it's easy to fix.
Good Work!!!!!!!!1
|
|
|
|
|
|
Easy to use , wonderful look and feeling.
tomPeakz
|
|
|
|
|
It integrated into my app very easy. and it has small footprint
Thanks
|
|
|
|
|
How can I change the color of the back ground of the menu?
|
|
|
|
|
I had trouble getting all levels of popups to be owner-drawn until I detached the HWND from the CMenu when attaching the popup, when the CMenu goes out of scope before calling TrackPopupMenu(). For example, this works:
CMenu subMenu;
(add to subMenu)
AppendMenu( MF_STRING | MF_POPUP, (UINT)subMenu.Detach(), title );
(subMenu goes out of scope before TrackPopupMenu is called on parent CMenu...)
and this does not:
AppendMenu( MF_STRING | MF_POPUP, (UINT)subMenu.m_hMenu, title );
Does anyone know if this approach leads to memory leaks? Probably eh? :> Silly standard menu doesn't complain about the second case at all, there must be some voodoo going on there... Guess I better add a CMenu std::vector...
Thanks again.
|
|
|
|
|
I just spent a whole day trying to get another implementation of owner-drawn menus up and running with our (granted, complex) existing menu code...
Finally gave up and switched to this. Dropped in the code as instructed, IN 1 MINUTE it was up, running, and looking GREAT! Thanks my man!
|
|
|
|
|
This project is awesome don't get me wrong, but I'm wondering...
the actual menu itself looks like menu, but the menu header ("File, Edit...etc") don't resemble an XP menu, I just noticed this as I was looking at Word 2002.
Just curious if this is something I am doing wrong or if it's hasn't been made yet.
|
|
|
|
|
The last version do it now !
|
|
|
|
|
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?
|
|
|
|
|