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