|
I too faced the same problem.
There is a simple work around. Just enter the ON_MENUXP_MESSAGES()
line after the text
//}}AFX_MSG_MAP
which is generated by the class wizard.
|
|
|
|
|
First of all, excellent job, looks great.
I'm having a problem getting the menu to show Bitmaps that are NOT also found in the toolbar which are picked automatically.
I am dynamically inserting Menu items at runtime using: AppendMenu
How do I now assign Bitmaps for each entry?
Have tried SetMenuItemBitmaps but has not worked, the function returns as successful, but no bitmaps are displayed.
Any help would be greatly appreciated.
Thanks,
John
|
|
|
|
|
My class is not designed to allow that.
I do not envisage to improve it for the moment.
You can try to add code in the painting function to retrieve your bitmap and use it instead of toolbar bitmaps.
|
|
|
|
|
At first, thank you for your effort.
But when I use this program, I have a problem.
I make a owner-drawn menu with DrawItem.
However, this is hooked all message, so that menu is not drawn..
I want some menu of mine to be NOT affected CMenuXP.
How??
Plz help me~
|
|
|
|
|
BOOL CMainFrame::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd* pParentWnd, CCreateContext* pContext)
{
if (!CFrameWnd::LoadFrame (nIDResource, dwDefaultStyle, pParentWnd, pContext) )
{
return false;
}
CMenuXP::UpdateMenuBar (this);
return true;
}
My code only work when i add this code on the function, because you only say about "CMenuXP::UpdateMenuBar (this);", and does not work whit this line only.
But it's the greatest and very simple code.... i haven't works to say TY!!!
REALLY KOOL!!!!!!!
|
|
|
|
|
You did a great job! But when I tried in dialog based application, it didn't work. Would you please give some suggestions?
|
|
|
|
|
You're wrong, it works:
1. Do the step LE FOL described in his article.
2. Create a menu resource
3. In your OnInitDialog() method of the main dialog, add the following code:
CMenu pMenu;<br />
pMenu.LoadMenu(YOUR_MENU_RES);<br />
SetMenu(&pMenu);<br />
pMenu.Detach();<br />
<br />
CMenuXP::SetXPLookNFeel(this, true);<br />
CMenuXP::UpdateMenuBar(this);
regards,
Happosai
------------------------------------
http://www.happosai.tk
|
|
|
|
|
|
Hi,
Thank you so much for your work. It is excellent under Windows 2000. But I just noticed that when i tried to run your demo(MDI for example) under Windows XP, the shadow effect looks just weird, something like double shadow...... Can you help me?
|
|
|
|
|
|
How would you take this code and make it work on an application that is already compiled, but can run dll exports and pass its hwnd? Is that even possible if it makes sence?
Would love to know how to do that
|
|
|
|
|
It should be possible by using the subclassing on the hwnd.
|
|
|
|
|
Thanks for replying, but i have no idea how to subclass hwnd If you could point me to an article on how to do that i would love it
|
|
|
|
|
i am a VB.Net coder. I found the vc++ files. I do not have any experience it them.
Can you help me, how to use them in my VB.code.
|
|
|
|
|
Hi. Just a small problem. I have implemented your code following exactly EACH step without forgotting anything in ChildFrm & MainFrm .cpp & .h files. When I run the sample without the ON_MENUXP_MESSAGES()in CMainFrm.cpp it works but the menus does not get the full XP-style. When I add ON_MENUXP_MESSAGES() in the CMainFrame message map, it hangs the software when I click a menu. I can't find the reason because I have watched your sample and I'm doing exactly the same.
The only major difference is that my application is of course more complex than your small dedicated sample and my CMainframe message map is bigger (see below):
My guess about this error is : would it be possible that the MenuXP hook function is also called for each CMainframe handled message and that some of my code can not be hooked by CMenuXP (because as you can see I am not only handling windows messages, but also some application specific messages) ??
If this is the reason, how can I determine for each CMainframe message implementation, if I am running a CMainframe message or a CMenu message ??
If not, do you have any idea of the problem ?
Many Thanks in advance for your lights about this
ON_WM_CREATE()
ON_WM_PALETTECHANGED()
ON_WM_QUERYNEWPALETTE()
ON_MESSAGE(WM_TRAYCALLBACK, OnTrayCallback)
ON_MESSAGE(WM_COMBOSEARCH, OnComboSearch)
ON_WM_WINDOWPOSCHANGED()
ON_WM_DESTROY()
ON_WM_CONTEXTMENU()
ON_WM_CLOSE()
ON_COMMAND(ID_VIEW_EDITBAR, OnViewEditbar)
ON_UPDATE_COMMAND_UI(ID_VIEW_EDITBAR, OnUpdateViewEditbar)
ON_COMMAND(ID_VIEW_ADVBAR, OnViewAdvBar)
ON_UPDATE_COMMAND_UI(ID_VIEW_ADVBAR, OnUpdateViewAdvBar)
ON_COMMAND(ID_UTIL_COLUM, OnUtilEditColumn)
ON_COMMAND(ID_UTIL_TYPE, OnUtilTypes)
ON_COMMAND(ID_VIEW_MENUBTN, OnViewMenuButtons)
ON_UPDATE_COMMAND_UI(ID_VIEW_MENUBTN, OnUpdateViewMenuButtons)
ON_COMMAND(ID_MEDIA_VIEW2, OnMediaViewInfoDlg)
ON_UPDATE_COMMAND_UI(ID_MEDIA_VIEW2, OnUpdateMediaInfoDlg)
ON_NOTIFY(TBN_DROPDOWN, AFX_IDW_TOOLBAR, OnToolbarDropDown)
ON_UPDATE_COMMAND_UI(ID_DROP_PRINT, OnUpdateDropPrint)
ON_COMMAND(ID_DROP_PRINT11, OnDropPrint11)
ON_COMMAND(ID_DROP_PRINT12, OnDropPrint12)
ON_COMMAND(ID_DROP_PRINT21, OnDropPrint21)
ON_COMMAND(ID_DROP_PRINT22, OnDropPrint22)
ON_COMMAND(ID_DROP_PRINT23, OnDropPrint23)
ON_COMMAND(ID_DROP_PRINT24, OnDropPrint24)
ON_COMMAND(ID_UTIL_RINFO, OnRestoreInfoDlg)
ON_COMMAND(ID_MEDIA_COPYIMG, OnMediaCopyImage)
ON_UPDATE_COMMAND_UI(ID_MEDIA_COPYIMG, OnUpdateMediaCopyImage)
ON_UPDATE_COMMAND_UI(ID_VIEW_ICONS3, OnUpdateDropView)
|
|
|
|
|
Sorry, my mistake ! this problem has been corrected, it was my fault. But I wanted to share the case here because it could also happen to other developers :
My application had already a menu hooking class designed to include icons within menus (icons stored in a dummy toolbar in project resources).
When I implemented the CMenuXP class in my code, I forgot to remove the previous hooking functions. So it seems that Windows or MFC could not support twice hooking, or maybe functions overlapped.
Anyway, that's the bottom line : do NOT forget to remove your previous menu hooking functions before setting this new one !
See ya.
|
|
|
|
|
Thanks for this great code that allows to implement XP style on Menus, but the interface like have some lacks if it can not be completed with a XP-style toolbar, with rounded buttons like in Internet Explorer 6 under Windows XP, see what I mean ?
Is a XP-style toolbar scheduled for design ?
Otherwise, does anyone here knows were such code can be found ?
Regards,
|
|
|
|
|
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
...
// Comment this line to deactivate the XP Look & Feel
CMenuXP::SetXPLookNFeel (this);
...
}
|
|
|
|
|
|
Congratulations, very good and useful article!
I suggest a little improvement regarding the usage of toolbars with more colors than by defalt.
I am using true colors toolbars. To get this functionality three bitmaps are to be provided - normal, disabled and hot version of toolbar images.
Since CMenuXP gets its images from the standard toolbar bitmap it can not take advantage of these true color bitmaps. However, with few simple changes this functionality can be achieved and still retain the normal behavior with simple toolbars.
Changes in MenuXP.h:
Change class CImgDesc into:
class CImgDesc
{
public:
HIMAGELIST m_hImgList;
HIMAGELIST m_hImgHotList;
HIMAGELIST m_hImgDisList;
int m_nIndex;
CImgDesc (HIMAGELIST hImgList = NULL, HIMAGELIST hImgHotList = NULL, HIMAGELIST hImgDisList = NULL, int nIndex = 0)
: m_hImgList (hImgList), m_hImgHotList (hImgHotList), m_hImgDisList (hImgDisList), m_nIndex (nIndex)
{
}
};
Changes in MenuXP.cpp:
Change drawing code in CMenuItem::Draw() to:
if ( GetDisabled() || (bSelected && !GetChecked()) )
{
if(m_ImgDesc.m_hImgDisList && GetDisabled())
::ImageList_Draw (m_ImgDesc.m_hImgDisList, m_ImgDesc.m_nIndex, pDC->m_hDC,
pRect->left+3, rc.top+3, ILD_TRANSPARENT);
else
{
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(m_ImgDesc.m_hImgHotList && bSelected)
::ImageList_Draw (m_ImgDesc.m_hImgHotList, m_ImgDesc.m_nIndex, pDC->m_hDC,
pRect->left+(!GetChecked()? 2 : 3 ), rc.top+(!GetChecked()? 2 : 3 ), ILD_TRANSPARENT);
else
::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);
}
Change reading of the images from the toolbar in CMenuXP::SetXPLookNFeel()
CImgDesc imgDesc ((HIMAGELIST)pBar->SendMessage (TB_GETIMAGELIST, 0, 0),
(HIMAGELIST)pBar->SendMessage (TB_GETHOTIMAGELIST, 0, 0),
(HIMAGELIST)pBar->SendMessage (TB_GETDISABLEDIMAGELIST, 0, 0),tbbi.iImage);
|
|
|
|
|
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.
|
|
|
|
|