⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atlctrlxp.h

📁 remote debug and compile tools
💻 H
📖 第 1 页 / 共 3 页
字号:
#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.
// Tim France fixed the flat window animations.
//
// 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)
      MESSAGE_HANDLER(WM_PRINT, OnPrint)
#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*/)
   {
      CDC dc = ::GetDCEx(m_hWnd, (HRGN) wParam, DCX_WINDOW | DCX_INTERSECTRGN | 0x10000);
      if( dc.IsNull() ) dc = ::GetWindowDC(m_hWnd);
      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;
   }
   LRESULT OnPrint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
   {
      CDCHandle dc = (HDC) wParam;
      RECT rcWin;
      GetWindowRect(&rcWin);
      ::OffsetRect(&rcWin, -rcWin.left, -rcWin.top);

      // Do the same as in OnNcPaint, but draw to provided DC.
      // Should there be a common method?
      if( (lParam & PRF_NONCLIENT) != 0 )
      {
         // 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);
      }

      // Get the system to draw all the items to a memory DC and then whack it
      // on top of the background we just drew above
      if( (lParam & PRF_CLIENT) != 0 )
      {
         RECT rcClient;
         GetClientRect(&rcClient);
         int cxClient = rcClient.right - rcClient.left;
         int cyClient = rcClient.bottom - rcClient.top;
         int offsetX = (rcWin.right - rcWin.left - cxClient) / 2;
         int offsetY = (rcWin.bottom - rcWin.top - cyClient) / 2;
         CDC memDC;
         CBitmap memBM;
         memDC.CreateCompatibleDC(dc);
         memBM.CreateCompatibleBitmap(dc, cxClient, cyClient);
         HBITMAP hOldBmp = memDC.SelectBitmap(memBM);
         DefWindowProc(WM_PRINTCLIENT, (WPARAM) memDC.m_hDC, PRF_CLIENT);
         dc.BitBlt(offsetX, offsetY, cxClient, cyClient, memDC, 0, 0, SRCCOPY);
         memDC.SelectBitmap(hOldBmp);
      }

      bHandled = TRUE;
      return 0;
   }
};


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) ) 
         {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -