|
and the color of the menu?
|
|
|
|
|
Great Project.
I implemented your menu in one of my program an it works without Icons. I would like to have some Icons.
My project has no toolbar showed and I don't know how to resolve it.
Can someone help me.
thx for helping
Pascal
|
|
|
|
|
Creating toolbar and to disable it.
Steps:
1. Insert new resource toolbar
2. Add any icons to toolbar
3. In CMainFrame.cpp:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
/*... something ...*/
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
}
// IMPORTANT!!! After creating toolbar to disable it
ShowControlBar (&m_wndToolBar, FALSE, TRUE);
/*... something ...*/
}
May be exist another ways...
Simvolokov Michael
|
|
|
|
|
Great program!I want to use this in dialog.
but I can't add icon in it conventially.
can you give me some adise ,Sir?
|
|
|
|
|
Great job! For anyone elses knowledge, if you are using the statusbar component which adds the current system date and time to the statusbar, you might have some code conflicts.
|
|
|
|
|
Overall I would say this is excellent, and is easy to integrate
Four suggestions for improvements (or questions):
1. What about the system menu?
2. What about handling if the toolbar is (slightly) not standard size? Maybe there could be a function to pass a menu-only toolbar bitmap with normal sized buttons to the menu code, even if the app's actual toolbar is not the standard button size.
3. Radio marks on menus show as checks, not dots
4. Is there a way to use the same underlying code to use on popup menus? (you know ones we create with TrackPopupMenu when a user right clicks on an item or something)
|
|
|
|
|
For the 4th point, it should work in the demo !?!
|
|
|
|
|
Thanks
I just stuck a copy of your code (without even looking at the sample) in 2 programs I had handy to see if it worked. These both have multiple popups and it didn't work on any of these popups. They just came up as normal popups.
I took a look at your sample, and yes it works on that.
There are 2 differences I think in the 2 programs I tried it on:
1. Build their popup menus on the fly, using AppendMenu etc
2. TPM_RETURNCMD in the popup code.
I haven't yet tested this out at all, and may not for some time, but my guess is TPM_RETURNCMD is the problem.
To be fair this is not really a weakness of your code, but it does mean it's not quite a drop in replacement.
|
|
|
|
|
Look at the 4th parameter of the TrackPopupMenu call:
pPopup->TrackPopupMenu (TPM_RIGHTBUTTON, pt.x, pt.y, GetParentFrame()); In my demo, this is the frame.
The window passed as 4th parameter must handle the MENUXP macros: ON_MENUXP_MESSAGES, DECLARE_MENUXP and IMPLEMENT_MENUXP.
Add them in your programs and it should work !
Bye
|
|
|
|
|
I did already and it didn't make a difference.
The problem seems to be the TrackPopupMenu call had TPM_NONOTIFY flag set
Removing this flag fixes the problem with display (tried on only 1 menu so far). However this then causes a knock on problem as the menu items are now all disabled, presumably because there is no code to handle the pCmdUI->Enable(...) etc stuff for these items.
So I know how to fix it in that program, but unless there is a trick I'm not aware of, it would be a fairly major job as it requires turning the code around: instead of building a popup with the right items enabled/disabled, I think that I would need to move move the enable/disable logic into separate handlers, and decide about each menu item, after the menu has been built rather than before.
|
|
|
|
|
a little impovement for MDI with multiple documents:
Change CMenuXP class in:
class CMenuXP : public CMenu
{
// Attributes
public:
static CMap <int, int, CString, CString&> m_sCaptions;
static CMap <int, int, CImgDesc, CImgDesc&> m_Images;
// Operations
public:
static void SetWinXPStyle (HMENU hMenu, CWnd* pWnd = NULL);
static bool IsOwnerDrawn (HMENU hMenu);
static void OnMeasureItem (MEASUREITEMSTRUCT* pMeasureItemStruct);
static void OnDrawItem (DRAWITEMSTRUCT* pDrawItemStruct);
static LRESULT OnMenuChar (HMENU hMenu, UINT nChar, UINT nFlags);
protected:
//
// new code !
//
static CImageList m_ImageList;
//
static int AddImage(HIMAGELIST hSourceImgList,int sourceImageIndex);
//
// end new code...
//
};
add in menuxp.cpp
CMap <int, int, CString, CString&> CMenuXP::m_sCaptions;
CMap <int, int, CImgDesc, CImgDesc&> CMenuXP::m_Images;
CImageList CMenuXP::m_ImageList; // new initialization
int CMenuXP::AddImage(HIMAGELIST hSourceImgList,int sourceImageIndex)
{
int index=-1;
//
if( hSourceImgList && sourceImageIndex > -1 ){
HICON hIcon = ::ImageList_ExtractIcon(
NULL ,
hSourceImgList ,
sourceImageIndex );
if( hIcon ){
//
if( CMenuXP::m_ImageList.m_hImageList == NULL )
CMenuXP::m_ImageList.Create(16 , // cx,
16 , // cy,
ILC_MASK , // nFlags,
0 , // int nInitial,
16 ); // grow...
//
if( CMenuXP::m_ImageList.m_hImageList != NULL ){
index=m_ImageList.GetImageCount();
CMenuXP::m_ImageList.Add(hIcon);
}
::DestroyIcon(hIcon);
}
}
return index;
}
and in the function SetWinXPStyle sostitute:
//
//----------- Previus code:
//
// CImgDesc imgDesc (
// (HIMAGELIST)pBar->SendMessage (TB_GETIMAGELIST, 0, 0), tbbi.iImage);
// m_Images.SetAt (mii.wID, imgDesc);
//
// ---------- New code...
//
if( (nMyImageIndex=AddImage(
(HIMAGELIST)pBar->SendMessage(TB_GETIMAGELIST, 0, 0),
tbbi.iImage)) > -1 ){
CImgDesc imgDesc(CMenuXP::m_ImageList.m_hImageList,nMyImageIndex);
m_Images.SetAt( mii.wID, imgDesc );
}
break;
In this way if you destroy some toolbars etc.. at runtime the image is correct..
Sorry for my poor english and thanks for your job
|
|
|
|
|
Hello!
This class is really cool and so easy to use! But there's one thing I'm missing. The original office xp menus have this blue border if you move your mouse over the menu. This class (http://www.codeproject.com/menu/shadowmenu.asp) has that effect.
I would be really gratefull if you could include this feature.
Bye,
Gertschi
|
|
|
|
|
|
I'm using 32x32 icons in my toolbar, and they appear in the same size in Menu. How can I fix it? I want them in smaller size.
|
|
|
|
|
Try that:
....
if ( m_ImgDesc.m_hImgList != NULL && m_ImgDesc.m_nIndex != -1 )
{
bool bOver = !GetDisabled() && bSelected;
bool bDontUseImage = FALSE;
int cx, cy;
if(ImageList_GetIconSize(m_ImgDesc.m_hImgList, &cx, &cy))
{
bDontUseImage = (cy > IMGHEIGHT) || (cx > IMGWIDTH);
}
if(!bDontUseImage) // we have small Icons in Image list => do it faster and cleaner
{
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() )
{
::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
{
HICON hIcon = ImageList_ExtractIcon (NULL, m_ImgDesc.m_hImgList, m_ImgDesc.m_nIndex);
if ( GetDisabled() || (bSelected && !GetChecked()) )
{
DrawIconEx( pDC->m_hDC,
pRect->left + ( bOver ? 4 : 3 ),
rc.top + ( bOver ? 4 : 3 ),
hIcon,
16, 16,
0,
NULL,
DI_NORMAL );
}
if ( !GetDisabled() )
{
DrawIconEx( pDC->m_hDC,
pRect->left+( (bSelected && !GetChecked()) ? 2 : 3 ),
rc.top+( (bSelected && !GetChecked()) ? 2 : 3 ),
hIcon,
16, 16,
0,
NULL,
DI_NORMAL );
}
DestroyIcon (hIcon);
}
}
....
|
|
|
|
|
That's right, but, in order to avoid image stretching another posibility is to change the size of the displayed images to match those from the toolbar. This can be done easily modifying the function:
static void SetWinXPStyle (HMENU hMenu, CWnd* pWnd = NULL);
To:
static void SetWinXPStyle (HMENU hMenu, CWnd* pWnd = NULL, imgWidth = 16, int imgHeight = 16);
Then, declare two additional static members and initialize them inside SetWinXPStyle:
// Attributes
public:
static CMap <int, int, CString, CString&> m_sCaptions;
static CMap <int, int, CImgDesc, CImgDesc&> m_Images;
static int m_imgWidth; // <-- new one
static int m_imgHeight; // <-- new one
void CMenuXP::SetWinXPStyle (HMENU hMenu, CWnd* pWnd, int imgWidth /*16*/, int imgHeight /*16*/)
{
m_imgWidth = imgWidth;
m_imgHeight = imgHeight;
// etc...
}
After it, delete IMGWIDTH/IMGHEIGHT definitions in CPP file and replace it by CMenuXP::m_imgWidth/m_imgHeight. Finally, in your CMainFrm::OnCreate (or wherever you initialize the menu) call CMenuXP::SetWinXPStyle() with the appropiate width/height of the buttons.
Perhaps 32x32 buttons cause a excessively height menu items, but in 21x20 buttons (my case) it looks fine, very much better than stretching them.
Eduard Huguet (eduard@cibercat.es)
Cibercat SL
|
|
|
|
|
This is surely a awesome work .
what I want to know is that is it possible to draw in Menu bar area als0 ??
that is can I give it a look some what similar to OfficeXp products ??
I know if we implement it as toolbar instead of menubar then we can do that ..
but you get my question ??
Regards,
Abhishek Narula
"Learn to appreciate others ... World would appreciate you"
|
|
|
|
|
This is harder than it first appears. While Windows does allow a programmer to create custom-drawn menus, the bar itself cannot be changed. The menu bar is considered to be a part of the non-client area. A simple test is to start the Windows Notepad, and then use Spy++ to observe what windows are available for selection.
Menus are not created through the "CreateWindow" and "CreateWindowEx" API functions. Rather, there is a separate "CreateMenu" function, specifically for this purpose.
The simplest solution to the problem is create the menu in a toolbar control, where you can use owner-draw code across the entire control. If you do not want to use a toolbar control at all, you would have to implement a menu system from scratch, and then figure out how to attach it to the main window in a way that would keep it out of the client area, and be relatively transparent to the application, unless you don't mind handling custom messages.
--
Paul
"I drank... WHAT?"
|
|
|
|
|
|
This new version is more robust and easier to use.
Have fun with it !
|
|
|
|
|
|
|
And when are we gonna see it?
|
|
|
|
|
|
This doesn't work at all if you dissect the project.
Try taking MenuXP.cpp/.h and doing anything with it ... the class is not standalone. I tried grabbing all the classes from the Tools directory, but there are classes defined within the UI code that are required. There is no flexibility built into your code ... outside of your test app it is unusable.
I look forward to seeing your next version. Keep at it, this could be really good ...
Jase
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
View your digital photos and images with ease using the ultimate desktop image manager for Microsoft Windows
Download your free copy of SlideShow Desktop today from http://www.slideshowdesktop.com
|
|
|
|
|