📄 cmdbar.h
字号:
return 0;
}
LRESULT OnHookSysChar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
{
bHandled = FALSE;
#ifdef _CMDBAR_EXTRA_TRACE
ATLTRACE2(atlTraceUI, 0, "CmdBar - Hook WM_SYSCHAR (0x%2.2X)\n", wParam);
#endif
if(!m_bMenuActive && m_hWndHook != m_hWnd && wParam != VK_SPACE)
bHandled = TRUE;
return 0;
}
LRESULT OnHookKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
{
#ifdef _CMDBAR_EXTRA_TRACE
ATLTRACE2(atlTraceUI, 0, "CmdBar - Hook WM_KEYDOWN (0x%2.2X)\n", wParam);
#endif
bHandled = FALSE;
if(wParam == VK_ESCAPE)
{
if(m_bMenuActive && !m_bContextMenu)
{
int nHot = GetHotItem();
if(nHot == -1)
nHot = m_nPopBtn;
if(nHot == -1)
nHot = 0;
SetHotItem(nHot);
bHandled = TRUE;
TakeFocus();
m_bEscapePressed = true; // To keep focus
}
else if(::GetFocus() == m_hWnd && m_wndParent.IsWindow())
{
SetHotItem(-1);
GiveFocusBack();
bHandled = TRUE;
}
}
else if(wParam == VK_RETURN || wParam == VK_UP || wParam == VK_DOWN)
{
if(!m_bMenuActive && ::GetFocus() == m_hWnd && m_wndParent.IsWindow())
{
int nHot = GetHotItem();
if(nHot != -1)
{
if(wParam != VK_RETURN)
PostMessage(WM_KEYDOWN, VK_DOWN, 0L);
}
else
{
ATLTRACE2(atlTraceUI, 0, "CmdBar - Can't find hot button\n");
}
}
if(wParam == VK_RETURN && m_bMenuActive)
{
PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L);
m_nNextPopBtn = -1;
GiveFocusBack();
}
}
else if(wParam == VK_LEFT || wParam == VK_RIGHT)
{
if(m_bMenuActive && !(wParam == VK_RIGHT && m_bPopupItem))
{
bool bAction = false;
int nCount = ::GetMenuItemCount(m_hMenu);
if(wParam == VK_LEFT && s_pCurrentBar->m_stackMenuWnd.GetSize() == 1)
{
bAction = true;
m_nNextPopBtn = m_nPopBtn - 1;
if(m_nNextPopBtn < 0)
m_nNextPopBtn = nCount - 1;
}
else if(wParam == VK_RIGHT)
{
bAction = true;
m_nNextPopBtn = m_nPopBtn + 1;
if(m_nNextPopBtn >= nCount)
m_nNextPopBtn = 0;
}
HWND hWndMenu = m_stackMenuWnd.GetCurrent();
ATLASSERT(hWndMenu != NULL);
// Close the popup menu
if(bAction)
{
::PostMessage(hWndMenu, WM_KEYDOWN, VK_ESCAPE, 0L);
if(wParam == VK_RIGHT)
{
int cItem = m_stackMenuWnd.GetSize() - 1;
while(cItem >= 0)
{
hWndMenu = m_stackMenuWnd[cItem];
if(hWndMenu)
{
::PostMessage(hWndMenu, WM_KEYDOWN, VK_ESCAPE, 0L);
}
cItem--;
}
}
bHandled = TRUE;
}
}
}
return 0;
}
LRESULT OnHookNextMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
#ifdef _CMDBAR_EXTRA_TRACE
ATLTRACE2(atlTraceUI, 0, "CmdBar - Hook WM_NEXTMENU\n");
#endif
bHandled = FALSE;
return 1;
}
LRESULT OnHookChar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
{
#ifdef _CMDBAR_EXTRA_TRACE
ATLTRACE2(atlTraceUI, 0, "CmdBar - Hook WM_CHAR (0x%2.2X)\n", wParam);
#endif
bHandled = (wParam == VK_ESCAPE);
if(wParam != VK_ESCAPE && wParam != VK_RETURN && m_bMenuActive)
{
SetHotItem(-1);
GiveFocusBack();
}
return 0;
}
// Implementation - ownerdraw overrideables and helpers
void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
_MenuItemData* pmd = (_MenuItemData*)lpDrawItemStruct->itemData;
CDCHandle dc = lpDrawItemStruct->hDC;
const RECT& rcItem = lpDrawItemStruct->rcItem;
if(pmd->fType & MFT_SEPARATOR)
{
// draw separator
RECT rc = rcItem;
rc.top += (rc.bottom - rc.top) / 2; // vertical center
dc.DrawEdge(&rc, EDGE_ETCHED, BF_TOP); // draw separator line
}
else // not a separator
{
//== Begin, Ramon Smits 22 april 2000
if(lpDrawItemStruct->itemID == SIDEBAR_ID)
{
DrawSideBar(dc, rcItem, pmd->lpstrText);
return;
}
//== End
BOOL bDisabled = lpDrawItemStruct->itemState & ODS_GRAYED;
BOOL bSelected = lpDrawItemStruct->itemState & ODS_SELECTED;
BOOL bChecked = lpDrawItemStruct->itemState & ODS_CHECKED;
BOOL bHasImage = FALSE;
if(LOWORD(lpDrawItemStruct->itemID) == (WORD)-1)
bSelected = FALSE;
RECT rcButn = { rcItem.left, rcItem.top, rcItem.left + m_szButton.cx, rcItem.top + m_szButton.cy }; // button rect
::OffsetRect(&rcButn, 0, ((rcItem.bottom - rcItem.top) - (rcButn.bottom - rcButn.top)) / 2); // center vertically
int iButton = pmd->iButton;
if(iButton >= 0)
{
bHasImage = TRUE;
// calc drawing point
SIZE sz = { rcButn.right - rcButn.left - m_szBitmap.cx, rcButn.bottom - rcButn.top - m_szBitmap.cy };
sz.cx /= 2;
sz.cy /= 2;
POINT point = { rcButn.left + sz.cx, rcButn.top + sz.cy };
// draw disabled or normal
if(!bDisabled)
{
// normal - fill background depending on state
if(!bChecked || bSelected)
dc.FillRect(&rcButn, (HBRUSH)LongToPtr((bChecked && !bSelected) ? (COLOR_3DLIGHT + 1) : (COLOR_MENU + 1)));
else
{
COLORREF crTxt = dc.SetTextColor(::GetSysColor(COLOR_BTNFACE));
COLORREF crBk = dc.SetBkColor(::GetSysColor(COLOR_BTNHILIGHT));
CBrush hbr(CDCHandle::GetHalftoneBrush());
dc.SetBrushOrg(rcButn.left, rcButn.top);
dc.FillRect(&rcButn, hbr);
dc.SetTextColor(crTxt);
dc.SetBkColor(crBk);
}
// draw pushed-in or popped-out edge
if(bSelected || bChecked)
{
RECT rc2 = rcButn;
dc.DrawEdge(&rc2, bChecked ? BDR_SUNKENOUTER : BDR_RAISEDINNER, BF_RECT);
}
// draw the image
::ImageList_Draw(m_hImageList, iButton, dc, point.x, point.y, ILD_TRANSPARENT);
}
else
{
DrawBitmapDisabled(dc, iButton, point);
}
}
else
{
// no image - look for custom checked/unchecked bitmaps
CMenuItemInfo info;
info.fMask = MIIM_CHECKMARKS;
::GetMenuItemInfo((HMENU)lpDrawItemStruct->hwndItem, lpDrawItemStruct->itemID, MF_BYCOMMAND, &info);
if(bChecked || info.hbmpUnchecked)
bHasImage = Draw3DCheckmark(dc, rcButn, bSelected, bChecked ? info.hbmpChecked : info.hbmpUnchecked);
}
// draw item text
int cxButn = m_szButton.cx;
COLORREF colorBG = ::GetSysColor(bSelected ? COLOR_HIGHLIGHT : COLOR_MENU);
if(bSelected || lpDrawItemStruct->itemAction == ODA_SELECT)
{
RECT rcBG = rcItem;
if(bHasImage)
rcBG.left += cxButn + s_kcxGap;
dc.FillRect(&rcBG, (HBRUSH)LongToPtr(bSelected ? (COLOR_HIGHLIGHT + 1) : (COLOR_MENU + 1)));
// == Begin, Ramon Smits 22-04-2000
// if(bSelected)
// dc.Draw3dRect(&rcBG, GetSysColor(COLOR_3DDKSHADOW), GetSysColor(COLOR_3DHILIGHT));
// == End
}else{
}
// calc text rectangle and colors
RECT rcText = rcItem;
rcText.left += cxButn + s_kcxGap + s_kcxTextMargin;
rcText.right -= cxButn;
dc.SetBkMode(TRANSPARENT);
COLORREF colorText = ::GetSysColor(bDisabled ? COLOR_GRAYTEXT : (bSelected ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT));
COLORREF colorAccellerator = ::GetSysColor(bDisabled ? COLOR_GRAYTEXT : (bSelected ? COLOR_HIGHLIGHTTEXT : COLOR_HIGHLIGHT)); //RS
// font already selected by Windows
if(bDisabled && (!bSelected || colorText == colorBG))
{
// disabled - draw shadow text shifted down and right 1 pixel (unles selected)
RECT rcDisabled = rcText;
::OffsetRect(&rcDisabled, 1, 1);
DrawMenuText(dc, rcDisabled, pmd->lpstrText, GetSysColor(COLOR_3DHILIGHT));
}
// == Begin (altered), Ramon Smits 22-04-2000
DrawMenuText(dc, rcText, pmd->lpstrText, colorText, colorAccellerator);
// == End, Original Begin
// DrawMenuText(dc, rcText, pmd->lpstrText, colorText); // finally!
// == End
}
}
void DrawMenuText(CDCHandle& dc, RECT& rc, LPCTSTR lpstrText, COLORREF color)
{
int nTab = -1;
for(int i = 0; i < lstrlen(lpstrText); i++)
{
if(lpstrText[i] == '\t')
{
nTab = i;
break;
}
}
dc.SetTextColor(color);
dc.DrawText(lpstrText, nTab, &rc, DT_SINGLELINE | DT_LEFT | DT_VCENTER);
dc.SetTextColor( GetSysColor(COLOR_HIGHLIGHT) );
if(nTab != -1)
dc.DrawText(&lpstrText[nTab + 1], -1, &rc, DT_SINGLELINE | DT_RIGHT | DT_VCENTER);
dc.SetTextColor(color);
}
// == Begin, Ramon Smits 22-04-2000
// This version takes 2 colors, one for the text and one for the shortcut. This way
// both can have a different color.
void DrawMenuText(CDCHandle& dc, RECT& rc, LPCTSTR lpstrText, COLORREF colorText, COLORREF colorAccellerator)
{
int nTab = -1;
for(int i = 0; i < lstrlen(lpstrText); i++)
{
if(lpstrText[i] == '\t')
{
nTab = i;
break;
}
}
dc.SetTextColor(colorText);
dc.DrawText(lpstrText, nTab, &rc, DT_SINGLELINE | DT_LEFT | DT_VCENTER);
dc.SetTextColor( colorAccellerator );
if(nTab != -1)
dc.DrawText(&lpstrText[nTab + 1], -1, &rc, DT_SINGLELINE | DT_RIGHT | DT_VCENTER);
dc.SetTextColor(colorText);
}
// == End
// == Begin, Ramon Smits 22-04-2000
// This renders a gradient bar from top to botten in the width that is specified in the
// item structure.
void DrawSideBar (CDCHandle& dc, const RECT& grrect, LPCTSTR lpstrSidebarText)
{
RECT rct;
dc.GetClipBox(&rct);
int iWidth = grrect.right - grrect.left;
// int iHeight = grrect.top - grrect.bottom;
int iSideBarHeight = rct.bottom-rct.top;
// int iSideBarWidth = rct.right-rct.left;
COLORREF right = GetSysColor(COLOR_ACTIVECAPTION);
COLORREF left = GetSysColor(27); // COLOR_GRADIENTACTIVECAPTION
COLOR16 r = (COLOR16) ((left & 0x000000FF)<<8);
COLOR16 g = (COLOR16) (left & 0x0000FF00);
COLOR16 b = (COLOR16) ((left & 0x00FF0000)>>8);
TRIVERTEX vert[2] ;
GRADIENT_RECT gRect;
vert [0] .x = 0;
vert [0] .y = 0;
vert [0] .Red = r;
vert [0] .Green = g;
vert [0] .Blue = b;
vert [0] .Alpha = 0x0000;
r = (COLOR16) ((right & 0x000000FF)<<8);
g = (COLOR16) (right & 0x0000FF00);
b = (COLOR16) ((right & 0x00FF0000)>>8);
vert [1] .x = iWidth;
vert [1] .y = iSideBarHeight;
vert [1] .Red = r;
vert [1] .Green = g;
vert [1] .Blue = b;
vert [1] .Alpha = 0x0000;
gRect.UpperLeft = 0;
gRect.LowerRight = 1;
GradientFill(dc.m_hDC,vert,2,&gRect,1,GRADIENT_FILL_RECT_V);
HFONT hFont;
hFont = CreateFont(iWidth, 0, 900,900,0,FALSE,FALSE,FALSE,0,
OUT_DEFAULT_PRECIS,CLIP_MASK, PROOF_QUALITY, FF_DONTCARE, _T(SIDEBAR_FONT));
if (lpstrSidebarText)
{
dc.SetBkMode(TRANSPARENT);
HFONT fontold = dc.SelectFont( hFont );
RECT dims;
dims.left = dims.top = 1;
dims.right = iWidth;
dims.bottom = iSideBarHeight;
dc.SetTextColor( 0x0 );
dc.DrawText(lpstrSidebarText, strlen(lpstrSidebarText),
&dims,
DT_SINGLELINE|DT_BOTTOM);
dims.top -= 1;
dims.left -= 1;
dims.right -= 1;
dims.bottom -= 1;
dc.SetTextColor( GetSysColor(COLOR_CAPTIONTEXT) );
dc.DrawText(lpstrSidebarText, strlen(lpstrSidebarText),
&dims,
DT_SINGLELINE|DT_BOTTOM);
dc.SelectFont( fontold );
}
}
// == End
void DrawBitmapDisabled(CDCHandle& dc, int nImage, POINT point)
{
// create memory DC
CDC dcMem;
dcMem.CreateCompatibleDC(dc);
// create mono or color bitmap
CBitmap bmp;
bmp.CreateCompatibleBitmap(dc, m_szBitmap.cx, m_szBitmap.cy);
ATLASSERT(bmp.m_hBitmap != NULL);
// draw image into memory DC--fill BG white first
HBITMAP hBmpOld = dcMem.SelectBitmap(bmp);
dcMem.PatBlt(0, 0, m_szBitmap.cx, m_szBitmap.cy, WHITENESS);
// If white is the text color, we can't use the normal painting since
// it would blend with the WHITENESS, but the mask is OK
UINT uDrawStyle = (::GetSysColor(COLOR_BTNTEXT) == RGB(255, 255, 255)) ? ILD_MASK : ILD_NORMAL;
::ImageList_Draw(m_hImageList, nImage, dcMem, 0, 0, uDrawStyle);
dc.DitherBlt(point.x, point.y, m_szBitmap.cx, m_szBitmap.cy, dcMem, NULL, 0, 0);
dcMem.SelectBitmap(hBmpOld); // restore
}
BOOL Draw3DCheckmark(CDCHandle& dc, const RECT& rc, BOOL bSelected, HBITMAP hBmpCheck)
{
// get checkmark bitmap if none, use Windows standard
CBitmapHandle bmp = hBmpCheck;
if(hBmpCheck == NULL)
{
bmp.LoadOEMBitmap(OBM_CHECK);
ATLASSERT(bmp.m_hBitmap != NULL);
}
// center bitmap in caller's rectangle
SIZE size = { 0, 0 };
bmp.GetSize(size);
RECT rcDest = rc;
POINT p = { 0, 0 };
SIZE szDelta = { (rc.right - rc.left - size.cx) / 2, (rc.bottom - rc.top - size.cy) / 2 };
if(rc.right - rc.left > size.cx)
{
rcDest.left = rc.left + szDelta.cx;
rcDest.top = rc.top + szDelta.cy;
rcDest.right = rcDest.left + size.cx;
rcDest.bottom = rcDest.top + size.cy;
}
else
{
p.x -= szDelta.cx;
p.y -= szDelta.cy;
}
// select checkmark into memory DC
CDC dcMem;
dcMem.CreateCompatibleDC(dc);
HBITMAP hBmpOld = dcMem.SelectBitmap(bmp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -