|
|
//
// cuimenu.cpp
//
#include "private.h"
#include "cuimenu.h"
#include "fontlink.h"
#if (_WIN32_WINNT < 0x0500)
#define SPI_GETMENUANIMATION 0x1002
#define SPI_GETMENUFADE 0x1012
/*
* AnimateWindow() Commands */ #define AW_HOR_POSITIVE 0x00000001
#define AW_HOR_NEGATIVE 0x00000002
#define AW_VER_POSITIVE 0x00000004
#define AW_VER_NEGATIVE 0x00000008
#define AW_CENTER 0x00000010
#define AW_HIDE 0x00010000
#define AW_ACTIVATE 0x00020000
#define AW_SLIDE 0x00040000
#define AW_BLEND 0x00080000
#endif /* _WIN32_WINNT < 0x0500 */
#define MENU_ARROW_MARGIN 2
#define MENU_TEXT_MARGIN 8
/*============================================================================*/ //
// CUIFMenuItem
//
/*============================================================================*/
/*------------------------------------------------------------------------------
ctor
------------------------------------------------------------------------------*/ CUIFMenuItem::CUIFMenuItem(CUIFMenu *pMenu, DWORD dwFlags) : CUIFObject(pMenu, 0, NULL, 0) { _uId = 0; _psz = NULL; _cch = 0; _pszTab = NULL; _cchTab = 0; _uShortcutkey = 0; _hbmp = NULL; _hbmpMask = NULL; _bChecked = FALSE; _bGrayed = FALSE; _pMenu = pMenu; _uUnderLine = -1; _bNonSelectedItem = (dwFlags & UIMENUITEM_NONSELECTEDITEM) ? TRUE : FALSE; }
/*------------------------------------------------------------------------------
dtor
------------------------------------------------------------------------------*/ CUIFMenuItem::~CUIFMenuItem(void) { if (_psz) delete _psz;
if (_pszTab) delete _pszTab;
if (_pSubMenu) delete _pSubMenu; }
/*------------------------------------------------------------------------------
Init
------------------------------------------------------------------------------*/ BOOL CUIFMenuItem::Init(UINT uId, WCHAR *psz) { _uId = uId;
if (!psz) { _psz = NULL; _cch = 0; return TRUE; }
UINT cch = StrLenW(psz); _psz = new WCHAR[cch + 1]; if (!_psz) return FALSE;
int i = 0; while (*psz && (*psz != L'\t')) { if (*psz == L'&') { psz++; if (*psz != L'&') { _uShortcutkey = LOBYTE(VkKeyScanW(*psz)); if (!_uShortcutkey) { Assert(!HIBYTE(*psz)); _uShortcutkey = LOBYTE(VkKeyScanA(LOBYTE(*psz))); } _uUnderLine = i; } } _psz[i] = *psz; i++; psz++; } _cch = StrLenW(_psz);
if (*psz == L'\t') { _pszTab = new WCHAR[cch + 1]; if (_pszTab) { i = 0; psz++; while (*psz) { _pszTab[i] = *psz; psz++; i++; } _cchTab = StrLenW(_pszTab); } }
return TRUE; }
/*------------------------------------------------------------------------------
SetBitmap
------------------------------------------------------------------------------*/ void CUIFMenuItem::SetBitmap(HBITMAP hbmp) { _hbmp = hbmp; }
/*------------------------------------------------------------------------------
Set bitmap of button face
------------------------------------------------------------------------------*/ void CUIFMenuItem::SetBitmapMask( HBITMAP hBmp ) { _hbmpMask = hBmp; #if 0
BITMAP bmp; GetObject(_hbmp, sizeof(bmp), &bmp); RECT rc; ::SetRect(&rc, 0, 0, bmp.bmWidth, bmp.bmHeight); _hbmpMask = CreateMaskBmp(&rc, _hbmp, hBmp, (HBRUSH)(COLOR_3DFACE + 1) ); #endif
CallOnPaint(); }
/*------------------------------------------------------------------------------
Check
------------------------------------------------------------------------------*/ void CUIFMenuItem::Check(BOOL bChecked) { _bChecked = bChecked; }
/*------------------------------------------------------------------------------
RadioCheck
------------------------------------------------------------------------------*/ void CUIFMenuItem::RadioCheck(BOOL bRadioChecked) { _bRadioChecked = bRadioChecked; }
/*------------------------------------------------------------------------------
Gray
------------------------------------------------------------------------------*/ void CUIFMenuItem::Gray(BOOL bGrayed) { _bGrayed = bGrayed; }
/*------------------------------------------------------------------------------
SetSub
------------------------------------------------------------------------------*/ void CUIFMenuItem::SetSub(CUIFMenu *pSubMenu) { _pSubMenu = pSubMenu; }
/*------------------------------------------------------------------------------
InitMenuExtent
------------------------------------------------------------------------------*/ void CUIFMenuItem::InitMenuExtent() { HDC hdc = GetDC(m_pUIWnd->GetWnd()); if (_psz) { HFONT hFontOld= (HFONT)SelectObject( hdc, GetFont() ); CUIGetTextExtentPoint32( hdc, _psz, _cch, &_size); _size.cx += MENU_TEXT_MARGIN * 2; _size.cy += MENU_TEXT_MARGIN;
if (_pszTab) { CUIGetTextExtentPoint32( hdc, _pszTab, _cchTab, &_sizeTab); _sizeTab.cy += MENU_TEXT_MARGIN; }
SelectObject( hdc, hFontOld);
if (GetSub()) { _size.cx += (_size.cy + MENU_ARROW_MARGIN); }
if (_pMenu->IsO10Menu()) _size.cx += 24; } else if (_hbmp) { BITMAP bmp; GetObject(_hbmp, sizeof(bmp), &bmp); _size.cx = bmp.bmWidth + 2; _size.cy = bmp.bmHeight + 4; } else { _size.cy = 0; _size.cx = 0; }
ReleaseDC(m_pUIWnd->GetWnd(), hdc);
}
/*------------------------------------------------------------------------------
OnLButtonUp
------------------------------------------------------------------------------*/ void CUIFMenuItem::OnLButtonUp(POINT pt) { if (IsGrayed()) return;
if (IsNonSelectedItem()) return;
if (_pSubMenu) return;
_pMenu->SetSelectedId(_uId); PostMessage(m_pUIWnd->GetWnd(), WM_NULL, 0, 0); }
/*------------------------------------------------------------------------------
OnMouseIn
------------------------------------------------------------------------------*/ void CUIFMenuItem::OnMouseIn(POINT pt) { _pMenu->CancelSubMenu();
//
// start timer to open submenu.
//
if (_pSubMenu) { UINT uElipse; if (!SystemParametersInfo(SPI_GETMENUSHOWDELAY, 0, (void *)&uElipse, FALSE)) { uElipse = 300; }
StartTimer(uElipse); }
//
// darw this.
//
_pMenu->SetSelectedItem(this); }
/*------------------------------------------------------------------------------
OnMouseOut
------------------------------------------------------------------------------*/ void CUIFMenuItem::OnMouseOut(POINT pt) {
}
/*------------------------------------------------------------------------------
OnTimer
------------------------------------------------------------------------------*/ void CUIFMenuItem::OnTimer() { EndTimer(); Assert(PtrToInt(_pSubMenu));
if (!_pMenu->IsPointed(this)) return;
ShowSubPopup();
} /*------------------------------------------------------------------------------
ShowSubPopup
------------------------------------------------------------------------------*/ void CUIFMenuItem::ShowSubPopup() { Assert(PtrToInt(_pSubMenu));
RECT rc = GetRectRef(); ClientToScreen(m_pUIWnd->GetWnd(), (POINT *)&rc.left); ClientToScreen(m_pUIWnd->GetWnd(), (POINT *)&rc.right); _pSubMenu->ShowSubPopup(_pMenu, &rc, FALSE); }
/*------------------------------------------------------------------------------
OnPaint
------------------------------------------------------------------------------*/ void CUIFMenuItem::OnPaint(HDC hDC) { if (_pMenu->IsO10Menu()) OnPaintO10(hDC); else OnPaintDef(hDC); }
/*------------------------------------------------------------------------------
OnPaintDef
------------------------------------------------------------------------------*/ void CUIFMenuItem::OnPaintDef(HDC hDC) { HFONT hFontOld; int xAlign; int yAlign; int xText; int yText; int xCheck; int yCheck; int xBmp; int yBmp; int xArrow; int yArrow; SIZE size;
hFontOld= (HFONT)SelectObject( hDC, GetFont() );
// calc alignment
CUIGetTextExtentPoint32( hDC, _psz, _cch, &size );
xAlign = 0; yAlign = (GetRectRef().bottom - GetRectRef().top - size.cy) / 2;
xCheck = GetRectRef().left + xAlign; yCheck = GetRectRef().top + yAlign;
xBmp = xCheck + (_pMenu->IsBmpCheckItem() ? _pMenu->GetMenuCheckWidth() : 0); yBmp = GetRectRef().top;
xText = xCheck + 2 + _pMenu->GetMenuCheckWidth() + (_pMenu->IsBmpCheckItem() ? _pMenu->GetMenuCheckWidth() : 0); yText = GetRectRef().top + yAlign; xArrow = GetRectRef().left + GetRectRef().right - 10, yArrow = GetRectRef().top + yAlign;
// draw
SetBkMode( hDC, TRANSPARENT );
if (!_bGrayed) { if (!_pMenu->IsSelectedItem(this) || IsNonSelectedItem()) { SetTextColor( hDC, GetSysColor(COLOR_MENUTEXT) );
CUIExtTextOut( hDC, xText, yText, ETO_CLIPPED, &GetRectRef(), _psz, _cch, NULL );
DrawUnderline(hDC, xText, yText, (HBRUSH)(COLOR_MENUTEXT + 1));
DrawCheck(hDC, xCheck, yCheck);
DrawBitmapProc(hDC, xBmp, yBmp);
DrawArrow(hDC, xArrow, yArrow);
} else { SetTextColor( hDC, GetSysColor(COLOR_HIGHLIGHTTEXT) ); SetBkColor( hDC, GetSysColor(COLOR_HIGHLIGHT) ); CUIExtTextOut( hDC, xText, yText, ETO_CLIPPED | ETO_OPAQUE, &GetRectRef(), _psz, _cch, NULL );
DrawUnderline(hDC, xText, yText, (HBRUSH)(COLOR_HIGHLIGHTTEXT + 1));
DrawCheck(hDC, xCheck, yCheck);
DrawBitmapProc(hDC, xBmp, yBmp);
DrawArrow(hDC, xArrow, yArrow); } } else { UINT ueto = ETO_CLIPPED;
if (!_pMenu->IsSelectedItem(this) || IsNonSelectedItem()) { SetTextColor( hDC, GetSysColor(COLOR_3DHIGHLIGHT) ); CUIExtTextOut( hDC, xText + 1, yText + 1, ueto, &GetRectRef(), _psz, _cch, NULL );
DrawCheck(hDC, xCheck + 1, yCheck + 1); DrawBitmapProc(hDC, xBmp + 1, yBmp + 1);
DrawArrow(hDC, xArrow + 1, yArrow + 1); } else { SetBkColor( hDC, GetSysColor(COLOR_HIGHLIGHT) ); ueto |= ETO_OPAQUE; }
SetTextColor(hDC, GetSysColor(COLOR_3DSHADOW) ); CUIExtTextOut(hDC, xText, yText, ueto, &GetRectRef(), _psz, _cch, NULL );
DrawUnderline(hDC, xText, yText, (HBRUSH)(COLOR_3DSHADOW + 1));
DrawCheck(hDC, xCheck, yCheck);
DrawBitmapProc(hDC, xBmp, yBmp);
DrawArrow(hDC, xArrow, yArrow); }
// restore objects
SelectObject( hDC, hFontOld); }
/*------------------------------------------------------------------------------
OnPaintO10
------------------------------------------------------------------------------*/ void CUIFMenuItem::OnPaintO10(HDC hDC) { HFONT hFontOld; int xAlign; int yAlign; int xText; int yText; int xCheck; int yCheck; int xBmp; int yBmp; int xArrow; int yArrow; SIZE size; RECT rc;
if (!m_pUIFScheme) return;
hFontOld= (HFONT)SelectObject( hDC, GetFont() );
// calc alignment
CUIGetTextExtentPoint32( hDC, _psz, _cch, &size );
xAlign = 0; yAlign = (GetRectRef().bottom - GetRectRef().top - size.cy) / 2;
xCheck = GetRectRef().left + xAlign; yCheck = GetRectRef().top + yAlign;
xBmp = xCheck + (_pMenu->IsBmpCheckItem() ? _pMenu->GetMenuCheckWidth() : 0); yBmp = GetRectRef().top;
xText = xBmp + 8 + _pMenu->GetMenuCheckWidth();
yText = GetRectRef().top + yAlign; xArrow = GetRectRef().left + GetRectRef().right - size.cy - MENU_ARROW_MARGIN; //size.cy may be enough for size of arrow...
yArrow = GetRectRef().top + yAlign;
// draw
GetRect(&rc); if (!_pMenu->IsSelectedItem(this) || IsNonSelectedItem()) { rc.right = rc.left + _pMenu->GetMenuCheckWidth() + 2; if (_pMenu->IsBmpCheckItem()) rc.right += _pMenu->GetMenuCheckWidth();
::FillRect(hDC, &rc, m_pUIFScheme->GetBrush(UIFCOLOR_CTRLBKGND)); } else { m_pUIFScheme->DrawCtrlBkgd(hDC, &rc, 0, UIFDCS_SELECTED); m_pUIFScheme->DrawCtrlEdge(hDC, &rc, 0, UIFDCS_SELECTED); }
SetBkMode( hDC, TRANSPARENT );
if (!_bGrayed) { if (!_pMenu->IsSelectedItem(this) || IsNonSelectedItem()) { SetTextColor( hDC, m_pUIFScheme->GetColor(UIFCOLOR_CTRLTEXT) );
CUIExtTextOut( hDC, xText, yText, ETO_CLIPPED, &GetRectRef(), _psz, _cch, NULL );
DrawUnderline(hDC, xText, yText, (HBRUSH)m_pUIFScheme->GetBrush(UIFCOLOR_CTRLTEXT));
if (_pszTab) CUIExtTextOut( hDC, GetRectRef().right - _pMenu->GetMaxTabTextLength() - MENU_TEXT_MARGIN, yText, ETO_CLIPPED, &GetRectRef(), _pszTab, _cchTab, NULL );
DrawCheck(hDC, xCheck, yCheck);
DrawBitmapProc(hDC, xBmp, yBmp);
DrawArrow(hDC, xArrow, yArrow);
} else { SetTextColor( hDC, m_pUIFScheme->GetColor(UIFCOLOR_MOUSEOVERTEXT) );
CUIExtTextOut( hDC, xText, yText, ETO_CLIPPED, &GetRectRef(), _psz, _cch, NULL );
DrawUnderline(hDC, xText, yText, (HBRUSH)m_pUIFScheme->GetBrush(UIFCOLOR_MOUSEOVERTEXT));
if (_pszTab) CUIExtTextOut( hDC, GetRectRef().right - _pMenu->GetMaxTabTextLength() - MENU_TEXT_MARGIN, yText, ETO_CLIPPED, &GetRectRef(), _pszTab, _cchTab, NULL );
DrawCheck(hDC, xCheck, yCheck);
DrawBitmapProc(hDC, xBmp, yBmp);
DrawArrow(hDC, xArrow, yArrow); } } else { #if 1
SetTextColor( hDC, m_pUIFScheme->GetColor(UIFCOLOR_CTRLTEXTDISABLED) ); CUIExtTextOut(hDC, xText, yText, ETO_CLIPPED, &GetRectRef(), _psz, _cch, NULL );
DrawUnderline(hDC, xText, yText, (HBRUSH)m_pUIFScheme->GetBrush(UIFCOLOR_CTRLTEXTDISABLED));
if (_pszTab) CUIExtTextOut( hDC, GetRectRef().right - _pMenu->GetMaxTabTextLength() - MENU_TEXT_MARGIN, yText, ETO_CLIPPED, &GetRectRef(), _pszTab, _cchTab, NULL );
DrawCheck(hDC, xCheck, yCheck);
DrawBitmapProc(hDC, xBmp, yBmp);
DrawArrow(hDC, xArrow, yArrow); #else
UINT ueto = ETO_CLIPPED;
if (!_pMenu->IsSelectedItem(this) || IsNonSelectedItem()) { SetTextColor( hDC, GetSysColor(COLOR_3DHIGHLIGHT) ); CUIExtTextOut( hDC, xText + 1, yText + 1, ueto, &GetRectRef(), _psz, _cch, NULL );
if (_pszTab) CUIExtTextOut( hDC, GetRectRef().right - _pMenu->GetMaxTabTextLength() - 3, yText + 1, ETO_CLIPPED, &GetRectRef(), _pszTab, _cchTab, NULL );
DrawCheck(hDC, xCheck + 1, yCheck + 1); DrawBitmapProc(hDC, xBmp + 1, yBmp + 1);
DrawArrow(hDC, xArrow + 1, yArrow + 1); } else { SetBkColor( hDC, GetSysColor(COLOR_HIGHLIGHT) ); ueto |= ETO_OPAQUE; }
SetTextColor(hDC, GetSysColor(COLOR_3DSHADOW) ); CUIExtTextOut(hDC, xText, yText, ueto, &GetRectRef(), _psz, _cch, NULL );
DrawUnderline(hDC, xText, yText, (HBRUSH)(COLOR_3DSHADOW + 1));
CUIExtTextOut( hDC, GetRectRef().right - _pMenu->GetMaxTabTextLength() - MENU_TEXT_MARGIN, yText, ETO_CLIPPED, &GetRectRef(), _pszTab, _cchTab, NULL );
DrawCheck(hDC, xCheck, yCheck);
DrawBitmapProc(hDC, xBmp, yBmp);
DrawArrow(hDC, xArrow, yArrow); #endif
}
// restore objects
SelectObject( hDC, hFontOld); }
/*------------------------------------------------------------------------------
DrawUnderline
------------------------------------------------------------------------------*/ void CUIFMenuItem::DrawUnderline(HDC hDC, int x, int y, HBRUSH hbr) { if (_uUnderLine > _cch) return;
SIZE size0, size1; CUIGetTextExtentPoint32( hDC, _psz, _uUnderLine, &size0 ); CUIGetTextExtentPoint32( hDC, _psz, _uUnderLine + 1, &size1 );
RECT rc; rc.left = x + size0.cx; if (_uUnderLine) rc.left++;
rc.right = x + size1.cx; rc.top = y + size1.cy - 1; rc.bottom = y + size1.cy; FillRect(hDC, &rc, hbr);
}
/*------------------------------------------------------------------------------
DrawCheck
------------------------------------------------------------------------------*/ void CUIFMenuItem::DrawCheck(HDC hDC, int x, int y) { if (!IsCheck()) return;
HFONT hFontOld = (HFONT)SelectObject( hDC, _pMenu->GetMarlettFont());
TextOut(hDC, x, y, _bChecked ? "a" : "h", 1);
SelectObject( hDC, hFontOld); }
/*------------------------------------------------------------------------------
DrawArrow
------------------------------------------------------------------------------*/ void CUIFMenuItem::DrawArrow(HDC hDC, int x, int y) { if (!_pSubMenu) return;
HFONT hFontOld = (HFONT)SelectObject( hDC, _pMenu->GetMarlettFont()); TextOut( hDC, x, y, "4", 1); SelectObject( hDC, hFontOld); }
/* D R A W B I T M A P P R O C */ /*------------------------------------------------------------------------------
Draw bitmap on button face
------------------------------------------------------------------------------*/ void CUIFMenuItem::DrawBitmapProc( HDC hDC, int x, int y) { BITMAP bmp; DWORD dwState = 0;
if (!m_pUIFScheme) return;
if (!_hbmp) return; int cx; int cy;
cx = _pMenu->GetMenuCheckWidth();
cy = GetRectRef().bottom - GetRectRef().top;
// we have to do this viewport trick to get around the fact that
// DrawState has a GDI bug in NT4, such that it handles offsets improperly.
// so we do the offset by hand.
// POINT ptOldOrg;
// BOOL fRetVal = SetViewportOrgEx( hDC, 0, 0, &ptOldOrg );
// Assert( fRetVal );
GetObject(_hbmp, sizeof(bmp), &bmp); if (cx > bmp.bmWidth) { x += (cx - bmp.bmWidth) / 2; cx = bmp.bmWidth; }
if (cy > bmp.bmHeight) { y += (cy - bmp.bmHeight) / 2; cy = bmp.bmHeight; } RECT rc; // ::SetRect(&rc, x + ptOldOrg.x,
// y + ptOldOrg.y,
// x + ptOldOrg.x + cx,
// y + ptOldOrg.y + cy);
::SetRect(&rc, x, y, x + cx, y + cy);
if (IsRTL()) m_pUIFScheme->SetLayout(LAYOUT_RTL);
if (_pMenu->IsSelectedItem(this) && !IsNonSelectedItem()) { dwState |= UIFDCS_SELECTED; m_pUIFScheme->DrawMenuBitmap(hDC, &rc, _hbmp, _hbmpMask, dwState); } #if 0
else if (IsCheck()) { dwState |= UIFDCS_MOUSEOVER; m_pUIFScheme->DrawMenuBitmap(hDC, &rc, _hbmp, _hbmpMask, dwState); ::OffsetRect(&rc, -1, -1); ::InflateRect(&rc, 2, 2); m_pUIFScheme->DrawCtrlEdge(hDC, &rc, 0, UIFDCS_SELECTED); } #endif
else { m_pUIFScheme->DrawMenuBitmap(hDC, &rc, _hbmp, _hbmpMask, dwState); }
if (IsRTL()) m_pUIFScheme->SetLayout(0);
// SetViewportOrgEx( hDC, ptOldOrg.x, ptOldOrg.y, NULL );
}
/*============================================================================*/ //
// CUIFMenuItemSeparator
//
/*============================================================================*/
/*------------------------------------------------------------------------------
OnPaint
------------------------------------------------------------------------------*/ void CUIFMenuItemSeparator::OnPaint(HDC hDC) { if (_pMenu->IsO10Menu()) OnPaintO10(hDC); else OnPaintDef(hDC); }
/*------------------------------------------------------------------------------
OnPaintDef
------------------------------------------------------------------------------*/ void CUIFMenuItemSeparator::OnPaintDef(HDC hDC) { if (!m_pUIFScheme) return;
int xAlign = 2; int yAlign = (GetRectRef().bottom - GetRectRef().top - 2) / 2; int cx = (GetRectRef().right - GetRectRef().left - 2 * xAlign);
RECT rc; ::SetRect(&rc, GetRectRef().left + xAlign, GetRectRef().top + yAlign, GetRectRef().left + xAlign + cx, GetRectRef().top + yAlign + 2);
m_pUIFScheme->DrawMenuSeparator( hDC, &rc); }
/*------------------------------------------------------------------------------
OnPaintO10 ------------------------------------------------------------------------------*/ void CUIFMenuItemSeparator::OnPaintO10(HDC hDC) { if (!m_pUIFScheme) return;
int xAlign = 2; int yAlign = (GetRectRef().bottom - GetRectRef().top - 2) / 2; int cx = (GetRectRef().right - GetRectRef().left - 2 * xAlign); int xStart = 0; RECT rc;
GetRect(&rc); rc.right = rc.left + _pMenu->GetMenuCheckWidth() + 2; if (_pMenu->IsBmpCheckItem()) rc.right += _pMenu->GetMenuCheckWidth();
::FillRect(hDC, &rc, m_pUIFScheme->GetBrush(UIFCOLOR_CTRLBKGND)); xStart = _pMenu->GetMenuCheckWidth() + 2;
::SetRect(&rc, GetRectRef().left + xAlign + xStart, GetRectRef().top + yAlign, GetRectRef().left + xAlign + cx, GetRectRef().top + yAlign + 1);
m_pUIFScheme->DrawMenuSeparator( hDC, &rc); }
/*------------------------------------------------------------------------------
InitMenuExtent
------------------------------------------------------------------------------*/ void CUIFMenuItemSeparator::InitMenuExtent() { _size.cx = 0; _size.cy = 6; }
/*============================================================================*/ //
// CUIFMenu
//
/*============================================================================*/
/*------------------------------------------------------------------------------
ctor
------------------------------------------------------------------------------*/ CUIFMenu::CUIFMenu(HINSTANCE hInst, DWORD dwWndStyle, DWORD dwMenuStyle) : CUIFWindow(hInst, dwWndStyle) { _uIdSelect = CUI_MENU_UNSELECTED; _dwMenuStyle = dwMenuStyle;
SetMenuFont(); }
/*------------------------------------------------------------------------------
dtor
------------------------------------------------------------------------------*/ CUIFMenu::~CUIFMenu( void ) { int i; for (i = 0; i < _rgItems.GetCount(); i++) { CUIFMenuItem *pItem = _rgItems.Get(i); delete pItem; } DeleteObject(_hfontMarlett); ClearMenuFont(); }
/*------------------------------------------------------------------------------
InsertItem
------------------------------------------------------------------------------*/ BOOL CUIFMenu::InsertItem(CUIFMenuItem *pItem) { if (!_rgItems.Add( pItem )) return FALSE;
pItem->SetFont(GetFont()); return TRUE; }
/*------------------------------------------------------------------------------
InsertSeparator
------------------------------------------------------------------------------*/ BOOL CUIFMenu::InsertSeparator() { CUIFMenuItemSeparator *pSep;
pSep = new CUIFMenuItemSeparator(this); if (!pSep) return FALSE;
pSep->Initialize();
if (!_rgItems.Add( pSep )) { delete pSep; return FALSE; }
return TRUE; }
/*------------------------------------------------------------------------------
ShowModalPopup
------------------------------------------------------------------------------*/ UINT CUIFMenu::ShowModalPopup(CUIFWindow *pcuiWndParent, const RECT *prc, BOOL fVertical) { UINT uId; CUIFObject *puicap;
if (pcuiWndParent) { puicap = pcuiWndParent->GetCaptureObject(); pcuiWndParent->SetCaptureObject(NULL); }
if (InitShow(pcuiWndParent, prc, fVertical, TRUE)) { _fInModal = TRUE; pcuiWndParent->SetBehindModal(this);
ModalMessageLoop();
uId = _uIdSelect; pcuiWndParent->SetBehindModal(NULL); _fInModal = FALSE; } else { uId = CUI_MENU_UNSELECTED; }
UninitShow();
if (pcuiWndParent) { pcuiWndParent->SetCaptureObject(puicap); }
return uId; }
/*------------------------------------------------------------------------------
ModalMessageLoop
------------------------------------------------------------------------------*/ void CUIFMenu::ModalMessageLoop( void ) { MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) { if (msg.message == WM_NULL) break;
if (msg.hwnd != GetWnd()) { if ((msg.message > WM_MOUSEFIRST) && (msg.message <= WM_MOUSELAST)) { break; } }
//
// Dispatch key message to Sub menu.
//
if ((msg.message >= WM_KEYFIRST) && (msg.message <= WM_KEYLAST)) { if (!msg.hwnd) { CUIFMenu *pSubMenu = GetTopSubMenu(); msg.hwnd = pSubMenu->GetWnd(); } }
TranslateMessage(&msg); DispatchMessage(&msg); } }
/*------------------------------------------------------------------------------
InitShow
------------------------------------------------------------------------------*/ BOOL CUIFMenu::InitShow(CUIFWindow *pcuiWndParent, const RECT *prc, BOOL fVertical, BOOL fAnimate) { int i; int cxMax = 0; SIZE size = {0, 0}; RECT rc = {0, 0, 0, 0}; RECT rcScreen; HMONITOR hMonitor; CUIFMenuItem *pItem; BOOL fMenuAnimation = FALSE; BOOL fAnimated = FALSE; DWORD dwSlideFlag = 0; int x; int y;
CreateWnd((pcuiWndParent != NULL) ? pcuiWndParent->GetWnd() : NULL);
_fIsBmpCheckItem = FALSE;
for (i = 0; i < _rgItems.GetCount(); i++) { pItem = _rgItems.Get(i); pItem->InitMenuExtent(); }
_cxMaxTab = 0; for (i = 0; i < _rgItems.GetCount(); i++) { pItem = _rgItems.Get(i);
pItem->GetMenuExtent(&size);
size.cx += GetMenuCheckWidth();
cxMax = (size.cx > cxMax) ? size.cx : cxMax; _cxMaxTab = (pItem->GetTabTextLength() > _cxMaxTab) ? pItem->GetTabTextLength() : _cxMaxTab;
_fIsBmpCheckItem |= (pItem->IsBmp() && pItem->IsCheck()) ? TRUE : FALSE; }
for (i = 0; i < _rgItems.GetCount(); i++) { pItem = _rgItems.Get(i);
pItem->GetMenuExtent(&size);
rc.right = rc.left + cxMax + _cxMaxTab; rc.bottom = rc.top + size.cy; pItem->SetRect(&rc); rc.top += size.cy;
AddUIObj(pItem); }
rc.top = 0; LONG_PTR dwStyle = GetWindowLongPtr(GetWnd(), GWL_STYLE);
int nWidth = rc.right; int nHeight = rc.bottom;
if (dwStyle & WS_DLGFRAME) { nWidth += GetSystemMetrics(SM_CXDLGFRAME) * 2; nHeight += GetSystemMetrics(SM_CYDLGFRAME) * 2; } else if (dwStyle & WS_BORDER) { nWidth += GetSystemMetrics(SM_CXBORDER) * 2; nHeight += GetSystemMetrics(SM_CYBORDER) * 2; }
::SetRect( &rcScreen, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN) ); RECT rcT; rcT = *prc; hMonitor = CUIMonitorFromRect( &rcT, MONITOR_DEFAULTTONEAREST ); if (hMonitor != NULL) { MONITORINFO MonitorInfo = {0};
MonitorInfo.cbSize = sizeof(MONITORINFO); if (CUIGetMonitorInfo( hMonitor, &MonitorInfo )) { rcScreen = MonitorInfo.rcMonitor; } }
if (FHasStyle( UIWINDOW_LAYOUTRTL )) rc.left -= nWidth;
if (fVertical) { x = rc.left + prc->left; if (rc.top + prc->bottom + nHeight <= rcScreen.bottom) { y = rc.top + prc->bottom; dwSlideFlag = AW_VER_POSITIVE; } else { y = rc.top + prc->top - nHeight; dwSlideFlag = AW_VER_NEGATIVE; }
if (rc.left + prc->right + nWidth > rcScreen.right) x = rcScreen.right - nWidth; } else { y = rc.top + prc->top; if (rc.left + prc->right + nWidth <= rcScreen.right) { x = rc.left + prc->right; dwSlideFlag = AW_HOR_POSITIVE; } else { x = rc.left + prc->left - nWidth; dwSlideFlag = AW_HOR_NEGATIVE; }
if (rc.top + prc->bottom + nHeight > rcScreen.bottom) y = rcScreen.bottom - nHeight; }
x = min( rcScreen.right - nWidth, x ); x = max( rcScreen.left, x ); y = min( rcScreen.bottom - nHeight, y ); y = max( rcScreen.top, y ); Move(x, y, nWidth, nHeight);
SetRect(NULL);
// animation support
fAnimated = FALSE; if (fAnimate) { if (SystemParametersInfo( SPI_GETMENUANIMATION, 0, &fMenuAnimation, FALSE ) && fMenuAnimation) { BOOL fFade = FALSE; DWORD dwFlags;
if (!SystemParametersInfo( SPI_GETMENUFADE, 0, &fFade, FALSE )) { fFade = FALSE; }
// determine animation flag
if (fFade) { dwFlags = AW_BLEND; } else { dwFlags = AW_SLIDE | dwSlideFlag; }
fAnimated = AnimateWnd( 200, dwFlags ); } } if (!fAnimated) { Show(TRUE); }
if (_pcuiParentMenu) _pcuiParentMenu->_pCurrentSubMenu = this;
return TRUE; }
/*------------------------------------------------------------------------------
UninitShow
------------------------------------------------------------------------------*/ BOOL CUIFMenu::UninitShow() { int i;
if (_pCurrentSubMenu) _pCurrentSubMenu->UninitShow();
Show(FALSE);
if (_pcuiParentMenu) _pcuiParentMenu->_pCurrentSubMenu = NULL;
for (i = 0; i < _rgItems.GetCount(); i++) RemoveUIObj(_rgItems.Get(i));
DestroyWindow(GetWnd());
return TRUE; }
/*------------------------------------------------------------------------------
ShowSubPopup
------------------------------------------------------------------------------*/ void CUIFMenu::ShowSubPopup(CUIFMenu *pcuiParentMenu, const RECT *prc, BOOL fVertical) { _pcuiParentMenu = pcuiParentMenu; InitShow(pcuiParentMenu, prc, fVertical, TRUE); // TODO: fAnimate = FALSE if submenu has already been shown, or going to be changed contibuously
}
/*------------------------------------------------------------------------------
OnLButtonUp
------------------------------------------------------------------------------*/ void CUIFMenu::HandleMouseMsg( UINT uMsg, POINT pt ) { if (!PtInRect(&GetRectRef(), pt)) { if ((uMsg == WM_LBUTTONDOWN) || (uMsg == WM_RBUTTONDOWN) || (uMsg == WM_LBUTTONUP) || (uMsg == WM_RBUTTONUP)) { SetSelectedId(CUI_MENU_UNSELECTED); PostMessage(GetWnd(), WM_NULL, 0, 0); } }
CUIFWindow::HandleMouseMsg( uMsg, pt ); }
/*------------------------------------------------------------------------------
CancelMenu
------------------------------------------------------------------------------*/ void CUIFMenu::CancelMenu() { if (_pcuiParentMenu) { UninitShow(); return; }
if (!_fInModal) return;
SetSelectedId(CUI_MENU_UNSELECTED); PostMessage(GetWnd(), WM_NULL, 0, 0); }
/*------------------------------------------------------------------------------
CancelMenu
------------------------------------------------------------------------------*/ void CUIFMenu::SetSelectedId(UINT uId) { if (_pcuiParentMenu) { _pcuiParentMenu->SetSelectedId(uId); return; } _uIdSelect = uId; }
/*------------------------------------------------------------------------------
GetTopSubMenu
------------------------------------------------------------------------------*/ CUIFMenu *CUIFMenu::GetTopSubMenu() { if (_pCurrentSubMenu) return _pCurrentSubMenu->GetTopSubMenu();
return this; }
/*------------------------------------------------------------------------------
PostKey
------------------------------------------------------------------------------*/ void CUIFMenu::PostKey(BOOL fUp, WPARAM wParam, LPARAM lParam) { if (!_fInModal) return;
if (fUp) PostMessage(0, WM_KEYUP, wParam, lParam); else PostMessage(0, WM_KEYDOWN, wParam, lParam); }
/*------------------------------------------------------------------------------
ModalMouseNotify
------------------------------------------------------------------------------*/ void CUIFMenu::ModalMouseNotify( UINT uMsg, POINT pt) { if ((uMsg == WM_LBUTTONDOWN) || (uMsg == WM_RBUTTONDOWN)) CancelMenu(); }
/*------------------------------------------------------------------------------
OnKeyDown
------------------------------------------------------------------------------*/ void CUIFMenu::OnKeyDown(HWND hwnd, WPARAM wParam, LPARAM lParam) { UINT uVKey = (UINT)wParam & 0xff; CUIFMenuItem *pItem;
switch (uVKey) { case VK_ESCAPE: CancelMenu(); break;
case VK_UP: pItem = GetPrevItem(_pSelectedItem); goto MoveToItem;
case VK_DOWN: pItem = GetNextItem(_pSelectedItem); MoveToItem: SetSelectedItem(pItem); break;
case VK_RIGHT: if (_pSelectedItem && _pSelectedItem->GetSub()) { _pSelectedItem->ShowSubPopup(); CUIFMenu *pSubMenu = _pSelectedItem->GetSub(); CUIFMenuItem *pSubMenuItem = pSubMenu->GetNextItem(NULL); pSubMenu->SetSelectedItem(pSubMenuItem); } break;
case VK_LEFT: if (_pcuiParentMenu) CancelMenu(); break;
case VK_RETURN: DoReturn: if (_pSelectedItem) { if (_pSelectedItem->IsGrayed()) break;
if (_pSelectedItem->GetSub()) { _pSelectedItem->ShowSubPopup(); CUIFMenu *pSubMenu = _pSelectedItem->GetSub(); CUIFMenuItem *pSubMenuItem = pSubMenu->GetNextItem(NULL); pSubMenu->SetSelectedItem(pSubMenuItem); } else { SetSelectedId(_pSelectedItem->GetId()); PostMessage(GetWnd(), WM_NULL, 0, 0); } } else { CancelMenu(); } break;
default: if ((uVKey >= 'A' && uVKey <= 'Z') || (uVKey >= '0' && uVKey <= '9')) { int nCnt = _rgItems.GetCount(); int i; for (i = 0; i < nCnt; i++) { pItem = _rgItems.Get(i); Assert(PtrToInt(pItem)); if (pItem->GetVKey() == uVKey) { SetSelectedItem(pItem); goto DoReturn; } } } break;
} }
/*------------------------------------------------------------------------------
OnKeyUp
------------------------------------------------------------------------------*/ void CUIFMenu::OnKeyUp(HWND hwnd, WPARAM wParam, LPARAM lParam) { }
/*------------------------------------------------------------------------------
GetNextItem
------------------------------------------------------------------------------*/ CUIFMenuItem *CUIFMenu::GetNextItem(CUIFMenuItem *pItem) { int nCnt = _rgItems.GetCount(); CUIFMenuItem *pItemTmp; int i;
if (!nCnt) return NULL;
if (!_pSelectedItem) return _rgItems.Get(0);
for (i = 0; i < nCnt; i++) { pItemTmp = _rgItems.Get(i); Assert(PtrToInt(pItemTmp));
if (pItem == pItemTmp) { i++; break; } }
if (i == nCnt) i = 0;
pItemTmp = _rgItems.Get(i); while (pItemTmp && pItemTmp->IsNonSelectedItem()) { i++; if (i == nCnt) i = 0; pItemTmp = _rgItems.Get(i); }
return pItemTmp; }
/*------------------------------------------------------------------------------
GetPrevItem
------------------------------------------------------------------------------*/ CUIFMenuItem *CUIFMenu::GetPrevItem(CUIFMenuItem *pItem) { int nCnt = _rgItems.GetCount(); CUIFMenuItem *pItemTmp = NULL; int i;
if (!nCnt) return NULL;
if (!_pSelectedItem) return _rgItems.Get(nCnt - 1);
for (i = nCnt - 1; i >= 0; i--) { pItemTmp = _rgItems.Get(i); Assert(PtrToInt(pItemTmp));
if (pItem == pItemTmp) { i--; break; } }
if (i < 0) i = nCnt - 1;
pItemTmp = _rgItems.Get(i); while (pItemTmp && pItemTmp->IsNonSelectedItem()) { i--; if (i < 0) i = nCnt - 1; pItemTmp = _rgItems.Get(i); }
return pItemTmp; }
/*------------------------------------------------------------------------------
SetMenuFont
------------------------------------------------------------------------------*/
void CUIFMenu::SetMenuFont() { NONCLIENTMETRICS ncm; int nMarlettFontSize = 14;
ncm.cbSize = sizeof(ncm); if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, FALSE)) { HFONT hFont = CreateFontIndirect(&ncm.lfMenuFont); SetFont(hFont); nMarlettFontSize = (ncm.lfMenuFont.lfHeight > 0) ? ncm.lfMenuFont.lfHeight : -ncm.lfMenuFont.lfHeight; nMarlettFontSize = (ncm.iMenuHeight + nMarlettFontSize) / 2; }
_hfontMarlett = CreateFont(nMarlettFontSize, 0, 0, 0, 400, FALSE, FALSE, FALSE, SYMBOL_CHARSET, 0, 0, 0, 0, "Marlett");
_cxMenuCheck = nMarlettFontSize;
int cxSmIcon = GetSystemMetrics( SM_CXSMICON ); if (_cxMenuCheck < cxSmIcon) _cxMenuCheck = cxSmIcon;
_cxMenuCheck += 2; }
/*------------------------------------------------------------------------------
ClearMenuFont
------------------------------------------------------------------------------*/
void CUIFMenu::ClearMenuFont() { HFONT hFont = GetFont(); SetFont(NULL); DeleteObject(hFont); }
|