Click here to Skip to main content
15,884,836 members
Articles / Desktop Programming / WTL

Outlook Bar Control and Frame (WTL)

Rate me:
Please Sign up or sign in to vote.
5.00/5 (7 votes)
27 Jun 2001 276.1K   7.1K   84  
An outlook control and framework that can be used in your WTL Application
/////////////////////////////////////////////////////////////////////////////
// CCaptionBar Version 1.0
//
//Created for ATL / WTL (Rashid Thadha) 09/04/2000
//
// Version  Date        Comments
// 01       09/04/2001  Created
// 02       22/05/2001  Added Etched Edge Option
// 
/////////////////////////////////////////////////////////////////////////////

#if !defined(ATL_CAPTIONBAR_H)
#define ATL_CAPTIONBAR_H

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

// =============================================================================================
// CCaptionBar window

#include "atlflatbutton.h"

#define IDC_FLAT_BUTTON 1034

struct CAPTIONBAR_INFO 
{
  CRect m_rect;
};

#define WM_CAPTIONBAR_NOTIFY		WM_APP + 10
#define NM_CBAR_BUTTONCLICKED		1

class CCaptionBar :	public CWindowImpl<CCaptionBar, CStatic>
			                   
{
// Construction
public:

  CCaptionBar::CCaptionBar() : m_hCaptionBarIcon(NULL), m_nBorder(0), m_pCaptionTextFont(NULL), m_sCaptionText(""),
                               m_cxSpacing(4), m_cySpacing(2), m_pflatButton(NULL), m_bButtonPressed(false),
                               m_hOwnerWindow(NULL), m_bFlatEdge(false), m_bCreateButtonOnText(false)
	{
	  m_colorFont	= ::GetSysColor(COLOR_WINDOW);
	  m_colorButtonFace = ::GetSysColor(COLOR_BTNFACE);
	  m_colorCaptionBackground = ::GetSysColor(COLOR_BTNSHADOW);
	  m_colorCaptionBorder = ::GetSysColor(COLOR_BTNFACE);
	}

	~CCaptionBar()
	{
    m_defaultFont.DeleteObject();
    if (m_pflatButton)
      delete m_pflatButton;
	}

  void SetOwner(HWND hWnd) {m_hOwnerWindow = hWnd;}

  BOOL Create(HWND pParentWnd, LPCTSTR lpszWindowName, UINT dwStyle, UINT dwExStyle) 
  {
	  // Let the base class create the control.
	  CRect rect;
    if( !CWindowImpl<CCaptionBar, CStatic>::Create(pParentWnd, rect, lpszWindowName, dwStyle, dwExStyle))
	  {
		  return FALSE;
	  }

	  NONCLIENTMETRICS ncm;
	  memset(&ncm, 0, sizeof(NONCLIENTMETRICS));
	  ncm.cbSize = sizeof(NONCLIENTMETRICS);

	  ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS,sizeof(NONCLIENTMETRICS), &ncm, 0);
	  _tcscpy(ncm.lfMessageFont.lfFaceName, _T("Arial"));
	  m_defaultFont.CreateFontIndirect(&ncm.lfMessageFont);

    // Save the window text.
	  m_sCaptionText = lpszWindowName;

    CreateButton();

    return TRUE;
  }

  void SetCaptionText(const CString& sCaptionText)
  {
    ATLASSERT(::IsWindow(m_hWnd));
	  
		m_sCaptionText = sCaptionText;
    SetWindowText(m_sCaptionText);
    if (m_pflatButton)
      m_pflatButton->SetWindowText(sCaptionText);
    
    MoveCaptionButton();
    if (m_pflatButton)
      m_pflatButton->Invalidate();
    
    Invalidate();
  }

  void SetIcon(HICON hIcon)
  {
    ATLASSERT(::IsWindow(m_hWnd));
	  
	  if(hIcon)
		  m_hCaptionBarIcon	= hIcon;
    Invalidate();
  }

  void SetFontColor(COLORREF color) {m_colorFont = color;}
  void SetBackgroundColor(COLORREF colorBackground) {m_colorCaptionBackground = colorBackground;}
  void SetBorderSize(int nBorderSize) {m_nBorder = nBorderSize;}
  int GetBorderSize() {return m_nBorder;}

  void SetFont(CFont* pFont) 
  {
    m_pCaptionTextFont = pFont;
    if (m_pflatButton)
      m_pflatButton->SetFont(m_pCaptionTextFont->m_hFont);
  }
	  
  BEGIN_MSG_MAP(CCaptionBar)
	  MESSAGE_HANDLER(WM_PAINT, OnPaint)
	  MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
	  MESSAGE_HANDLER(WM_SYSCOLORCHANGE, OnSysColorChange)
	  MESSAGE_HANDLER(WM_SIZE, OnSize)
		COMMAND_ID_HANDLER(IDC_FLAT_BUTTON, OnFlatButton)
		REFLECT_NOTIFICATIONS() // required by owner drawn buttons
		MESSAGE_HANDLER(WM_COMMAND, OnCommand)
	END_MSG_MAP()

public:
  
  void SetButtonOnText(bool bValue) {m_bCreateButtonOnText = bValue;}
  void SetFlatEdge(bool bValue) {m_bFlatEdge = bValue;}
  void SetButtonState(bool bState)
  {
    if (m_pflatButton)
    {
      m_pflatButton->SetState(bState);
      m_bButtonPressed = bState;
    }
  }

  void ShowButton(bool bShow = true)
  {
    if (m_pflatButton)
    {
      if (bShow)
        m_pflatButton->ShowWindow(SW_SHOW);
      else
        m_pflatButton->ShowWindow(SW_HIDE);
    }    
  }

protected:
	HICON				    m_hCaptionBarIcon;
	CString				  m_sCaptionText;	 
  CButtonST*      m_pflatButton;
  bool            m_bButtonPressed;
  bool            m_bFlatEdge;
  bool            m_bCreateButtonOnText;

	COLORREF			  m_colorCaptionBorder;	    
	COLORREF			  m_colorFont;		    
	COLORREF			  m_colorButtonFace;	    
	COLORREF			  m_colorCaptionBackground;	    

	CFont*				  m_pCaptionTextFont;       // Override Font
  CFont           m_defaultFont;             // Class Default Font
  HWND m_hOwnerWindow;

  int					    m_nBorder;		    
  int             m_cxSpacing;
  int             m_cySpacing;

	
  LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
	  CPaintDC hDC(m_hWnd);
    
    CRect rect, rectOriginal;
	  GetClientRect(&rect);
    rectOriginal = rect;

    // double buffering for smoother flicker free drawing
    CDC* pDC = NULL;
	  pDC = new CDC;
    ATLASSERT(pDC);

	  pDC->CreateCompatibleDC(hDC.m_hDC);
	  CBitmap bmp;
	  bmp.CreateCompatibleBitmap(hDC.m_hDC, rect.Width(), rect.Height());	  
    HBITMAP obmp = pDC->SelectBitmap(bmp);
	  pDC->FillSolidRect(rectOriginal, m_colorButtonFace);

		if (m_bFlatEdge)
      pDC->DrawEdge(&rect, EDGE_ETCHED, BF_LEFT | BF_TOP | BF_RIGHT | BF_BOTTOM | BF_ADJUST);
    rect.DeflateRect(m_nBorder, m_nBorder);

    // Draw the background
	  pDC->SetBkMode(TRANSPARENT);
    pDC->FillSolidRect(rect, m_colorCaptionBackground);

	  LPTSTR szText;
	  UINT cchText = GetWindowTextLength();
	  szText = (LPTSTR) _alloca((cchText + 1) * sizeof(TCHAR));
	  GetWindowText(szText, cchText + 1);

    CSize size;
	  pDC->GetTextExtent(szText, cchText, &size);
	  
    // Draw the icon
    CRect rc = rect;

	  CSize iconSize;

	  if (m_hCaptionBarIcon != NULL) 
    {
		  iconSize.cx = ::GetSystemMetrics(SM_CXSMICON);
		  iconSize.cy = ::GetSystemMetrics(SM_CYSMICON);

	    rc.left = (rc.right - iconSize.cx) - m_cxSpacing; 
	    if (rc.left < m_cxSpacing)
		    rc.left = m_cxSpacing;
	    rc.top += ( rect.Height() - iconSize.cy )/2;
	    rc.right = rc.left + iconSize.cx;
	    rc.bottom = rc.top + iconSize.cy; 

	    if (rectOriginal.left + size.cx < rc.left - iconSize.cx) 
      { 
        pDC->DrawIconEx(rc.left, rc.top,
					    m_hCaptionBarIcon, iconSize.cx, iconSize.cy);
      }
	  } 

    rect.left += m_cxSpacing;
	  rect.right -= m_cxSpacing;
	  
	  // Draw the text
	  
	  
    HFONT hOldFont;
    
    if (m_pCaptionTextFont)
      hOldFont = pDC->SelectFont(m_pCaptionTextFont->m_hFont);
    else
      hOldFont = pDC->SelectFont(m_defaultFont.m_hFont);

	  pDC->SetBkMode(TRANSPARENT);
	  pDC->SetTextColor(m_colorFont);

	  BOOL bEllipsis = (rect.left + size.cx > rect.right);
	  
	  if (bEllipsis) 
    {
		  CSize sizeEllipsis;
		  pDC->GetTextExtent(_T("..."), 3, &sizeEllipsis);
		  rect.right -= sizeEllipsis.cx;

		  //
		  CSize size;
		  pDC->GetTextExtent(szText, cchText, &size);
		  while (cchText && rect.left + size.cx > rect.right) 
      {
			  cchText--;
			  pDC->GetTextExtent(szText, cchText, &size);
		  }
		  
		  rect.right = rect.left + size.cx;
	  }

	  pDC->ExtTextOut(rect.left, (rect.top + rect.bottom - size.cy) / 2,
					  ETO_CLIPPED, rect, szText, cchText, 0);

	  if (bEllipsis) 
    {
		  pDC->ExtTextOut(rect.right, (rect.top + rect.bottom - size.cy) / 2,
					  0, rect, _T("..."), 3, 0);
	  }

	  hDC.BitBlt(rectOriginal.left, rectOriginal.top, rectOriginal.Width(), rectOriginal.Height(), pDC->m_hDC, 0,0, SRCCOPY);

    pDC->SelectFont(hOldFont);
    pDC->SelectBitmap(obmp);
	    
	  pDC->DeleteDC();
    bmp.DeleteObject();
	  if (pDC)
      delete pDC;

		return 0;
	}

  LRESULT OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		// Set to 1 for flicker free drawing
		return 1;
	}
	
  LRESULT OnSysColorChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
	  m_colorButtonFace   = ::GetSysColor(COLOR_BTNFACE);
		return 0;
	}
	LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
	  WORD cx, cy;
    cx = LOWORD(lParam);
    cy = HIWORD(lParam);

    // do this only once to initialise the button size
    static bool bDone(false);
    if (!bDone && m_pflatButton && m_pflatButton->m_hWnd)
    {
      MoveCaptionButton();
      bDone = true;
    }
		

		return 0;
	}

  void MoveCaptionButton()
  {
    CRect rect;
	  GetClientRect(&rect);
    
    if(m_pflatButton && m_pflatButton->m_hWnd)
	  {
		  CDC hDC(GetDC());
	    HFONT hOldFont;
      if (m_pCaptionTextFont)
        hOldFont = hDC.SelectFont(m_pCaptionTextFont->m_hFont);
      else
        hOldFont = hDC.SelectFont(m_defaultFont.m_hFont);

		  TEXTMETRIC tm;
		  hDC.GetTextMetrics(&tm);

		  CSize size; 
      hDC.GetTextExtent(m_sCaptionText, -1, &size);
		  size.cx += tm.tmAveCharWidth+19;
		  hDC.SelectFont(hOldFont);
		  ReleaseDC(hDC);
		  
		  CRect rc(0, 0, size.cx, rect.Height());
		  rc.DeflateRect(m_nBorder+1, m_nBorder+1);
		  m_pflatButton->MoveWindow(rc);
	  }
  }

  LRESULT OnFlatButton(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
    if (!m_bButtonPressed)
    {
      CRect rect, rc;
      m_pflatButton->GetWindowRect(&rect);
	    rc.left = rect.left - m_nBorder - 2;
      rc.right = rect.left + 160; // Width
	    rc.top = rect.bottom;
	    rc.bottom = rect.top + 500; // Height
        
		  CAPTIONBAR_INFO ob;
      ob.m_rect = rc;

      CWindow wnd(m_hOwnerWindow);
		  if (!wnd.SendMessage(WM_CAPTIONBAR_NOTIFY, NM_CBAR_BUTTONCLICKED, (LPARAM) &ob))
      {
        // Somethings gone wrong
      }
        
      m_pflatButton->SetState(TRUE);
      m_bButtonPressed = true;
    }
    m_pflatButton->SetState(TRUE);

    return 0;
	}

  LRESULT OnCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		bHandled = FALSE;
		return 1;
	}

  bool CreateButton()
  {
	  if (m_bCreateButtonOnText)
    {
      if (m_pflatButton)
        delete m_pflatButton;

      m_pflatButton = new CButtonST;

      if( !m_pflatButton->Create(m_hWnd, CRect(0,0,0,0), m_sCaptionText, 0, 0, IDC_FLAT_BUTTON ))
	    {
		    return false;
	    }

      m_pflatButton->SetInactiveBgColor(::GetSysColor(COLOR_BTNSHADOW));
	    m_pflatButton->SetActiveBgColor(::GetSysColor(COLOR_BTNSHADOW));
      m_pflatButton->SetShadowColor(::GetSysColor(COLOR_3DDKSHADOW));
      if (m_pCaptionTextFont)
        m_pflatButton->SetFont(m_pCaptionTextFont->m_hFont);
      else
        m_pflatButton->SetFont(m_defaultFont.m_hFont);
      m_pflatButton->SetTextColor(::GetSysColor(COLOR_WINDOW));
      m_pflatButton->DrawArrow(TRUE);
    
    }
    return true;
  }
  
};


/////////////////////////////////////////////////////////////////////////////

#endif // !defined(ATL_CAPTIONBAR_H)

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United Kingdom United Kingdom
Was made redundant in early 2003 after 10 years in computer programming, since then started my own business (selling computer books on the net)
www.pricecutbook.co.uk


Comments and Discussions