📄 atlctrlxp.h
字号:
#ifndef __ATLCTRLXP_H__
#define __ATLCTRLXP_H__
/////////////////////////////////////////////////////////////////////////////
// CCommandBarXPCtrl - Command Bar (XP look) and others
//
// Written by Bjarke Viksoe (bjarke@viksoe.dk)
// Copyright (c) 2001-2002 Bjarke Viksoe.
// Alex Kamenev provided chevron support.
// Thanks to Ramon Casellas for plenty for suggestions.
// Nicola Tufarelli supplied fixes for button texts.
//
// Overrides the original WTL CCommandBarCtrl.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name is included.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability if it causes any damage to you or your
// computer whatsoever. It's free, so don't hassle me about it.
//
// Beware of bugs.
//
#pragma once
#ifndef __cplusplus
#error WTL requires C++ compilation (use a .cpp suffix)
#endif
#ifndef __ATLCTRLW_H__
#error atlctrlxp.h requires atlctrlw.h to be included first
#endif
#if (_WTL_VER < 0x0700)
#error This file requires WTL version 7.0 or higher
#endif
// This hack allows us to have a SDI and MDI commandbar (but only one).
// Add this define if you're building a MDI app.
#ifndef _WTL_USE_MDI
#define COMMANDBAR_CLASS CCommandBarCtrlImpl
#else
#define COMMANDBAR_CLASS CMDICommandBarCtrlImpl
#endif
/////////////////////////////////////////////////////////////////////////////
// CCommandBarXPCtrl - The Command Bar
// Standard XP Command Bar styles
#define ATL_SIMPLE_XP_CMDBAR_PANE_STYLE \
(WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CBRWS_NODIVIDER | CBRWS_NORESIZE | CBRWS_NOPARENTALIGN)
// Additional Extended CommandBar styles
#define CBR_EX_NOWIGGLE 0x10000000
class CFlatMenuWindow :
public CWindowImpl<CFlatMenuWindow>
#ifdef __DIALOGSHADOWS_H__
, public CDialogShadows<CFlatMenuWindow>
#endif // __DIALOGSHADOWS_H__
{
public:
DECLARE_WND_SUPERCLASS(_T("WTL_XpMenu"), GetWndClassName())
BEGIN_MSG_MAP(CFlatMenuWindow)
MESSAGE_HANDLER(WM_NCPAINT, OnNcPaint)
#ifdef __DIALOGSHADOWS_H__
CHAIN_MSG_MAP( CDialogShadows<CFlatMenuWindow> )
#endif // __DIALOGSHADOWS_H__
END_MSG_MAP()
COLORREF m_clrHighlightBorder;
COLORREF m_clrBackground;
COLORREF m_clrMenu;
SIZE m_sizeBorder;
int m_cxMenuButton;
CFlatMenuWindow(int cxMenuButton, COLORREF clrBorder, COLORREF clrBack, COLORREF clrColor)
: m_cxMenuButton(cxMenuButton),
m_clrHighlightBorder(clrBorder),
m_clrBackground(clrBack),
m_clrMenu(clrColor)
{
m_sizeBorder.cx = ::GetSystemMetrics(SM_CXDLGFRAME);
m_sizeBorder.cy = ::GetSystemMetrics(SM_CYDLGFRAME);
}
virtual void OnFinalMessage(HWND /*hWnd*/)
{
delete this;
}
LRESULT OnNcPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
//CDCHandle dc = GetDCEx( (HRGN) wParam, DCX_WINDOW | DCX_INTERSECTRGN | 0x10000 );
CWindowDC dc(m_hWnd);
if( wParam > 1 ) dc.SelectClipRgn( (HRGN)wParam );
RECT rcWin;
GetWindowRect(&rcWin);
::OffsetRect(&rcWin, -rcWin.left, -rcWin.top);
// Paint frame
CBrush brushBack;
brushBack.CreateSolidBrush(m_clrBackground);
CPen pen;
pen.CreatePen(PS_SOLID, 1, m_clrHighlightBorder);
HPEN hOldPen = dc.SelectPen(pen);
HBRUSH hOldBrush = dc.SelectBrush(brushBack);
dc.Rectangle(rcWin.left, rcWin.top, rcWin.right, rcWin.bottom);
// Fill area to the left with grey color
CBrush brushColor;
brushColor.CreateSolidBrush(m_clrMenu);
RECT rcLeft = { rcWin.left + 1, rcWin.top + m_sizeBorder.cy, rcWin.left + m_sizeBorder.cx, rcWin.bottom - m_sizeBorder.cy };
dc.FillRect(&rcLeft, brushColor);
// If this is a top-level dropdown menu, smooth the top/left area
if( m_cxMenuButton > 0 ) {
CPen penColor;
penColor.CreatePen(PS_SOLID, 1, m_clrMenu);
dc.SelectPen(penColor);
dc.MoveTo(rcWin.left + 1, rcWin.top);
dc.LineTo(rcWin.left + m_cxMenuButton, rcWin.top);
}
dc.SelectPen(hOldPen);
dc.SelectBrush(hOldBrush);
return 1;
}
};
typedef struct tagXPSTYLE
{
COLORREF clrFrame;
COLORREF clrBackground;
COLORREF clrMenu;
COLORREF clrHighlightBorder;
COLORREF clrHighlight;
COLORREF clrHighlightDark;
COLORREF clrPressed;
COLORREF clrGreyText;
COLORREF clrMenuText;
COLORREF clrSelMenuText;
COLORREF clrButtonText;
COLORREF clrSelButtonText;
COLORREF clrShadow;
} XPSTYLE;
class CCommandBarXPCtrlBase : public CCommandBarCtrlBase
{
public:
static RECT m_rcButton;
static bool m_bIsMenuDropped;
static XPSTYLE m_xpstyle;
};
template< class T, class TBase = CCommandBarXPCtrlBase, class TWinTraits = CControlWinTraits >
class ATL_NO_VTABLE CCommandBarXPCtrlImpl : public COMMANDBAR_CLASS< T, TBase, TWinTraits >
{
public:
DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())
typedef COMMANDBAR_CLASS< T, TBase, TWinTraits > baseCtrlClass;
enum
{
s_kcxTextMargin = 6,
s_kcxDropDownArrowWidth = 14,
s_kcxDropWholeArrowWidth = 10,
s_kcxChevronItemWidth = 12,
_nMaxMenuItemTextLength = 100,
};
// Declarations
CSimpleValArray<HWND> m_Toolbars;
// Message map and handlers
BEGIN_MSG_MAP(CRecentCommandBarCtrlImpl)
MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
CHAIN_MSG_MAP( baseCtrlClass )
ALT_MSG_MAP(1) // Parent window messages
NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnParentCustomDraw)
NOTIFY_CODE_HANDLER(TBN_DROPDOWN, OnParentToolbarDropDown)
CHAIN_MSG_MAP_ALT( baseCtrlClass, 1 )
ALT_MSG_MAP(2) // MDI client window messages
CHAIN_MSG_MAP_ALT( baseCtrlClass, 2 )
ALT_MSG_MAP(3) // Message hook messages
CHAIN_MSG_MAP_ALT( baseCtrlClass, 3 )
END_MSG_MAP()
CCommandBarXPCtrlImpl()
{
}
// Operations
BOOL AddToolbar(HWND hwndTB)
{
ATLASSERT(::IsWindow(hwndTB));
m_Toolbars.Add(hwndTB);
#if (_WIN32_IE >= 0x0501)
// WTL 7.1 attempts to set the clipped button style
DWORD dwExStyle = (DWORD)::SendMessage(hwndTB, TB_GETEXTENDEDSTYLE, 0, 0L);
::SendMessage(hwndTB, TB_SETEXTENDEDSTYLE, 0, dwExStyle & ~TBSTYLE_EX_HIDECLIPPEDBUTTONS);
#endif //(_WIN32_IE >= 0x0501)
return TRUE;
}
#ifndef _WTL_USE_MDI
BOOL SetMDIClient(HWND /*hWndMDIClient*/)
{
// Use CMDICommandBarCtrl for MDI support
// and define _WTL_USE_MDI in stdafx.h
ATLASSERT(false);
return FALSE;
}
#endif // _WTL_USE_MDI
void Prepare()
{
#ifndef RBBS_NOGRIPPER
const UINT RBBS_NOGRIPPER = 0x00000100;
#endif // RBBS_NOGRIPPER
// Update colors
_GetSystemSettings();
// Assume we are in a rebar
HWND hWndReBar = GetParent();
ATLASSERT(::IsWindow(hWndReBar));
// Turn off gripper for menu and remove band edge
int nCount = (int) ::SendMessage(hWndReBar, RB_GETBANDCOUNT, 0, 0L);
for( int i = 0; i < nCount; i++ ) {
REBARBANDINFO rbbi = { sizeof(REBARBANDINFO), RBBIM_CHILD | RBBIM_STYLE | RBBIM_COLORS };
BOOL bRet = (BOOL)::SendMessage(hWndReBar, RB_GETBANDINFO, i, (LPARAM) &rbbi);
if( bRet && rbbi.hwndChild == m_hWnd ) {
// Menubar has no gripper.
rbbi.fStyle |= RBBS_NOGRIPPER;
}
else {
// Other toolbars have a special background colour
rbbi.clrBack = m_xpstyle.clrMenu;
}
rbbi.fMask &= ~RBBIM_CHILD;
::SendMessage(hWndReBar, RB_SETBANDINFO, i, (LPARAM) &rbbi);
}
// A nasty hack to get rid of the small indent of the menu toolbar.
// We hide & show the band, and presto - no paint/indent problems!?
::SendMessage(hWndReBar, RB_SHOWBAND, 0, 0L);
::SendMessage(hWndReBar, RB_SHOWBAND, 0, 1L);
}
// Implementation
void _GetSystemSettings()
{
#ifndef BlendRGB
#define BlendRGB(c1, c2, factor) \
RGB( GetRValue(c1) + ((GetRValue(c2) - GetRValue(c1)) * factor / 100), \
GetGValue(c1) + ((GetGValue(c2) - GetGValue(c1)) * factor / 100), \
GetBValue(c1) + ((GetBValue(c2) - GetBValue(c1)) * factor / 100) );
#endif
::EnterCriticalSection(&_Module.m_csStaticDataInit);
COLORREF clrWindow = ::GetSysColor(COLOR_WINDOW);
COLORREF clrText = ::GetSysColor(COLOR_WINDOWTEXT);
COLORREF clrButton = ::GetSysColor(COLOR_BTNFACE);
CWindowDC dc(NULL);
int nBitsPerPixel = dc.GetDeviceCaps(BITSPIXEL);
if( nBitsPerPixel > 8 ) {
m_xpstyle.clrBackground = BlendRGB(clrWindow, clrText, 3);
m_xpstyle.clrMenu = BlendRGB(clrButton, clrWindow, 20);
m_xpstyle.clrHighlightBorder = ::GetSysColor(COLOR_HIGHLIGHT);
m_xpstyle.clrHighlight = BlendRGB(m_xpstyle.clrHighlightBorder, clrWindow, 70);
m_xpstyle.clrHighlightDark = BlendRGB(m_xpstyle.clrHighlightBorder, clrWindow, 60);
m_xpstyle.clrPressed = BlendRGB(m_xpstyle.clrHighlight, clrText, 20);
m_xpstyle.clrShadow = BlendRGB(::GetSysColor(COLOR_3DFACE), ::GetSysColor(COLOR_WINDOWTEXT), 35);
}
else {
m_xpstyle.clrBackground = clrWindow;
m_xpstyle.clrMenu = clrButton;
m_xpstyle.clrHighlightBorder = ::GetSysColor(COLOR_HIGHLIGHT);
m_xpstyle.clrHighlight = clrWindow;
m_xpstyle.clrHighlightDark = clrWindow;
m_xpstyle.clrPressed = ::GetSysColor(COLOR_HIGHLIGHT);
m_xpstyle.clrShadow = ::GetSysColor(COLOR_GRAYTEXT);
}
m_xpstyle.clrFrame = ::GetSysColor(COLOR_WINDOWFRAME);
m_xpstyle.clrGreyText = ::GetSysColor(COLOR_GRAYTEXT);
m_xpstyle.clrMenuText = ::GetSysColor(COLOR_WINDOWTEXT);
m_xpstyle.clrSelMenuText = ::GetSysColor(COLOR_MENUTEXT);
m_xpstyle.clrButtonText = ::GetSysColor(COLOR_BTNTEXT);
m_xpstyle.clrSelButtonText = ::GetSysColor(COLOR_MENUTEXT);
::LeaveCriticalSection(&_Module.m_csStaticDataInit);
}
#if (_WIN32_IE >= 0x0500)
// Chevron support by Alex Kamenev, thanks.
void _DrawChevron(HWND hwndRebar, UINT nItemId, CDCHandle& dc, RECT rc)
{
// Assume we are in a rebar
CReBarCtrl wndRB = hwndRebar;
// Get current band
int nItem = wndRB.IdToIndex(nItemId);
RECT rcTb; // child toolbar rect
REBARBANDINFO rbbi = { sizeof(REBARBANDINFO), RBBIM_STYLE | RBBIM_IDEALSIZE | RBBIM_HEADERSIZE | RBBIM_CHILD | RBBIM_COLORS };
if( ::SendMessage(wndRB, RB_GETBANDINFO, nItem, (LPARAM) &rbbi) )
{
::GetWindowRect(rbbi.hwndChild, &rcTb);
if( (rbbi.fStyle & RBBS_USECHEVRON) != 0 && ( (UINT)(rcTb.right - rcTb.left) < rbbi.cxIdeal) )
{
POINT pt;
::GetCursorPos(&pt);
::ScreenToClient(wndRB, &pt);
CBrush brush;
RECT rcChevItem = { rc.left + rbbi.cxHeader + (rcTb.right - rcTb.left) + 4, rc.top, 0, 0 };
RECT rcBand;
wndRB.GetRect(nItem, &rcBand);
rcChevItem.right = rcChevItem.left + s_kcxChevronItemWidth;
rcChevItem.bottom = rcChevItem.top + (rcBand.bottom - rcBand.top);
#ifdef _CMDBAR_EXTRA_TRACE
//ATLTRACE2(atlTraceUI, 0, "CmdBar - DrawChevron1: (%d,%d; %d;%d), (%d;%d)\n", rcChevItem.left, rcChevItem.top, rcChevItem.right, rcChevItem.bottom, pt.x, pt.y);
#endif
if( ::PtInRect(&rcChevItem, pt) )
{
CPen pen;
brush.CreateSolidBrush(m_xpstyle.clrHighlight);
pen.CreatePen(PS_SOLID, 1, m_xpstyle.clrHighlightBorder);
HPEN hOldPen = dc.SelectPen(pen);
HBRUSH hOldBrush = dc.SelectBrush(brush);
dc.Rectangle(&rcChevItem);
dc.SelectPen(hOldPen);
dc.SelectBrush(hOldBrush);
}
else
{
brush.CreateSolidBrush(rbbi.clrBack);
dc.FillRect(&rcChevItem, brush);
}
// Draw chevron
CFont fnt;
CFontHandle fntOld;
LOGFONT lf = { 0 };
::lstrcpy(lf.lfFaceName, _T("Verdana"));
lf.lfHeight = -MulDiv(8, dc.GetDeviceCaps(LOGPIXELSY), 72);
lf.lfWeight = FW_BOLD;
fnt.CreateFontIndirect(&lf);
fntOld = dc.SelectFont(fnt);
WCHAR wszChevron[] = { 0x00bb, 0x0000 }; //TCHAR szChevron[] = _T(">");
dc.SetBkMode(TRANSPARENT);
::TextOutW(dc, rc.left + rbbi.cxHeader + (rcTb.right - rcTb.left) + 5, rc.top + 1, wszChevron, 1);
dc.SelectFont(fntOld);
}
}
}
#endif //(_WIN32_IE >= 0x0500)
// Implementation - overriding original functionality
BOOL DoTrackPopupMenu(HMENU hMenu, UINT uFlags, int x, int y, LPTPMPARAMS lpParams = NULL)
{
#ifdef _CMDBAR_EXTRA_TRACE
//ATLTRACE2(atlTraceUI, 0, "CmdBar - DoTrackPopupMenu, m_bContextMenu: %s\n", m_bContextMenu ? "yes" : "no");
#endif
// Remember to call Prepare()
// Add toolbars with AddToolbar()
ATLASSERT(m_xpstyle.clrBackground!=m_xpstyle.clrMenuText);
// Added by Tom Furuya
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -