// Copyright (c) 2002
// Sergey Klimov (kidd@ukr.net)
// WTL Docking windows
//
// This code is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified 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. If
// the source code in this file is used in any commercial application
// then a simple email woulod be nice.
#if !defined(AFX_EXTDOCKINGWINDOW_H__0CD64AFC_8687_4B20_8B8F_EE149C8C0E94__INCLUDED_)
#define AFX_EXTDOCKINGWINDOW_H__0CD64AFC_8687_4B20_8B8F_EE149C8C0E94__INCLUDED_
#include <DockingWindow.h>
namespace dockwins{
class COutlookLikeCaption : public CCaptionBase
{
typedef COutlookLikeCaption thisClass;
typedef CCaptionBase baseClass;
public:
enum{fntSpace=10,cFrameSpace=2,btnSpace=1};
protected:
typedef baseClass::CButton CButtonBase;
struct CButton : CButtonBase
{
virtual void CalculateRect(const CRect& rc,bool bHorizontal=true)
{
bHorizontal;// avoid level 4 warning
CopyRect(rc);
DeflateRect(cFrameSpace+btnSpace,cFrameSpace+btnSpace);
left=right-Height();
}
virtual void Draw (CDC& dc)=0;
virtual void Press(HWND hWnd)
{
CWindowDC dc(hWnd);
Draw(dc);
dc.DrawEdge(this,BDR_SUNKENOUTER/*|BF_ADJUST*/ ,BF_RECT); //look like button push
}
virtual void Release(HWND hWnd)
{
CWindowDC dc(hWnd);
Draw(dc);
}
virtual void Hot(HWND hWnd)
{
CWindowDC dc(hWnd);
Draw(dc);
dc.DrawEdge(this,BDR_RAISEDINNER/*|BF_ADJUST*/ ,BF_RECT); //look like button raise
}
};
class CCloseButton: public CButton
{
public:
virtual void Draw(CDC& dc)
{
dc.FillRect(this,(HBRUSH)LongToPtr(COLOR_3DFACE + 1));
CPen pen;
pen.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNTEXT));
HPEN hPenOld = dc.SelectPen(pen);
const sp=5;
dc.MoveTo(left+sp, top+sp);
dc.LineTo(right-sp, bottom-sp);
dc.MoveTo(left + sp+1, top+sp);
dc.LineTo(right - sp + 1, bottom - sp);
dc.MoveTo(left+sp, bottom - sp-1);
dc.LineTo(right-sp, top +sp -1 );
dc.MoveTo(left + sp +1, bottom - sp -1);
dc.LineTo(right - sp +1, top + sp -1);
dc.SelectPen(hPenOld);
}
};
public:
COutlookLikeCaption():baseClass(0,true)
{
m_hFont=reinterpret_cast<HFONT>(::GetStockObject(DEFAULT_GUI_FONT));
assert(m_hFont);
CDC dc(::GetDC(NULL));
HFONT hFontOld = dc.SelectFont(m_hFont);
TEXTMETRIC tm;
dc.GetTextMetrics(&tm);
dc.SelectFont(hFontOld);
m_thickness=tm.tmHeight+fntSpace;
}
void SetOrientation(bool /*bHorizontal*/)
{
// now only horizontal
}
bool CalculateRect(CRect& rc,bool bTop)
{
assert(IsHorizontal()); // now only horizontal
bool bRes=baseClass::CalculateRect(rc,bTop);
m_btnClose.CalculateRect(*this);
return bRes;
}
void Draw(HWND hWnd,CDC& dc)
{
assert(IsHorizontal()); // now only horizontal
dc.FillRect(this,(HBRUSH)LongToPtr(COLOR_3DFACE + 1));
dc.DrawEdge(this,EDGE_ETCHED,BF_RECT);
int len=GetWindowTextLength(hWnd)+1;
TCHAR* sText=new TCHAR[len];
if(GetWindowText(hWnd,sText,len)!=0)
{
dc.SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));
dc.SetBkMode(TRANSPARENT);
HFONT hFontOld = dc.SelectFont(m_hFont);
CRect rc(this);
rc.left+=fntSpace+cFrameSpace;
rc.right=m_btnClose.left-cFrameSpace-btnSpace;
if(rc.left<rc.right)
dc.DrawText(sText,-1,rc, DT_END_ELLIPSIS | DT_LEFT | DT_VCENTER | DT_SINGLELINE );
dc.SelectFont(hFontOld);
}
m_btnClose.Draw(dc);
delete sText;
}
LRESULT HitTest(const CPoint& pt) const
{
LRESULT lRes=HTNOWHERE;
if(PtInRect(pt))
{
lRes=HTCAPTION;
if(m_btnClose.PtInRect(pt))
lRes=HTCLOSE;
}
return lRes;
}
bool OnAction(HWND hWnd,unsigned int nHitTest)
{
bool bRes=true;
switch(nHitTest)
{
case HTCLOSE:
OnClose(hWnd);
break;
default:
bRes=false;
}
return bRes;
}
void HotTrack(HWND hWnd,unsigned int nHitTest)
{
if(nHitTest==HTCLOSE)
{
CHotBtnTracker<thisClass> tracker(m_btnClose,*this,hWnd,nHitTest);
TrackDragAndDrop(tracker,hWnd);
if(tracker)
::PostMessage(hWnd,WM_CLOSE,NULL,NULL);
}
}
void OnClose(HWND hWnd)
{
CBtnClickTracker tracker(hWnd,m_btnClose);
if(TrackDragAndDrop(tracker,hWnd))
{
CPoint pt;
CRect rc;
::GetWindowRect(hWnd,&rc);
::GetCursorPos(&pt);
pt.x-=rc.left;
pt.y-=rc.top;
if(HitTest(pt)==HTCLOSE)
::PostMessage(hWnd,WM_CLOSE,NULL,NULL);
}
}
protected:
CCloseButton m_btnClose;
HFONT m_hFont;
};
typedef CDockingWindowTraits<COutlookLikeCaption,
WS_OVERLAPPEDWINDOW | WS_POPUP | WS_VISIBLE |
WS_CLIPCHILDREN | WS_CLIPSIBLINGS,WS_EX_TOOLWINDOW>
COutlookLikeTitleDockingWindowTraits;
class CVC6LikeCaption : public CCaptionBase
{
typedef CVC6LikeCaption thisClass;
typedef CCaptionBase baseClass;
public:
enum{btnSpace=2,grThick=3};
protected:
typedef baseClass::CButton CButtonBase;
struct CButton : CButtonBase
{
virtual void CalculateRect(const CRect& rc,bool bHorizontal)
{
CopyRect(rc);
DeflateRect(btnSpace,btnSpace);
if(bHorizontal)
left=right-Height();
else
bottom=top+Width();
}
virtual void Draw (CDC& dc)=0;
virtual void Press(HWND hWnd)
{
CWindowDC dc(hWnd);
Draw(dc);
dc.DrawEdge(this,BDR_SUNKENOUTER/*|BF_ADJUST*/ ,BF_RECT); //look like button push
}
virtual void Release(HWND hWnd)
{
CWindowDC dc(hWnd);
Draw(dc);
}
virtual void Hot(HWND hWnd)
{
CWindowDC dc(hWnd);
Draw(dc);
dc.DrawEdge(this,BDR_RAISEDINNER/*|BF_ADJUST*/ ,BF_RECT); //look like button raise
}
};
class CCloseButton: public CButton
{
public:
virtual void Draw(CDC& dc)
{
dc.FillRect(this,(HBRUSH)LongToPtr(COLOR_3DFACE + 1));
CPen pen;
pen.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNTEXT));
HPEN hPenOld = dc.SelectPen(pen);
const sp=3;
dc.MoveTo(left+sp, top+sp);
dc.LineTo(right-sp, bottom-sp);
dc.MoveTo(left + sp+1, top+sp);
dc.LineTo(right - sp + 1, bottom - sp);
dc.MoveTo(left+sp, bottom - sp-1);
dc.LineTo(right-sp, top +sp -1 );
dc.MoveTo(left + sp +1, bottom - sp -1);
dc.LineTo(right - sp +1, top + sp -1);
dc.SelectPen(hPenOld);
}
};
public:
bool CalculateRect(CRect& rc,bool bTop)
{
bool bRes=baseClass::CalculateRect(rc,bTop);
m_btnClose.CalculateRect(*this,IsHorizontal());
return bRes;
}
void Draw(HWND /*hWnd*/,CDC& dc)
{
dc.FillRect(this,(HBRUSH)LongToPtr(COLOR_3DFACE + 1));
CRect rc;
if(IsHorizontal())
{
rc.left=left+btnSpace;
rc.right=m_btnClose.left-btnSpace;
if(rc.left<rc.right)
{
long offset=(m_btnClose.Height()-grThick*2/*+btnSpace*/)/2;
rc.top=m_btnClose.top+offset;
rc.bottom=rc.top+grThick;
dc.Draw3dRect(&rc, ::GetSysColor(COLOR_BTNHIGHLIGHT), ::GetSysColor(COLOR_BTNSHADOW));
rc.top=rc.bottom/*+btnSpace*/;
rc.bottom=rc.top+grThick;
dc.Draw3dRect(&rc, ::GetSysColor(COLOR_BTNHIGHLIGHT), ::GetSysColor(COLOR_BTNSHADOW));
}
}
else
{
rc.top=m_btnClose.bottom+btnSpace;
rc.bottom=bottom-btnSpace;
if(rc.top<rc.bottom)
{
long offset=(m_btnClose.Width()-grThick*2/*+btnSpace*/)/2;
rc.left=m_btnClose.left+offset;
rc.right=rc.left+grThick;
dc.Draw3dRect(&rc, ::GetSysColor(COLOR_BTNHIGHLIGHT), ::GetSysColor(COLOR_BTNSHADOW));
rc.left=rc.right/*+btnSpace*/;
rc.right=rc.left+grThick;
dc.Draw3dRect(&rc, ::GetSysColor(COLOR_BTNHIGHLIGHT), ::GetSysColor(COLOR_BTNSHADOW));
}
}
m_btnClose.Draw(dc);
}
LRESULT HitTest(const CPoint& pt) const
{
LRESULT lRes=HTNOWHERE;
if(PtInRect(pt))
{
lRes=HTCAPTION;
if(m_btnClose.PtInRect(pt))
lRes=HTCLOSE;
}
return lRes;
}
bool OnAction(HWND hWnd,unsigned int nHitTest)
{
bool bRes=true;
switch(nHitTest)
{
case HTCLOSE:
OnClose(hWnd);
break;
default:
bRes=false;
}
return bRes;
}
void HotTrack(HWND hWnd,unsigned int nHitTest)
{
if(nHitTest==HTCLOSE)
{
CHotBtnTracker<thisClass> tracker(m_btnClose,*this,hWnd,nHitTest);
TrackDragAndDrop(tracker,hWnd);
if(tracker)
::PostMessage(hWnd,WM_CLOSE,NULL,NULL);
}
}
void OnClose(HWND hWnd)
{
CBtnClickTracker tracker(hWnd,m_btnClose);
if(TrackDragAndDrop(tracker,hWnd))
{
CPoint pt;
CRect rc;
::GetWindowRect(hWnd,&rc);
::GetCursorPos(&pt);
pt.x-=rc.left;
pt.y-=rc.top;
if(HitTest(pt)==HTCLOSE)
::PostMessage(hWnd,WM_CLOSE,NULL,NULL);
}
}
protected:
CCloseButton m_btnClose;
};
typedef CDockingWindowTraits<CVC6LikeCaption,
WS_OVERLAPPEDWINDOW | WS_POPUP | WS_VISIBLE |
WS_CLIPCHILDREN | WS_CLIPSIBLINGS,WS_EX_TOOLWINDOW>
CVC6LikeTitleDockingWindowTraits;
}//namespace dockwins
#endif // !defined(AFX_EXTDOCKINGWINDOW_H__0CD64AFC_8687_4B20_8B8F_EE149C8C0E94__INCLUDED_)