|
The submenu arrows are drawn by the system/menu/Windows (whatever you want to call it). There is a way you can draw it yourself and stop the system from drawing it. Basically, you have to add code to your OnDrawItem function to draw the arrow when needed, then call ExcludeClipRect with the rect where the arrow shows up to stop the system from drawing it. I've done this in my modified version of CMenuXP. Let me know if you are interested.
-Frank
|
|
|
|
|
Good site, good member!
by scroll_lock
of Brazil
|
|
|
|
|
I'm using dialog based application. Till now i can change state to ENABLED or GRAYED by using MFS_ENABLED and MFS_GRAYED. (i was tryin with MF_GRAYED but no effect). However MFS_CHECKED AND MFS_RADIOCHECK have no effect using this code. I don't understand why?
CWnd* pWnd = AfxGetMainWnd();
CMenu *pMenu = pWnd->GetMenu();
pMenu->EnableMenuItem ( ID_MODE_BLACKNWHITE,MFS_CHECKED);
I do check item but using Visual Property Form Pls help
|
|
|
|
|
I am seeing on Win2k where a faint image of the selected menu option is left on the screen if I select a menu option and move the cursor immediately after the selection. I don't see the problem on XP. Has anyone seen this problem? Is there a fix?
|
|
|
|
|
How may I have CheckBox and RadioButton looking as nice as XP Button object?
|
|
|
|
|
I still seem to have problems with this. I did see in a couple of comments from the author that this has been taken care of in the latest fix.
But I am working in W2K, compiling in .NET VS but I am still not able to get the (File, Edit...) Menu headers to be highlighted in the blue box as in XP products...
Please tell me what I am doing wrong here.
Tons of thanks to this code....
Mike
Austin
|
|
|
|
|
|
Its not clear what you ask to do.Can you please explain in bit detail?It will be quite helpful.
|
|
|
|
|
I have included the changed source from menuxp.h.
Notice the FrameRect and FillRect replacement for Rectangle. Just search your code for 'Rectangle(' and replace that section with the one from this file.
Smae enhancements regarding Multi MRU Support and Office2003 Look-N-Feel have been excluded to eliminate confusion.
Let me know if there is a better way to comunicate the change.
LRESULT OnCustomDraw (int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
{
TCHAR sClass[128];
GetClassName (pnmh->hwndFrom, sClass, 128);
if ( _tcscmp (sClass, _T("WTL_CommandBarXP")) )
{
return CDRF_DODEFAULT;
}
NMCUSTOMDRAW* pCustomDraw = (NMCUSTOMDRAW*)pnmh;
if ( pCustomDraw->dwDrawStage == CDDS_PREPAINT )
{
// Request prepaint notifications for each item
return CDRF_NOTIFYITEMDRAW;
}
if ( pCustomDraw->dwDrawStage == CDDS_ITEMPREPAINT )
{
CDCHandle dc (pCustomDraw->hdc);
CRect rc = pCustomDraw->rc;
TCHAR sBtnText[128];
//[kwh] Mimiced base class for getting text
//
//::SendMessage (pnmh->hwndFrom, TB_GETBUTTONTEXT, pCustomDraw->dwItemSpec, (LPARAM)sBtnText);
TBBUTTONINFO tbbi;
tbbi.cbSize = sizeof(TBBUTTONINFO);
tbbi.dwMask = TBIF_TEXT;
tbbi.pszText = sBtnText;
tbbi.cchText = sizeof(sBtnText) / sizeof(TCHAR);
GetButtonInfo((int)pCustomDraw->dwItemSpec, &tbbi);
if ( pCustomDraw->uItemState & CDIS_HOT )
{
COLORREF crHighLight = ::GetSysColor (COLOR_HIGHLIGHT);
CBrush brush, brushFrame;
brush.CreateSolidBrush ((pCustomDraw->uItemState & CDIS_SELECTED) ? HLS_TRANSFORM (crHighLight, +50, -50) : HLS_TRANSFORM (crHighLight, +70, -57));
brushFrame.CreateSolidBrush (crHighLight);
dc.FillRect(&rc, brush);
dc.FrameRect(&rc, brushFrame);
dc.SetTextColor ( (pCustomDraw->uItemState & CDIS_SELECTED) ? ::GetSysColor (COLOR_HIGHLIGHTTEXT) : RGB(0,0,0) );
}
else
{
// dc.FillSolidRect (rc, HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), +20, 0));
dc.FillSolidRect (rc, ::GetSysColor (COLOR_3DFACE));
dc.SetTextColor ( ::GetSysColor (m_bParentActive ? COLOR_BTNTEXT : COLOR_3DSHADOW) );
}
dc.SetBkMode (TRANSPARENT);
HFONT hOldFont = dc.SelectFont ((HFONT)GetStockObject (DEFAULT_GUI_FONT));
dc.DrawText (sBtnText, _tcslen (sBtnText), rc, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
dc.SelectFont(hOldFont);
return CDRF_SKIPDEFAULT;
}
bHandled = FALSE;
return CDRF_DODEFAULT;
}
#define IMGPADDING 6
#define TEXTPADDING 8
// From <winuser.h>
#define OBM_CHECK 32760
void DrawItem (LPDRAWITEMSTRUCT lpDrawItemStruct)
{
_MenuItemData* pmd = (_MenuItemData*)lpDrawItemStruct->itemData;
const RECT& rcItem = lpDrawItemStruct->rcItem;
CDCHandle dc = lpDrawItemStruct->hDC;
const BOOL bDisabled = lpDrawItemStruct->itemState & ODS_GRAYED;
const BOOL bSelected = lpDrawItemStruct->itemState & ODS_SELECTED;
const BOOL bChecked = lpDrawItemStruct->itemState & ODS_CHECKED;
const COLORREF clrFace = HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), +75, 0);
COLORREF crBackImg = CLR_NONE;
const COLORREF crHighLight = ::GetSysColor (COLOR_HIGHLIGHT);
CRect rc (rcItem);
rc.right = m_szBitmap.cx+IMGPADDING;
crBackImg = HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), +20, 0);
dc.FillSolidRect (rc, crBackImg);
rc.left = rc.right;
rc.right = rcItem.right;
dc.FillSolidRect (rc, clrFace);
if ( bSelected )
{
crBackImg = bDisabled ? HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), +73, 0) : HLS_TRANSFORM (crHighLight, +70, -57);
CBrush brush, brushFrame;
brush.CreateSolidBrush (crBackImg);
brushFrame.CreateSolidBrush (crHighLight);
dc.FillRect(&rcItem, brush);
dc.FrameRect(&rcItem, brushFrame);
}
if ( pmd->fType & MFT_SEPARATOR )
{
CPenDC pen (dc, HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), -18, 0));
dc.MoveTo (rcItem.left+m_szBitmap.cx+IMGPADDING+TEXTPADDING, (rcItem.top+rcItem.bottom)/2);
dc.LineTo (rcItem.right-1, (rcItem.top+rcItem.bottom)/2);
}
else
{
CRect rc (rcItem);
LPTSTR pszTab = _tcschr(pmd->lpstrText,_T('\t'));
TCHAR szCaption[200];
if ( pszTab)
{
*pszTab = _T('\0');
_tcscpy(szCaption, pmd->lpstrText);
*pszTab = _T('\t');
}
else
{
_tcscpy(szCaption, pmd->lpstrText);
}
dc.SetTextColor (bDisabled ? HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), -18, 0) : ::GetSysColor (COLOR_MENUTEXT));
dc.SetBkMode (TRANSPARENT);
CBoldDC bold (dc, (lpDrawItemStruct->itemState & ODS_DEFAULT) != 0);
rc.left = m_szBitmap.cx+IMGPADDING+TEXTPADDING;
dc.DrawText (szCaption, _tcslen(szCaption), rc, DT_SINGLELINE|DT_VCENTER|DT_LEFT);
if ( pszTab )
{
pszTab = CharNext(pszTab);
rc.right -= TEXTPADDING+4;
dc.DrawText (pszTab, _tcslen (pszTab), rc, DT_SINGLELINE|DT_VCENTER|DT_RIGHT);
}
if ( bChecked )
{
CBrush brush, brushFrame;
brush.CreateSolidBrush (crBackImg = bDisabled ? HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), +73, 0) :
(bSelected ? HLS_TRANSFORM (crHighLight, +50, -50) : HLS_TRANSFORM (crHighLight, +70, -57)));
brushFrame.CreateSolidBrush (crHighLight);
CRect rc (rcItem.left+1, rcItem.top+1, rcItem.left+m_szButton.cx-2, rcItem.bottom-1);
dc.FillRect(&rc, brush);
dc.FrameRect(&rc, brushFrame);
}
if ( m_hImageList != NULL && pmd->iButton != -1 )
{
bool bOver = !bDisabled && bSelected;
if ( bDisabled || (bSelected && !bChecked) )
{
HICON hIcon = ImageList_ExtractIcon (NULL, m_hImageList, pmd->iButton);
CBrush brush;
brush.CreateSolidBrush (bOver ? HLS_TRANSFORM (::GetSysColor (COLOR_HIGHLIGHT), +50, -66) : HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), -27, 0));
dc.DrawState (CPoint (rcItem.left + ( bOver ? 4 : 3 ), rc.top + ( bOver ? 5 : 4 )),
CSize (m_szBitmap.cx, m_szBitmap.cx), hIcon, DSS_MONO, brush);
DestroyIcon (hIcon);
}
if ( !bDisabled )
{
::ImageList_Draw (m_hImageList, pmd->iButton, dc.m_hDC,
rcItem.left+( (bSelected && !bChecked) ? 2 : 3 ), rc.top+( (bSelected && !bChecked) ? 3 : 4 ), ILD_TRANSPARENT);
}
}
else if ( bChecked )
{
// Draw the check mark
rc.left = rcItem.left+5;
rc.right = rc.left + m_szBitmap.cx + IMGPADDING;
dc.SetBkColor (crBackImg);
HBITMAP hBmp = LoadBitmap (NULL, MAKEINTRESOURCE(OBM_CHECK));
dc.DrawState (CPoint (rc.left,rc.top+3), CSize(rc.Size()), hBmp, DSS_NORMAL, (HBRUSH)NULL);
DeleteObject (hBmp);
}
}
}
Ken
|
|
|
|
|
Hi Ken,
The problem is,I can download the sample project,build and run it successfully.But when I add the MenuXP to my project it doesnt work.I have followed all the steps as mentioned on the web page.
Thanks a lot.
|
|
|
|
|
I have found 2 problems.
The first problem is when you use MenuXP with an Windows Skin (like WindowBlinds), then the menu looks sometimes (depending on the theme) a little bit ugly.
But a real problem is when you open the context menu on the taskbar of the menu xp app. Then some other application (like Windows Explorer) doesn't show the context menu in the taskbar anymore. The opera browser chrashes after that with an fatal error. There seems to be a real problem!
I have WinNT 4.0 installed, I've tested it with XP and there's no problem.
If you have an proposal for solving this error, please tell me.
thx & cu
Eric
|
|
|
|
|
I've discovered a problem with MenuXP that seems to be an incompatibility with the CComboBox::GetLBText function. If the CComboBox that GetLBText is used on has items that are very long (>1024 characters), an application that uses MenuXP will crash when GetLBText is called.
The last application function that is on the stack is CWndMenuXP::WindowsHook and indeed by removing the call to CMenuXP::InitializeHook the crash is resolved.
I realize this is a very strange report, but I would appreciate any suggestions.
|
|
|
|
|
Just an update, the only resolution I still have is removing the call to InitializeHook().
|
|
|
|
|
There are a couple of improvements that I think need to be made to this code:
1 - The system menu does not appear like the normal system menu, that is the restore, minimize, maximize items have icons instead of icons and captions.
2 - When the toolbar is floating it has the mini-frame window appearence instead of the flat frame appearence like the other XP sytle controls.
Other than this I like this code and simplicity to change the drawing...making it easy to change the appearence to the new Office 03 style (hint hint)
|
|
|
|
|
Good idea...ähemm I would like to get point 2, too...
|
|
|
|
|
As far as requested improvement 1, I had pretty good sucess with adding:
CMenu* pmSystem = GetSystemMenu(FALSE); CMenuXP::SetXPLookNFeel(this,pmSystem->GetSafeHmenu());
To CMainFrame::LoadFrame of my SDI App.
Thanks for a great job,
Larry
|
|
|
|
|
I've inserted your code into my app. Perfect! But if I hover the mouse over a toolbar button, the button is not highlighted. I've found out (up to now), that there is no WM_PAINT generated at mouse hit. Your MDI-sample does (on my XP system, on a w2k system it does not,too). Any ideas?
|
|
|
|
|
Did you add the tbs_flat style ?
|
|
|
|
|
Thanks for answering so fast.
I've tried several modifications. All of them are working ok using your MDI sample on XP, including this one:
if (!m_wndToolBar.Create(this, WS_CHILD | WS_VISIBLE | CBRS_TOP)
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
Isn't it curious?
But my app does not work and on W2k even your MDI sample does not work.
This is the call stack, setting a breakpoint for bover inside ToolbarXP:
CToolBarXP::OnPaint() line 251
CWnd::OnWndMsg(unsigned int 15, unsigned int 0, long 0, long * 0x0012fc14) line 1825
CWnd::WindowProc(unsigned int 15, unsigned int 0, long 0) line 1585 + 30 bytes
CControlBar::WindowProc(unsigned int 15, unsigned int 0, long 0) line 480 + 20 bytes
AfxCallWndProc(CWnd * 0x003353dc {CToolBarXP hWnd=0x0002020a}, HWND__ * 0x0002020a, unsigned int 15, unsigned int 0, long 0) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x0002020a, unsigned int 15, unsigned int 0, long 0) line 368
AfxWndProcBase(HWND__ * 0x0002020a, unsigned int 15, unsigned int 0, long 0) line 220 + 21 bytes
USER32! 77d13a68()
USER32! 77d13b37()
USER32! 77d1450d()
USER32! 77d1453d()
NTDLL! 77fa4da6()
USER32! 77d1438c()
CWinThread::Run() line 487 + 11 bytes
CWinApp::Run() line 400
AfxWinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00151f07, int 1) line 49 + 11 bytes
WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00151f07, int 1) line 30
WinMainCRTStartup() line 330 + 54 bytes
KERNEL32! 77e614c7()
I think it is a matter of USER32.dll, but what?
|
|
|
|
|
|
I do know. Mr. Stupid had been there and placed code to catch the message inside the inherited toolbar. Grrr !
|
|
|
|
|
Hello,
I have a menu with a submenu. On Highlighting main menu......when sub menu is appearing little triangle on right side of main menu is disappearing. Please tell how to solve this.
Thanks,
Rahul.
|
|
|
|
|
See 'Blue box highlight' thread. I believe this will fix your issue as well.
|
|
|
|
|
Everything worked perfect.... until I tried to set up menus to behave when the user clicked. I mean, the presentation and so on works perfect, but the trouble that I have is that I can't or I don't know where I may introduce the ON_COMMAND(...........), it doesn't work, it seems like nothing is returned, it works the same as if I wouldn't change anything.
I need help, please.
Thank you, Rafael from spain.
MaestroProgramador.Com
Where every source code is loved like a girl.
|
|
|
|
|
Hi,
I have the following strange effect, which is that my main menu captions are overwritten by the captions of submenu. The situation is that I have the same command in both the main menu and some popup-menu's, but that their caption is different.
To illustrate this, in the main menu I have a "Setup" main-item with in this "Setup" menu the items "Setup Size...", "Setup Color..." and "Setup Font...". But the user can also rightclick on an object in my document, and then a submenu appears with Item "Size >" and subitems "10 mm", "20 mm", "30 mm" and "Dialog...".
Now, the mainmenu item "Setup Color..." and the submenu item "Dialog..." both have the same command ID. After retrieving the pop-up menu, the main menu item "Setup Color..." becomes "Dialog..."
A work-around would be to assign a different command ID to the item in the main menu and the submenu and map both command to the same function, but this behaviour is different from the MFC standard menus, so then it would at least be something to mentions in the description of CMenuXP.
|
|
|
|
|