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

📄 cooltabctrls.h

📁 这是一本学习 window编程的很好的参考教材
💻 H
📖 第 1 页 / 共 3 页
字号:
// using public member methods to access all variables.
//
// You need to add the...
//   REFLECT_NOTIFICATIONS()
// macro to the parent's message map.
//

class CButtonTabCtrl : 
   public CCustomTabCtrl<CButtonTabCtrl>,
   public CCustomDraw<CButtonTabCtrl>
{
public:
   DECLARE_WND_CLASS(_T("WTL_CoolButtonTabCtrl"))

   BEGIN_MSG_MAP(CButtonTabCtrl)
      REFLECTED_NOTIFY_CODE_HANDLER(TCN_INITIALIZE, OnInitialize)
      CHAIN_MSG_MAP(CCustomTabCtrl<CButtonTabCtrl>)
      CHAIN_MSG_MAP_ALT(CCustomDraw<CButtonTabCtrl>, 1)
      DEFAULT_REFLECTION_HANDLER()
   END_MSG_MAP()

   LRESULT OnInitialize(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
   {
      TCMETRICS metrics;
      GetMetrics(&metrics);
      metrics.cxButtonSpacing = 3;
      metrics.cxMargin = 10;
      SetMetrics(&metrics);
      return 0;
   }

   DWORD OnPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/)
   {
      return CDRF_NOTIFYITEMDRAW;   // We need per-item notifications
   }

   DWORD OnItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw)
   {
      ::SetBkMode(lpNMCustomDraw->hdc, TRANSPARENT);
      ::SetTextColor(lpNMCustomDraw->hdc, ::GetSysColor(COLOR_BTNTEXT));
      
      UINT state = 0;
      if( lpNMCustomDraw->uItemState & CDIS_SELECTED ) state |= DFCS_PUSHED;
      if( lpNMCustomDraw->uItemState & CDIS_DISABLED ) state |= DFCS_INACTIVE;
      ::DrawFrameControl(lpNMCustomDraw->hdc, &lpNMCustomDraw->rc, DFC_BUTTON, DFCS_BUTTONPUSH | state );
      
      TCITEM item = { 0 };
      TCHAR szText[128] = { 0 };
      item.mask = TCIF_TEXT;
      item.pszText = szText;
      item.cchTextMax = (sizeof(szText)/sizeof(TCHAR)) - 1;
      GetItem(lpNMCustomDraw->dwItemSpec, &item);
      if( lpNMCustomDraw->uItemState & CDIS_SELECTED ) {
         lpNMCustomDraw->rc.left += 2;
         lpNMCustomDraw->rc.top += 2;
      }
      ::DrawText(lpNMCustomDraw->hdc, item.pszText, ::lstrlen(item.pszText), &lpNMCustomDraw->rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);

      return CDRF_SKIPDEFAULT;
   }
};

class CFolderTabCtrl : 
   public CCustomTabCtrl<CFolderTabCtrl>,
   public CCustomDraw<CFolderTabCtrl>
{
public:
   DECLARE_WND_CLASS(_T("WTL_CoolFolderTabCtrl"))

   CFont m_font;

   enum { CXOFFSET = 8 };     // defined pitch of trapezoid slant
   enum { CXMARGIN = 2 };     // left/right text margin
   enum { CYMARGIN = 1 };     // top/bottom text margin
   enum { CYBORDER = 1 };     // top border thickness
 
   BEGIN_MSG_MAP(CFolderTabCtrl)
      MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
      REFLECTED_NOTIFY_CODE_HANDLER(TCN_INITIALIZE, OnInitialize)
      CHAIN_MSG_MAP(CCustomTabCtrl<CFolderTabCtrl>)
      CHAIN_MSG_MAP_ALT(CCustomDraw<CFolderTabCtrl>, 1)
      DEFAULT_REFLECTION_HANDLER()
   END_MSG_MAP()

   LRESULT OnInitialize(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
   {
      TCMETRICS metrics;
      GetMetrics(&metrics);
      metrics.cxIndent = CXOFFSET;
      metrics.cxPadding = CXOFFSET + 3;
      metrics.cxOverlap = CXOFFSET;
      metrics.cxImagePadding = 2;
      SetMetrics(&metrics);
      return 0;
   }

   DWORD OnPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/)
   {
      return CDRF_NOTIFYITEMDRAW;   // We need per-item notifications
   }

   DWORD OnItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw)
   {
      CDCHandle dc( lpNMCustomDraw->hdc );
      bool bSelected = lpNMCustomDraw->uItemState & CDIS_SELECTED;

      COLORREF bgColor = ::GetSysColor(bSelected ? COLOR_WINDOW     : COLOR_3DFACE);
      COLORREF fgColor = ::GetSysColor(bSelected ? COLOR_WINDOWTEXT : COLOR_BTNTEXT);

      CBrush brush;
      brush.CreateSolidBrush(bgColor);     // background brush
      dc.SetBkColor(bgColor);              // text background
      dc.SetTextColor(fgColor);            // text color = fg color

      CPen shadowPen;
      shadowPen.CreatePen(PS_SOLID, 1, ::GetSysColor(COLOR_3DSHADOW));

      // Fill trapezoid
      POINT pts[4];
      RECT rc = lpNMCustomDraw->rc;
      _GetTrapezoid(rc, pts);
      CPenHandle hOldPen = dc.SelectStockPen(BLACK_PEN);   
      CRgn rgn;
      rgn.CreatePolygonRgn(pts, 4, WINDING);
      dc.FillRgn(rgn, brush);

      // Draw edges. This requires two corrections:
      // 1) Trapezoid dimensions don't include the right and bottom edges,
      //    so must use one pixel less on bottom (cybottom)
      // 2) the endpoint of LineTo is not included when drawing the line, so
      //    must add one pixel (cytop)
      pts[1].y--;       // correction #1: true bottom edge y-coord
      pts[2].y--;       // ...ditto
      pts[3].y--;       // correction #2: extend final LineTo
      dc.MoveTo(pts[0]);              // upper left
      dc.LineTo(pts[1]);              // bottom left
      dc.SelectPen(shadowPen);        // bottom line is shadow color
      dc.MoveTo(pts[1]);              // line is inside trapezoid bottom
      dc.LineTo(pts[2]);              // ...
      dc.SelectStockPen(BLACK_PEN);   // upstroke is black
      dc.LineTo(pts[3]);              // y-1 to include endpoint
      if( !bSelected ) {
         // If not highlighted, upstroke has a 3D shadow, one pixel inside
         pts[2].x--;    // offset left one pixel
         pts[3].x--;    // ...ditto
         dc.SelectPen(shadowPen);
         dc.MoveTo(pts[2]);
         dc.LineTo(pts[3]);
      }
      dc.SelectPen(hOldPen);

      TCITEM item = { 0 };
      TCHAR szText[128] = { 0 };
      item.mask = TCIF_TEXT;
      item.pszText = szText;
      item.cchTextMax = (sizeof(szText) / sizeof(TCHAR)) - 1;
      GetItem(lpNMCustomDraw->dwItemSpec, &item);

      // Draw text
      ::InflateRect(&rc, -(CXOFFSET + CXMARGIN), -CYMARGIN);
      HFONT hOldFont = dc.SelectFont(bSelected ? GetSelFont() : GetFont());
      dc.DrawText(item.pszText, ::lstrlen(item.pszText), &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
      dc.SelectFont(hOldFont);

      return CDRF_SKIPDEFAULT;
   }

   void _GetTrapezoid(const RECT& rc, POINT* pts) const
   {
      pts[0].x = rc.left;
      pts[0].y = rc.top;
      pts[1].x = rc.left + CXOFFSET;
      pts[1].y = rc.bottom;
      pts[2].x = rc.right - CXOFFSET - 1;
      pts[2].y = rc.bottom;
      pts[3].x = rc.right - 1, rc.top;
      pts[3].y = rc.top;
   }

   LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
   {
      // Initialize font
      if( !m_font.IsNull() ) m_font.DeleteObject();
      LOGFONT lf = { 0 };      
      lf.lfHeight = ::GetSystemMetrics(SM_CYHSCROLL) - CYMARGIN;
      lf.lfWeight = FW_NORMAL;
      lf.lfCharSet = DEFAULT_CHARSET;
      ::lstrcpy(lf.lfFaceName, _T("Arial"));
      m_font.CreateFontIndirect(&lf);
      SetFont(m_font);

      bHandled = FALSE;
      return 0;
   }
};

class CDotNetTabCtrl : 
   public CCustomTabCtrl<CDotNetTabCtrl>,
   public CCustomDraw<CDotNetTabCtrl>
{
public:
   DECLARE_WND_CLASS(_T("WTL_DotNetTabCtrl")) 

   CFont m_font;
   CFont m_fontBold;
   CBrush m_hbrBack;

   BEGIN_MSG_MAP(CDotNetTabCtrl)
      MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
      REFLECTED_NOTIFY_CODE_HANDLER(TCN_INITIALIZE, OnInitialize)
      CHAIN_MSG_MAP(CCustomTabCtrl<CDotNetTabCtrl>)
      CHAIN_MSG_MAP_ALT(CCustomDraw<CDotNetTabCtrl>, 1)
      DEFAULT_REFLECTION_HANDLER()
   END_MSG_MAP()

   LRESULT OnInitialize(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
   {
      TCMETRICS metrics;
      GetMetrics(&metrics);
      metrics.cxIndent = 6;
      metrics.cxPadding = 0;
      metrics.cxMargin = 4;
      metrics.cxSelMargin = 2;
      metrics.cxOverlap = 2;
      metrics.cxImagePadding = 2;
      SetMetrics(&metrics);
      return 0;
   }

   DWORD OnPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw)
   {
      CDCHandle dc( lpNMCustomDraw->hdc );

      RECT rc;
      GetClientRect(&rc);
      HBRUSH hOldBrush = dc.SelectBrush(m_hbrBack);
      dc.PatBlt(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY);
      if( GetStyle() & TCS_BOTTOM ) 
      {
         dc.SelectStockPen(BLACK_PEN);
         dc.MoveTo(rc.left, rc.top + 1);
         dc.LineTo(rc.right, rc.top + 1);
      }
      else
      {
         dc.SelectStockPen(WHITE_PEN);
         dc.MoveTo(rc.left, rc.bottom - 1);
         dc.LineTo(rc.right, rc.bottom - 1);
      }
      dc.SelectBrush(hOldBrush);

      dc.SetBkMode(TRANSPARENT);

      return CDRF_NOTIFYITEMDRAW;   // We need per-item notifications
   }

   DWORD OnItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw)
   {
      CDCHandle dc( lpNMCustomDraw->hdc );
      RECT rc = lpNMCustomDraw->rc;
      bool bSelected = (lpNMCustomDraw->uItemState & CDIS_SELECTED) != 0;

      int iCurSel = GetCurSel();
      DWORD dwStyle = GetStyle();
      DWORD dwExtStyle = GetExtendedStyle();

      if( dwStyle & TCS_BUTTONS ) /* */;
      else if( dwStyle & TCS_BOTTOM ) rc.bottom -= 3; 
      else rc.top += 3;

      // Paint separators if needed
      if( dwExtStyle & TCS_EX_FLATSEPARATORS ) 
      {
         if( (int) lpNMCustomDraw->dwItemSpec != iCurSel 
             && (int) lpNMCustomDraw->dwItemSpec != iCurSel - 1 
             && (int) lpNMCustomDraw->dwItemSpec != GetItemCount() - 1 ) 
         {
            RECT rcLine = { rc.right - 1, rc.top + 2, rc.right, rc.bottom - 2 };
            dc.FillRect(&rcLine, ::GetSysColorBrush(COLOR_GRAYTEXT));
            rc.right -= 2;
         }
      }

      rc.right--;
      RECT rcText = rc;

      // Tab is selected, so paint tab folder
      if( dwStyle & TCS_BUTTONS ) 
      {
         ::InflateRect(&rc, -4, -3);
         ::InflateRect(&rcText, -2, -2);
         if( bSelected ) 
         {
            dc.FillRect(&rc, ::GetSysColorBrush(COLOR_HIGHLIGHTTEXT));
            dc.Draw3dRect(&rc, ::GetSysColor(COLOR_HIGHLIGHT), ::GetSysColor(COLOR_HIGHLIGHT));
         }
      }
      else if( dwStyle & TCS_BOTTOM ) 
      {
         if( bSelected ) 
         {
            dc.FillRect(&rc, ::GetSysColorBrush(COLOR_BTNFACE));
            dc.SelectStockPen(WHITE_PEN);
            dc.MoveTo(rc.left, rc.top);
            dc.LineTo(rc.left, rc.bottom);
            dc.SelectStockPen(BLACK_PEN);
            dc.LineTo(rc.right, rc.bottom);
            dc.LineTo(rc.right, rc.top);
         }
         rcText.top += 4;
         rcText.bottom -= 1;
      }
      else
      {
         if( bSelected ) 
         {
            dc.FillRect(&rc, ::GetSysColorBrush(COLOR_BTNFACE));
            dc.SelectStockPen(WHITE_PEN);
            dc.MoveTo(rc.left, rc.bottom);
            dc.LineTo(rc.left, rc.top);
            dc.LineTo(rc.right, rc.top);
            dc.SelectStockPen(BLACK_PEN);
            dc.LineTo(rc.right, rc.bottom);
         }
         rcText.top += 1;
      }

      // Get some item information
      COOLTCITEM item;
      ::ZeroMemory(&item, sizeof(item));
      TCHAR szText[128] = { 0 };
      item.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_TEXTCOLOR;
      item.pszText = szText;
      item.cchTextMax = (sizeof(szText) / sizeof(TCHAR)) - 1;
      GetItem(lpNMCustomDraw->dwItemSpec, &item);

      TCMETRICS metrics;
      GetMetrics(&metrics);

      CImageList Images = GetImageList();

      rcText.left += 2;
      ::InflateRect(&rcText, -metrics.cxPadding, 0);

      if( item.iImage >= 0 && (item.mask & TCIF_IMAGE) != 0 && !Images.IsNull() ) 
      {
         SIZE szIcon;
         Images.GetIconSize(szIcon);
         if( szIcon.cx * 2 < rcText.right - rcText.left ) {
            Images.Draw(dc, item.iImage, rcText.left + metrics.cxImagePadding, rcText.top + (((rcText.bottom - rcText.top)/2) - (szIcon.cy/2)), ILD_TRANSPARENT);
            rcText.left += szIcon.cx + (metrics.cxImagePadding * 2);
         }
      }
      if( item.mask & TCIF_TEXT )
      {
         dc.SetTextColor(::GetSysColor(COLOR_BTNTEXT));
         if( item.mask & TCIF_TEXTCOLOR ) dc.SetTextColor(item.clrText);
         HFONT hOldFont = dc.SelectFont(bSelected ? GetSelFont() : GetFont());
         dc.DrawText(item.pszText, -1, &rcText, DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_END_ELLIPSIS);
         dc.SelectFont(hOldFont);
      }

      return CDRF_SKIPDEFAULT;
   }

   LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
   {
      // Initialize font
      if( !m_font.IsNull() ) m_font.DeleteObject();
      NONCLIENTMETRICS ncm = { 0 };
      ncm.cbSize = sizeof(ncm);
      ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
      ncm.lfSmCaptionFont.lfWeight = FW_NORMAL;
      m_font.CreateFontIndirect(&ncm.lfSmCaptionFont);
      SetFont(m_font);
      if( !m_fontBold.IsNull() ) m_fontBold.DeleteObject();
      ncm.lfSmCaptionFont.lfWeight = FW_BOLD;
      m_fontBold.CreateFontIndirect(&ncm.lfSmCaptionFont);
      SetSelFont(m_fontBold);

      // Background brush
      if( !m_hbrBack.IsNull() ) m_hbrBack.DeleteObject();
      CWindowDC dc(NULL);
      int nBitsPerPixel = dc.GetDeviceCaps(BITSPIXEL);
      if( nBitsPerPixel > 8 ) {
         COLORREF clrBtnHilite = ::GetSysColor(COLOR_BTNHILIGHT);
         COLORREF clrBtnFace = ::GetSysColor(COLOR_BTNFACE);
         COLORREF clrLight = 
            RGB( GetRValue(clrBtnFace) + ((GetRValue(clrBtnHilite) - GetRValue(clrBtnFace)) / 2),
                 GetGValue(clrBtnFace) + ((GetGValue(clrBtnHilite) - GetGValue(clrBtnFace)) / 2),
                 GetBValue(clrBtnFace) + ((GetBValue(clrBtnHilite) - GetBValue(clrBtnFace)) / 2) );
         m_hbrBack.CreateSolidBrush(clrLight);
      }
      else {
         m_hbrBack =  CDCHandle::GetHalftoneBrush();
      }
      
      bHandled = FALSE;
      return 0;
   }
};


#endif // __COOLTABCTRLS_H__

⌨️ 快捷键说明

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