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

📄 atlctrlxp.h

📁 这是一本学习 window编程的很好的参考教材
💻 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.
//
// 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 + -