 |
|
 |
I tested your menu. There is a problem with the background bitmap. You put the bitmap on a memory DC in SetBackBackground():
::SelectObject(m_memDC.m_hDC, m_hBitmap);
Now, suppose that I had one bitmap in my application, I want it loaded as background on the menu and it pop-ups. However, when I call again SetBackBackground() from the popup it do not work:
CMenuXP *pPopup = new CMenuXP;
pPopup->CreatePopupMenu();
pPopup->SetSelectedBarColor(RGB(0x66, 0x99, 0xff));
pPopup->SetBackBitmap((HBITMAP)bmp.m_hObject()); - will not work
I do not see the bitmap on the popups background! I need to open one and the same bimap several times for each popup which is too unhandy.
The solution is to move the code ::SelectObject(m_memDC.m_hDC, m_hBitmap); in DrawItem() and to select/unselect the background bitmap ach time you draw menu item, something like that:
void CMenuXP::DrawItem( LPDRAWITEMSTRUCT lpds )
{
.................
HBITMAP hbmOld = NULL ;
if(m_hBitmap)
{
m_memDC.CreateCompatibleDC(&dc);
HBITMAP hbmOld = (HBITMAP)SelectObject(m_memDC.m_hDC, m_hBitmap);
if(lpds->itemID == 1000 || lpds->itemID == 1001 || lpds->itemID == 1002)
TRACE("Select: \n"
}
..................
if(m_hBitmap)
{
SelectObject(m_memDC.m_hDC, hbmOld);
// TRACE("Unselect\n");
m_memDC.DeleteDC();
}
dc.Detach();
}
I tested this and it works. It maybe needs a little optimization. Anyway I don't see reason why the bitmap should stay on the DC all the time.
tonim
|
|
|
|
 |
|
 |
I've added the DrawItem() and MeasureItem() message handlers to the CXXDlg,and tray message hander like this
LONG CXXDlg::OnTrayNotification(WPARAM wparam, LPARAM lparam)
{
switch ( lparam )// The tray icon sent us a message. Let's see what it is
{
/*case WM_CONTEXTMENU:
TRACE( "WM_CONTEXTMENU\n" );*/
case WM_RBUTTONDOWN:
{
CPoint oPoint;
GetCursorPos( &oPoint );
SetForegroundWindow();
CMenuXP *pMenu = new CMenuXP;
CreatePopupMenu();
SetMenuStyle(CMenuXP::STYLE_XP);
pMenSetBackColor(RGB(230,246,254));
pMenSetSelectedBarColor(RGB(53, 196, 240));
SetSideBarStartColor(RGB(0,0,255));
SetSideBarEndColor(RGB(0,0,255));
AddSideBar(new CMenuXPSideBar(30, " ETCall"));
AppendODMenu2(0, new CMenuXPText(9, " OnLine", m_hOnLine));
AppendODMenu2(0, new CMenuXPText(10, " Qme", m_hQme));
AppendODMenu2(0, new CMenuXPText(11, " Away",m_hAway));
AppendODMenu2(0, new CMenuXPText(19, " Busy",m_hBusy));
AppendODMenu2(0, new CMenuXPText(19, " NoBother",m_hNoBother));
AppendODMenu2(0, new CMenuXPText(13, " Hide",m_hHide));
AppendODMenu2(0, new CMenuXPText(14, " Exit",m_hExit));
SetDefaultItem(12);
pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, oPoint.x, oPoint.y, this);
delete pMenu;
}
break;
//
case WM_LBUTTONDBLCLK:
case WM_LBUTTONDOWN:
OnMenuitemShow();
break;!!
}
return 0;
}
the first time ,icons show correct,but when the tray show again,the icons don't show anymore!
|
|
|
|
 |
|
 |
I tested it and I really like it. Great work!!!
|
|
|
|
 |
|
 |
hi
sreenivas003@yahoo.co.in
|
|
|
|
 |
|
 |
just blank when i click woodtray icon.
but i can used in the dialog.
maybe there is some error of the way i use it.
can u give me some suggestion?
raulshao@gmail.com
|
|
|
|
 |
|
 |
Hi Neil, thank you very much for your nice menu. I am using it and find it work well except that when there is only one menu item in the menu, the width of sidebar is not calculated correctly. I find the width of sidebar will be the same as the one of first (and only) menu item. If I do not set a sidebar or add another menu item in, the width of sidebar will be OK.
I have tested you demo project under VC2002. It works perfectly. But if I remove all the menu items and keep only one left, the width of sidebar is incorrect as well.
I have traced the source code and I found the size is correct in MeasureItem(), but incorrect in DrawItem(). I tried to force the size of sidebar to be "pItem->m_nSize" in DrawItem(). Then the width of sidebar can be fixed, but the others parts are still on their original incorrect position. There is a gray (back color) area between the side bar and the first menu item.
Although this is not a serious problem, but I hope you can give me some advice to fix it if you have time.
Thank in advance.
Frank Jiang
|
|
|
|
 |
|
 |
怎样实现基于对话框的菜单建立并具有xp style.
Lee 李兵(苏州)
|
|
|
|
 |
|
 |
Thanks for this excellent article.
How To change menu font (font of menu and submenu items) at runtime ?
Is it possible ? How to implement it ?
BCGControlBar library has somehow implemented it (but that library is too expensive for
small project)
Any idea or direction ?
Ana
Ana_v123
|
|
|
|
 |
|
 |
Am I missing something? I tried building your demo program on winDoze 2000 advanced server, using VC++ 6, and got nothing but stock menus when I ran the demo program.
Also, I noticed there are things missing from the ZIP file that the project thinks are part of it, e.g. ReadMe.txt and res\beauty.BMP that I noticed.
|
|
|
|
 |
|
 |
Hello!
plz help me how to disable popup menu items at any time.
for example i wana disable IDD_FILE_NEW until user closes the current window .
Me waiting for ur reply.
with regards.
|
|
|
|
 |
|
 |
The height and width are not calculated correctly, if at all, for popup items.
The unknown WM_MEASUREITEM for menu item messages are coming from the popup menu items.
|
|
|
|
 |
|
 |
Hi,
I needed to be able to change the text
on the items in my menu so I added the following to your class. Plus, I wanted to have custom checkmarks using Icons and here is the code I came with:
in MenuXP.h add:
public:
void SetCheckStyle(long lIconChecked, long lIconUnchecked);
void SetItemCheck(long lItemID, bool bChecked = true);
void SetItemText(long lItemID, CString strText);
private:
long m_lIconChecked;
long m_lIconUnchecked;
in MenuXP.cpp
1. in the constructor initialize both longs to -1
2. add the following at the end
void CMenuXP::SetCheckStyle(long lIconChecked, long lIconUnchecked)
{
m_lIconChecked = lIconChecked;
m_lIconUnchecked = lIconUnchecked;
}
void CMenuXP::SetItemCheck(long lItemID, bool bChecked)
{
MENUITEMINFO itemInfo;
ZeroMemory(&itemInfo, sizeof(MENUITEMINFO));
itemInfo.cbSize = sizeof(MENUITEMINFO);
itemInfo.fMask = MIIM_DATA | MIIM_STATE;
GetMenuItemInfo(lItemID, &itemInfo, FALSE);
CMenuXPItem* pItem = (CMenuXPItem*)itemInfo.dwItemData;
if (bChecked && m_lIconChecked != -1)
{
pItem->m_hIcon = AfxGetApp()->LoadIcon(m_lIconChecked);
}
else if (bChecked)
{
itemInfo.fState |= MFS_CHECKED;
}
else if (!bChecked && m_lIconUnchecked != -1)
{
pItem->m_hIcon = AfxGetApp()->LoadIcon(m_lIconUnchecked);
}
else if (!bChecked)
{
itemInfo.fState &= ~MFS_CHECKED;
}
SetMenuItemInfo(GetSafeHmenu(), lItemID, FALSE, &itemInfo);
GetMenuItemInfo(lItemID, &itemInfo, FALSE);
}
void CMenuXP::SetItemText(long lItemID, CString strText)
{
MENUITEMINFO itemInfo;
ZeroMemory(&itemInfo, sizeof(MENUITEMINFO));
itemInfo.cbSize = sizeof(MENUITEMINFO);
itemInfo.fMask = MIIM_DATA;
GetMenuItemInfo(lItemID, &itemInfo, FALSE);
CMenuXPItem* pItem = (CMenuXPItem*)itemInfo.dwItemData;
pItem->m_strText = strText;
SetMenuItemInfo(GetSafeHmenu(), lItemID, FALSE, &itemInfo);
}
hope this helps others
Alexandre Senechal, ing. jr
Programmer
Optifor inc.
|
|
|
|
 |
|
 |
Hi, your code is great but I get a strange behavior
on NT4. I am building a tray app. (Without the CSystemTray class).
When I display the menu, the first time everything
is fine. But once I used any of the Items in it, the next time it is displayed it is not in the right place.
I mean, using the TPM_RIGHTALIGN flag, should place the bottom-right corner on the mouse tip which is the case for the first display. The next ones, it is incorrect and more on the verge of the left edge lined up with the mouse tip. This causes the menu to be partially visible and is very annoying.
I believe there is some problem in the DrawItem()/ MeasureItem() code, but I did not take time to look further into it. I will, but I also wanted to know if others had the same problem or a very similar.
thanks.
Alexandre Senechal, ing. jr
Programmer
Optifor inc.
|
|
|
|
 |
|
 |
A tray app might bring unnecessarily complexity. You could try to use a normal menu, get it work, then replace it by using this menu.
I have not used this menu class in a tray app by myself, but I do know somebody else did it, and it work well.
|
|
|
|
 |
|
 |
Dear Sir,
Can this be converted into an active x control so that can be used by any application (C#,VB.Net for example)
Regards,
Rahul.
|
|
|
|
 |
|
 |
It is possible but I have no time to do it recently. And I will not courage you to do this for use in .net world. Instead, you may rewrite it in C#, or maybe I will do it someday.
|
|
|
|
 |
|
 |
Dear Sir,
Thanks for your kind reply. The problem with C# is the owner drawn menu created there flickers' in windows xp ( not sure about win 2003 server) and hence causes lot of in convinience to users.
Thanks again for a reply!
Regards,
Rahul
|
|
|
|
 |
|
 |
May I suggest you to modify CMenuXP::CMenuXP() in order to get the sidebar colored as XP start menu?
...
//initialize sidebar colors
m_clrSideBarStart = RGB(0, 0, 192);
m_clrSideBarEnd = RGB(0, 0, 0);
if(::GetVersion()>= 0x0501)
{
m_clrSideBarStart = ::GetSysColor(COLOR_MENUHILIGHT);
}
...
bye
|
|
|
|
 |
|
 |
I'm using your CMenuXp for a popup. I use ::ExtractAssociatedIcon to extract the icons.
But I got only 256 colored icons.
Do I miss something?
Thanks for you source code.
|
|
|
|
 |
|
 |
I don't know why. You may try to add a normal icon rather than to load using ::ExtractAssociatedIcon. So you can determine if it's the function ExtractAssociatedIcon causing it or not.
|
|
|
|
 |
 | SideBar  |  | trudy_la_fee | 2:47 20 Aug '03 |
|
 |
Hi,
It's me AGAIN!
Sorry but I use Visual C++ for only a few weeks so I am not very good. That is the erason for all my questions....
I was just wondering if it was possible to have the sidebar on the top. Let's call it a TopBar then
I have looked into the code but I haven't found a way to do it.
But, I noticed that the font and size of the sidebar did not change with windows settings or the menu setting and I changed that so if anyone is interrested I car give the code.
Also, the background of the check (for a checked item) has the color of windows background and not of the background of the menu ( if it has been changed)
Thank you
|
|
|
|
 |
|
 |
A topbar is possible. It will be a little easier than to implement a sidebar. But it is not supported directly here. You may try to do it by yourself.
|
|
|
|
 |
|
 |
Hello,
I am using this class to make a beautifull dynamic menu. It works great but I just have one question about the WM_MEASUREITEM message.
I am using a dialog base application. I added the code you told in the handle of this message but when I am degugging it says :
"Warning: unknown WM_MEASUREITEM for menu item 0x7602C3."
If I remove the WM_MEASUREITEM handle it also works.
So is the WM_MEASUREITEM handle necessary or have I done something wrong?
|
|
|
|
 |
|
 |
Actually I'm not sure how MFC handle the WM_MEASUREITEM message. I think the warning is due to some mistake in your code. But if it works when you remove the handler. That's fine, isn't it;P
|
|
|
|
 |
|
 |
I noticed today that even if I remove the handle of the WM_MEASUREITEM message I get the same warning....
My program works, so it's ok but I believe it's not normal....
|
|
|
|
 |