// TCMiniDockFraeWnd.cpp : implementation file
//
#include "stdafx.h"
#include "TCMiniDockFrameWnd.h"
#include "ToolsContainer.h"
#include "DockDef.h"
#include "Draw.h"
// CTCMiniDockFrameWnd
HHOOK CTCMiniDockFrameWnd::m_hMouseHook = NULL;
CTCMiniDockFrameWnd * CTCMiniDockFrameWnd::m_pThis = NULL;
IMPLEMENT_DYNCREATE(CTCMiniDockFrameWnd, CMiniDockFrameWnd)
CTCMiniDockFrameWnd::CTCMiniDockFrameWnd():
m_bXbuttonDown(FALSE),
m_bFullWindow(TRUE),
m_bTextAllShowing(TRUE),
m_bDragShowContent(FALSE)
{
Initialize();
}
CTCMiniDockFrameWnd::~CTCMiniDockFrameWnd()
{
}
BEGIN_MESSAGE_MAP(CTCMiniDockFrameWnd, CMiniDockFrameWnd)
ON_WM_CREATE()
ON_WM_NCPAINT()
ON_WM_NCLBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_NCCALCSIZE()
ON_WM_NCHITTEST()
ON_WM_NCACTIVATE()
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnTTipNotify)
ON_WM_SIZE()
ON_WM_DESTROY()
END_MESSAGE_MAP()
// CTCMiniDockFrameWnd message handlers
void CTCMiniDockFrameWnd::Initialize()
{
}
int CTCMiniDockFrameWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMiniDockFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
::SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &m_bDragShowContent, 0);
m_hMouseHook = ::SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MouseProc,
AfxGetInstanceHandle(), (DWORD)::GetCurrentThreadId());
m_pThis = this;
EnableToolTips();
return 0;
}
void CTCMiniDockFrameWnd::RecalcLayout(BOOL bNotify)
{
if((GetTCControlBar() != NULL) && (GetStyle() & WS_CAPTION))
{
ModifyStyle(WS_CAPTION | WS_THICKFRAME | WS_SYSMENU | 0x3300, WS_CLIPCHILDREN | 0x3501);
}
CMiniDockFrameWnd::RecalcLayout(bNotify);
}
CRect CTCMiniDockFrameWnd::CalcNcOffsetRect() const
{
return CRect(TCW_LEFTOFFSET, TCW_TOPOFFSET, TCW_RIGHTOFFSET, TCW_BOTTOMOFFSET);
}
void CTCMiniDockFrameWnd::CalcWindowRect(LPRECT lpClientRect, UINT nAdjustType)
{
DWORD dwExStyle = GetExStyle();
if (nAdjustType == 0)
dwExStyle &= ~WS_EX_CLIENTEDGE;
::AdjustWindowRectEx(lpClientRect, GetStyle(), FALSE, dwExStyle);
if(GetTCControlBar() != NULL)
{
CRect rect = lpClientRect;
rect.InflateRect(CalcNcOffsetRect());
lpClientRect->left = rect.left;
lpClientRect->top = rect.top;
lpClientRect->right = rect.right;
lpClientRect->bottom = rect.bottom;
}
}
void CTCMiniDockFrameWnd::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
{
// TODO: Add your message handler code here and/or call default
CMiniDockFrameWnd::OnNcCalcSize(bCalcValidRects, lpncsp);
if(GetTCControlBar() != NULL)
{
CRect rect = lpncsp->rgrc[0];
rect.DeflateRect(CalcNcOffsetRect());
lpncsp->rgrc[0] = rect;
}
}
CControlBar * CTCMiniDockFrameWnd::GetTCControlBar() const
{
CWnd *pWnd = m_wndDockBar.GetWindow(GW_CHILD);
if(pWnd == NULL || !pWnd->IsKindOf(RUNTIME_CLASS(CToolsContainer)))
{
pWnd = NULL;
}
return reinterpret_cast<CToolsContainer *>(pWnd);
}
void CTCMiniDockFrameWnd::OnNcPaint()
{
// TODO: Add your message handler code here
// Do not call CMiniDockFrameWnd::OnNcPaint() for painting messages
// CMiniDockFrameWnd::OnNcPaint();
if(GetTCControlBar() == NULL)
{
CMiniDockFrameWnd::OnNcPaint();
return;
}
CWindowDC dc(this);
CRect rectWindow, rectClient;
GetWindowRect(&rectWindow);
ScreenToClient(&rectWindow);
GetClientRect(rectClient);
rectClient.OffsetRect(-rectWindow.left, -rectWindow.top);
rectWindow.OffsetRect(-rectWindow.left, -rectWindow.top);
dc.ExcludeClipRect(rectClient);
dc.IntersectClipRect(rectWindow); // calc the non-client area for draw things
CBitmap bitmap;
CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
bitmap.CreateCompatibleBitmap(&dc, rectWindow.Width(), rectWindow.Height());
CBitmap *pOldbitmap = dcMem.SelectObject(&bitmap);
dcMem.FillSolidRect(rectWindow, ::GetSysColor(COLOR_BTNFACE)); //draw background
// draw the caption
DrawCaption(&dcMem, &rectWindow);
// draw bottom-right lines of border
CPoint m_ptRightBtm = CPoint(rectWindow.right - BORDER_OFFSET , rectWindow.bottom); // left-bottom point
CPoint m_ptBtmRight = CPoint(rectWindow.right , rectWindow.bottom - BORDER_OFFSET);
CPen m_cGdipen(PS_SOLID, 2, RGB(86,86,86));
CPen *pOldpen = dcMem.SelectObject(&m_cGdipen);
m_ptBtmRight.Offset(-1,-1);
m_ptRightBtm.Offset(-1,-1);
dcMem.MoveTo(m_ptRightBtm);
dcMem.LineTo(m_ptBtmRight);
dcMem.SelectObject(pOldpen);
// draw borders
DrawBorders(&dcMem, &rectWindow, RGB(86,86,86), 2);
DrawBorders(&dcMem, &rectWindow, RGB(121,121,123), 1); //
dc.BitBlt(0, 0, rectWindow.Width(), rectWindow.Height(), &dcMem, 0, 0, SRCCOPY);
dcMem.SelectObject(pOldbitmap);
dcMem.DeleteDC();
bitmap.DeleteObject();
}
void CTCMiniDockFrameWnd::DrawBorders(CDC *pDC, LPRECT lpRect, COLORREF crGdipen, int nOffset)
{
if(m_bFullWindow)
{
CPoint pts[] = {CPoint(2, lpRect->bottom - nOffset),
CPoint(lpRect->right - BORDER_OFFSET - nOffset, lpRect->bottom - nOffset),
CPoint(lpRect->right - nOffset, lpRect->bottom - BORDER_OFFSET - nOffset),
CPoint(lpRect->right - nOffset, 1)};
DrawBorders(pDC, pts, 4, crGdipen);
}
else
{
CPoint pts[] = {CPoint(2, lpRect->bottom - nOffset),
CPoint(m_rcWndCaption.right + (nOffset ^ 3), lpRect->bottom - nOffset),
CPoint(m_rcWndCaption.right + (nOffset ^ 3), lpRect->top)};
DrawBorders(pDC, pts, 3, crGdipen);
}
}
void CTCMiniDockFrameWnd::DrawBorders(CDC *pDC, LPPOINT points, int nCount, COLORREF crGdipen)
{
CPen m_cGdipen(PS_SOLID, 1, crGdipen);
CPen *pOldpen = pDC->SelectObject(&m_cGdipen);
pDC->Polyline(points, nCount);
pDC->SelectObject(pOldpen);
}
void CTCMiniDockFrameWnd::DrawCaption(CDC *pDC, LPRECT lpRect)
{
CBrush brCaption;
COLORREF cr = ::GetSysColor(m_bActive ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION);
brCaption.CreateSolidBrush(cr);
// calc caption rectangle
m_rcWndCaption.CopyRect(lpRect);
m_rcWndCaption.right = m_rcWndCaption.left + TCW_LEFTOFFSET;
m_rcWndCaption.DeflateRect(1, 1, 0, 3);
pDC->FillRect(&m_rcWndCaption, &brCaption);
// calc close button rectangle
m_rcButtonClose = m_rcWndCaption;
m_rcButtonClose.DeflateRect(2, 2, 3, 0);
m_rcButtonClose.bottom = m_rcButtonClose.top + m_rcButtonClose.Width();
// draw close button
DrawX(pDC, m_rcButtonClose);
// draw icon
CRect rectIcon = m_rcButtonClose;
HICON hIcon = (HICON)(DWORD_PTR)::GetClassLong(GetTCControlBar()->GetSafeHwnd(), GCL_HICONSM);
if(hIcon != NULL)
{
rectIcon.OffsetRect(0, rectIcon.Height() + 2);
ICONINFO ii;
GetIconInfo(hIcon, &ii);
::DrawIconEx(pDC->m_hDC, rectIcon.left + 2, rectIcon.top, hIcon, ii.xHotspot*2, ii.yHotspot*2, 0, NULL, DI_NORMAL);
}
// calc window title rectangle
m_rcWndTitle = rectIcon;
m_rcWndTitle.OffsetRect(0, m_rcButtonClose.Height() + 2);
m_rcWndTitle.bottom = m_rcWndCaption.bottom - 38;
// Draw Title
DrawTitle(pDC, m_rcWndTitle);
// calc pin bar rectangle
m_rcpinBar = m_rcButtonClose;
m_rcpinBar.OffsetRect(0, m_rcWndTitle.bottom + 4);
// draw pin bar
DrawpinBar(pDC, m_rcpinBar, cr);
brCaption.DeleteObject();
}
void CTCMiniDockFrameWnd::DrawX(CDC *pDC, LPRECT lpRect)
{
CRect rcX;
rcX.CopyRect(lpRect);
if(m_bXbuttonDown)
{
pDC->DrawEdge(rcX, BDR_SUNKENINNER, BF_RECT);
}
rcX.DeflateRect(4, 4);
rcX.OffsetRect(0, -1);
CPen penDraw;
LOGBRUSH logBrush;
logBrush.lbColor = ::GetSysColor(m_bActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT);
logBrush.lbStyle = BS_SOLID;
penDraw.CreatePen(PS_SOLID | PS_GEOMETRIC | PS_ENDCAP_ROUND, 2, &logBrush);
CPen *poldpen = pDC->SelectObject(&penDraw);
pDC->MoveTo(rcX.left, rcX.top);
pDC->LineTo(rcX.right, rcX.bottom);
pDC->MoveTo(rcX.right, rcX.top );
pDC->LineTo(rcX.left, rcX.bottom);
pDC->SelectObject(poldpen);
penDraw.De