You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1895 lines
54 KiB
C++

// XTPDockingPaneContext.cpp : implementation of the CXTPDockingPaneContext class.
//
// This file is a part of the XTREME DOCKINGPANE MFC class library.
// (c)1998-2012 Codejock Software, All Rights Reserved.
//
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
// CONSENT OF CODEJOCK SOFTWARE.
//
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
// SINGLE COMPUTER.
//
// CONTACT INFORMATION:
// support@codejock.com
// http://www.codejock.com
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Resource.h"
#include "Common/XTPColorManager.h"
#include "Common/XTPDrawHelpers.h"
#include "Common/XTPResourceManager.h"
#include "Common/XTPSystemHelpers.h"
#include "Common/XTPImageManager.h"
#include "TabManager/XTPTabManager.h"
#include "TabManager/XTPTabPaintManager.h"
#include "XTPDockingPaneDefines.h"
#include "XTPDockingPaneBase.h"
#include "XTPDockingPaneBaseContainer.h"
#include "XTPDockingPaneContext.h"
#include "XTPDockingPane.h"
#include "XTPDockingPaneManager.h"
#include "XTPDockingPaneTabbedContainer.h"
#include "XTPDockingPaneSplitterContainer.h"
#include "XTPDockingPaneMiniWnd.h"
#include "XTPDockingPaneSidePanel.h"
#include "XTPDockingPanePaintManager.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
void AFX_CDECL CXTPDockingPaneContext::AdjustRectangle(CRect& rect, CPoint pt)
{
int nXOffset = (pt.x < rect.left) ? (pt.x - rect.left - 6) :
(pt.x > rect.right) ? (pt.x - rect.right + 6) : 0;
int nYOffset = (pt.y < rect.top) ? (pt.y - rect.top - 6) :
(pt.y > rect.bottom) ? (pt.y - rect.bottom + 6) : 0;
rect.OffsetRect(nXOffset, nYOffset);
}
void AFX_CDECL CXTPDockingPaneContext::AdjustCursor(CPoint& pt)
{
CRect rc = XTPMultiMonitor()->GetWorkArea(pt);
if (pt.x < rc.left) pt.x = rc.left;
if (pt.x > rc.right) pt.x = rc.right;
if (pt.y < rc.top) pt.y = rc.top;
if (pt.y > rc.bottom) pt.y = rc.bottom;
}
typedef BOOL (WINAPI *PFNSETLAYEREDWINDOWATTRIBUTES) (HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
#ifndef LWA_ALPHA
#define LWA_ALPHA 0x00000002
#endif
#ifndef WS_EX_LAYERED
#define WS_EX_LAYERED 0x00080000
#endif
/////////////////////////////////////////////////////////////////////////////
// CXTPDockingPaneContextAlphaWnd
CXTPDockingPaneContextAlphaWnd::CXTPDockingPaneContextAlphaWnd()
{
}
CXTPDockingPaneContextAlphaWnd::~CXTPDockingPaneContextAlphaWnd()
{
}
BEGIN_MESSAGE_MAP(CXTPDockingPaneContextAlphaWnd, CWnd)
//{{AFX_MSG_MAP(CXTPDockingPaneContextAlphaWnd)
ON_WM_ERASEBKGND()
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CXTPDockingPaneContextAlphaWnd message handlers
BOOL CXTPDockingPaneContextAlphaWnd::OnEraseBkgnd(CDC* /*pDC*/)
{
return TRUE;
}
void CXTPDockingPaneContextAlphaWnd::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect rc;
GetClientRect(&rc);
dc.FillSolidRect(rc, GetSysColor(COLOR_HIGHLIGHT));
}
//////////////////////////////////////////////////////////////////////////
// CXTPDockingPaneContextStickerWnd
CXTPDockingPaneContextStickerWnd::CXTPDockingPaneContextStickerWnd(CXTPDockingPaneContext* pContext)
: m_pContext(pContext)
{
m_typeSticker = m_selectedSticker = xtpPaneStickerNone;
}
CXTPDockingPaneContextStickerWnd::~CXTPDockingPaneContextStickerWnd()
{
}
BEGIN_MESSAGE_MAP(CXTPDockingPaneContextStickerWnd, CWnd)
//{{AFX_MSG_MAP(CXTPDockingPaneContextStickerWnd)
ON_WM_ERASEBKGND()
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CXTPDockingPaneContextAlphaWnd message handlers
BOOL CXTPDockingPaneContextStickerWnd::OnEraseBkgnd(CDC* /*pDC*/)
{
return TRUE;
}
struct CXTPDockingPaneContextStickerWnd::SPRITEINFO
{
SPRITEINFO(int x, int y, int left, int top, int cx, int cy)
{
ptDest = CPoint(x, y);
rcSrc.SetRect(left, top, left + cx, top + cy);
}
CPoint ptDest;
CRect rcSrc;
};
#define SPRITE_STICKER_TOP 0
#define SPRITE_STICKER_LEFT 1
#define SPRITE_STICKER_BOTTOM 2
#define SPRITE_STICKER_RIGHT 3
#define SPRITE_STICKER_TOP_SELECTED 4
#define SPRITE_STICKER_LEFT_SELECTED 5
#define SPRITE_STICKER_BOTTOM_SELECTED 6
#define SPRITE_STICKER_RIGHT_SELECTED 7
#define SPRITE_STICKER_CENTER 8
#define SPRITE_STICKER_CENTER_SELECTED 9
#define SPRITE_STICKER_CLIENT 10
static CXTPDockingPaneContextStickerWnd::SPRITEINFO arrSpritesStyckerWidbey[] =
{
CXTPDockingPaneContextStickerWnd::SPRITEINFO(25, 0, 0, 0, 43, 30),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 25, 30, 33, 30, 43),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(25, 63, 43, 0, 43, 30),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(63, 25, 0, 33, 30, 43),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(25, 0, 0, 76, 43, 30),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 25, 90, 33, 30, 43),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(25, 63, 43, 76, 43, 30),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(63, 25, 60, 33, 30, 43),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(30, 30, 86, 0, 33, 33),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(30, 30, 86, 76, 33, 33),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(25, 25, 0, 0, 43, 43),
};
static CXTPDockingPaneContextStickerWnd::SPRITEINFO arrSpritesStyckerVisualStudio2005[] =
{
CXTPDockingPaneContextStickerWnd::SPRITEINFO(30, 0, 61, 29, 29, 30),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 30, 90, 30, 30, 29),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(30, 59, 91, 0, 29, 30),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(60, 30, 62, 0, 30, 29),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(30, 0, 61, 29 + 61, 29, 30),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 30, 90, 30 + 61, 30, 29),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(30, 59, 91, 0 + 61, 29, 30),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(60, 30, 62, 0 + 61, 30, 29),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(30, 30, 120, 82, 28, 29),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(24, 24, 120, 41, 41, 41),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(24, 24, 120, 0, 41, 41),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0, 29, 29, 32),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 29, 32, 32, 29),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 32, 0, 29, 32),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0, 0, 32, 29),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0, 29 + 61, 29, 32),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 29, 32 + 61, 32, 29),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 32, 0 + 61, 29, 32),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0, 0 + 61, 32, 29),
};
static CXTPDockingPaneContextStickerWnd::SPRITEINFO arrSpritesStyckerVisualStudio2008[] =
{
CXTPDockingPaneContextStickerWnd::SPRITEINFO(36, 0, 142, 35, 35, 35),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 35, 142 + 35, 35, 35, 35),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(36, 70, 142 + 35, 0, 35, 35),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(72, 35, 142, 0, 35, 35),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(36, 0, 212, 35, 35, 35),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 35, 212 + 35, 35, 35, 35),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(36, 70, 212 + 35, 0, 35, 35),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(72, 35, 212, 0, 35, 35),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(37, 38, 359, 0, 32, 31),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(37, 38, 359, 31, 32, 31),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(15, 15, 282, 0, 77, 75), // Client
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0, 35, 35, 36),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 35, 36, 36, 35),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 36, 0, 35, 36),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0, 0, 36, 35),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0 + 71, 35, 35, 36),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 35 + 71, 36, 36, 35),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 36 + 71, 0, 35, 36),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0 + 71, 0, 36, 35),
};
static CXTPDockingPaneContextStickerWnd::SPRITEINFO arrSpritesStyckerVisualStudio2010[] =
{
CXTPDockingPaneContextStickerWnd::SPRITEINFO(36, 0, 80, 40, 40, 40),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 36, 80 + 40, 40, 40, 40),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(36, 72, 80 + 40, 0, 40, 40),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(72, 36, 80, 0, 40, 40),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(36, 0, 80, 40 + 80, 40, 40),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 36, 80 + 40, 40 + 80, 40, 40),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(36, 72, 80 + 40, 0 + 80, 40, 40),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(72, 36, 80, 0 + 80, 40, 40),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(40, 40, 160, 120, 32, 32),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(40, 40, 192, 120, 32, 32),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 160, 0, 112, 112), // Client
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0, 40, 40, 40),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 40, 40, 40, 40),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 40, 0, 40, 40),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0, 0, 40, 40),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0, 40 + 80, 40, 40),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 40, 40 + 80, 40, 40),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 40, 0 + 80, 40, 40),
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0, 0 + 80, 40, 40),
};
void CXTPDockingPaneContextStickerWnd::DrawTransparent(CDC* pDC , const CPoint& ptDest, const CSize& sz, CBitmap* pBitmap)
{
CImageList il;
il.Create(sz.cx, sz.cy, ILC_COLOR24 | ILC_MASK, 0, 1);
il.Add(pBitmap, RGB(0, 0xFF, 0));
il.Draw(pDC, 0, ptDest, ILD_NORMAL);
}
void CXTPDockingPaneContextStickerWnd::DrawSprite(CDC* pDC, UINT nID, SPRITEINFO* pSpriteInfo, BOOL bClientBitmap)
{
CBitmap bmp;
{
CXTPResourceManager::CManageState state;
bmp.Attach(CXTPImageManagerIcon::LoadBitmapFromResource(MAKEINTRESOURCE(nID), NULL));
}
CSize sz(pSpriteInfo->rcSrc.Width(), pSpriteInfo->rcSrc.Height());
CBitmap bmpSprite;
bmpSprite.CreateCompatibleBitmap(pDC, sz.cx, sz.cy);
if (bmpSprite.GetSafeHandle())
{
CXTPCompatibleDC dcSprite(pDC, &bmpSprite);
CXTPCompatibleDC dc(pDC, &bmp);
dcSprite.BitBlt(0, 0, sz.cx, sz.cy, &dc, pSpriteInfo->rcSrc.left, pSpriteInfo->rcSrc.top, SRCCOPY);
}
CPoint ptDest = bClientBitmap ? pSpriteInfo->ptDest : CPoint(0, 0);
DrawTransparent(pDC, ptDest, sz, &bmpSprite);
}
void CXTPDockingPaneContextStickerWnd::OnDraw(CDC* pDC)
{
BOOL bClient = (m_typeSticker & xtpPaneStickerClient) == xtpPaneStickerClient;
XTPDockingContextStickerStyle style = m_pContext->GetStickerStyle();
if (style == xtpPaneStickerStyleVisualStudio2005Beta)
{
XTPCurrentSystemTheme theme = XTPColorManager()->GetCurrentSystemTheme();
UINT nIDBitmap = theme == xtpSystemThemeOlive ? XTP_IDB_DOCKINGPANE_STICKERS_OLIVE :
theme == xtpSystemThemeSilver ? XTP_IDB_DOCKINGPANE_STICKERS_SILVER : XTP_IDB_DOCKINGPANE_STICKERS_BLUE;
SPRITEINFO* sprites = arrSpritesStyckerWidbey;
if (bClient)
DrawSprite(pDC, XTP_IDB_DOCKINGPANE_STICKER_CLIENT, &sprites[SPRITE_STICKER_CLIENT]);
if (m_typeSticker & xtpPaneStickerTop)
DrawSprite(pDC, nIDBitmap, &sprites[m_selectedSticker == xtpPaneStickerTop ? SPRITE_STICKER_TOP_SELECTED : SPRITE_STICKER_TOP], bClient);
if (m_typeSticker & xtpPaneStickerLeft)
DrawSprite(pDC, nIDBitmap, &sprites[m_selectedSticker == xtpPaneStickerLeft ? SPRITE_STICKER_LEFT_SELECTED : SPRITE_STICKER_LEFT], bClient);
if (m_typeSticker & xtpPaneStickerBottom)
DrawSprite(pDC, nIDBitmap, &sprites[m_selectedSticker == xtpPaneStickerBottom ? SPRITE_STICKER_BOTTOM_SELECTED : SPRITE_STICKER_BOTTOM], bClient);
if (m_typeSticker & xtpPaneStickerRight)
DrawSprite(pDC, nIDBitmap, &sprites[m_selectedSticker == xtpPaneStickerRight ? SPRITE_STICKER_RIGHT_SELECTED : SPRITE_STICKER_RIGHT], bClient);
if (m_typeSticker & xtpPaneStickerCenter)
DrawSprite(pDC, nIDBitmap, &sprites[m_selectedSticker == xtpPaneStickerCenter ? SPRITE_STICKER_CENTER_SELECTED : SPRITE_STICKER_CENTER]);
}
else if (style == xtpPaneStickerStyleVisualStudio2008 || style == xtpPaneStickerStyleVisualStudio2010)
{
UINT nIDBitmap = style == xtpPaneStickerStyleVisualStudio2008 ? XTP_IDB_DOCKINGPANE_STICKERS_2008 : XTP_IDB_DOCKINGPANE_STICKERS_2010;
SPRITEINFO* sprites = style == xtpPaneStickerStyleVisualStudio2008 ? arrSpritesStyckerVisualStudio2008 : arrSpritesStyckerVisualStudio2010;
int nClientSprite = bClient ? 0 : 11;
if (bClient)
{
DrawSprite(pDC, nIDBitmap, &sprites[SPRITE_STICKER_CLIENT]);
if (m_typeSticker & xtpPaneStickerCenter)
DrawSprite(pDC, nIDBitmap, &sprites[m_selectedSticker == xtpPaneStickerCenter ? SPRITE_STICKER_CENTER_SELECTED : SPRITE_STICKER_CENTER]);
}
if (m_typeSticker & xtpPaneStickerTop)
DrawSprite(pDC, nIDBitmap, &sprites[nClientSprite + (m_selectedSticker == xtpPaneStickerTop ? SPRITE_STICKER_TOP_SELECTED : SPRITE_STICKER_TOP)], bClient);
if (m_typeSticker & xtpPaneStickerLeft)
DrawSprite(pDC, nIDBitmap, &sprites[nClientSprite + (m_selectedSticker == xtpPaneStickerLeft ? SPRITE_STICKER_LEFT_SELECTED : SPRITE_STICKER_LEFT)], bClient);
if (m_typeSticker & xtpPaneStickerBottom)
DrawSprite(pDC, nIDBitmap, &sprites[nClientSprite + (m_selectedSticker == xtpPaneStickerBottom ? SPRITE_STICKER_BOTTOM_SELECTED : SPRITE_STICKER_BOTTOM)], bClient);
if (m_typeSticker & xtpPaneStickerRight)
DrawSprite(pDC, nIDBitmap, &sprites[nClientSprite + (m_selectedSticker == xtpPaneStickerRight ? SPRITE_STICKER_RIGHT_SELECTED : SPRITE_STICKER_RIGHT)], bClient);
}
else
{
SPRITEINFO* sprites = arrSpritesStyckerVisualStudio2005;
int nClientSprite = bClient ? 0 : 11;
if (bClient)
DrawSprite(pDC, XTP_IDB_DOCKINGPANE_STICKERS_2005, &sprites[m_selectedSticker == xtpPaneStickerCenter ? SPRITE_STICKER_CENTER_SELECTED : SPRITE_STICKER_CLIENT]);
if (m_typeSticker & xtpPaneStickerTop)
DrawSprite(pDC, XTP_IDB_DOCKINGPANE_STICKERS_2005, &sprites[nClientSprite + (m_selectedSticker == xtpPaneStickerTop ? SPRITE_STICKER_TOP_SELECTED : SPRITE_STICKER_TOP)], bClient);
if (m_typeSticker & xtpPaneStickerLeft)
DrawSprite(pDC, XTP_IDB_DOCKINGPANE_STICKERS_2005, &sprites[nClientSprite + (m_selectedSticker == xtpPaneStickerLeft ? SPRITE_STICKER_LEFT_SELECTED : SPRITE_STICKER_LEFT)], bClient);
if (m_typeSticker & xtpPaneStickerBottom)
DrawSprite(pDC, XTP_IDB_DOCKINGPANE_STICKERS_2005, &sprites[nClientSprite + (m_selectedSticker == xtpPaneStickerBottom ? SPRITE_STICKER_BOTTOM_SELECTED : SPRITE_STICKER_BOTTOM)], bClient);
if (m_typeSticker & xtpPaneStickerRight)
DrawSprite(pDC, XTP_IDB_DOCKINGPANE_STICKERS_2005, &sprites[nClientSprite + (m_selectedSticker == xtpPaneStickerRight ? SPRITE_STICKER_RIGHT_SELECTED : SPRITE_STICKER_RIGHT)], bClient);
if (m_typeSticker & xtpPaneStickerCenter)
DrawSprite(pDC, XTP_IDB_DOCKINGPANE_STICKERS_2005, &sprites[SPRITE_STICKER_CENTER]);
}
}
void CXTPDockingPaneContextStickerWnd::OnPaint()
{
CPaintDC dcPaint(this); // device context for painting
CXTPBufferDC dc(dcPaint, CXTPClientRect(this));
OnDraw(&dc);
}
XTPDockingPaneStickerType CXTPDockingPaneContextStickerWnd::HitTest(CPoint pt)
{
CXTPClientRect rc(this);
ScreenToClient(&pt);
if (!rc.PtInRect(pt))
return xtpPaneStickerNone;
CClientDC dcClient(this);
CBitmap bmp;
bmp.CreateCompatibleBitmap(&dcClient, rc.Width(), rc.Height());
CXTPCompatibleDC dc(&dcClient, &bmp);
dc.FillSolidRect(rc, 0);
XTPDockingContextStickerStyle style = m_pContext->GetStickerStyle();
UINT nIDBitmap = style == xtpPaneStickerStyleVisualStudio2005 ? XTP_IDB_DOCKINGPANE_STICKERS_2005 :
style == xtpPaneStickerStyleVisualStudio2008 ? XTP_IDB_DOCKINGPANE_STICKERS_2008 :
style == xtpPaneStickerStyleVisualStudio2010 ? XTP_IDB_DOCKINGPANE_STICKERS_2010 : XTP_IDB_DOCKINGPANE_STICKERS_BLUE;
UINT nIDBitmapClient = style == xtpPaneStickerStyleVisualStudio2005Beta ? XTP_IDB_DOCKINGPANE_STICKER_CLIENT : nIDBitmap;
BOOL bClient = (m_typeSticker & xtpPaneStickerClient) == xtpPaneStickerClient;
SPRITEINFO* sprites = style == xtpPaneStickerStyleVisualStudio2005Beta ? arrSpritesStyckerWidbey :
style == xtpPaneStickerStyleVisualStudio2008 ? arrSpritesStyckerVisualStudio2008 :
style == xtpPaneStickerStyleVisualStudio2010 ? arrSpritesStyckerVisualStudio2010 : arrSpritesStyckerVisualStudio2005;
if (m_typeSticker & xtpPaneStickerTop)
{
DrawSprite(&dc, nIDBitmap, &sprites[SPRITE_STICKER_TOP], bClient);
if (dc.GetPixel(pt) != 0)
return xtpPaneStickerTop;
}
if (m_typeSticker & xtpPaneStickerLeft)
{
DrawSprite(&dc, nIDBitmap, &sprites[SPRITE_STICKER_LEFT], bClient);
if (dc.GetPixel(pt) != 0)
return xtpPaneStickerLeft;
}
if (m_typeSticker & xtpPaneStickerBottom)
{
DrawSprite(&dc, nIDBitmap, &sprites[SPRITE_STICKER_BOTTOM], bClient);
if (dc.GetPixel(pt) != 0)
return xtpPaneStickerBottom;
}
if (m_typeSticker & xtpPaneStickerRight)
{
DrawSprite(&dc, nIDBitmap, &sprites[SPRITE_STICKER_RIGHT], bClient);
if (dc.GetPixel(pt) != 0)
return xtpPaneStickerRight;
}
if (m_typeSticker & xtpPaneStickerCenter)
{
DrawSprite(&dc, nIDBitmapClient, &sprites[SPRITE_STICKER_CLIENT]);
if (dc.GetPixel(pt) != 0)
return xtpPaneStickerCenter;
}
return xtpPaneStickerNone;
}
//////////////////////////////////////////////////////////////////////////
// CXTPDockingPaneContext
CXTPDockingPaneContext::CXTPDockingPaneContext()
{
m_bUseAlphaContext = FALSE;
m_bUseDockingStickers = FALSE;
m_bDragKeyboard = FALSE;
m_pStickerPane = NULL;
m_pLastStickerPane = NULL;
m_pManager = NULL;
m_pPane = NULL;
m_pContainer = NULL;
m_bAttachLast = FALSE;
m_bSideDock = FALSE;
m_bAttach = FALSE;
m_bFloatable = TRUE;
m_bDockable = TRUE;
m_bDitherLast = FALSE;
m_containDirection = (XTPDockingPaneDirection)-1;
m_pDC = NULL;
m_pfnSetLayeredWindowAttributes = NULL;
HMODULE hLib = GetModuleHandle(_T("USER32"));
if (hLib)
{
m_pfnSetLayeredWindowAttributes = (PVOID) ::GetProcAddress(hLib, "SetLayeredWindowAttributes");
}
m_bResetDC = FALSE;
}
CXTPDockingPaneContext::~CXTPDockingPaneContext()
{
}
void CXTPDockingPaneContext::Drag(CXTPDockingPaneBase* pPane, CPoint point)
{
CRect rcPane = pPane->GetPaneWindowRect();
CWnd* pSite = pPane->GetDockingSite();
if (pSite && (pPane->GetType() == xtpPaneTypeDockingPane || pPane->GetType() == xtpPaneTypeTabbedContainer)
&& !pSite->IsKindOf(RUNTIME_CLASS(CXTPDockingPaneMiniWnd)))
{
CXTPDockingPane* pActivePane = pPane->GetType() == xtpPaneTypeTabbedContainer ?
((CXTPDockingPaneTabbedContainer*)pPane)->GetSelected() : (CXTPDockingPane*)pPane;
if (pActivePane)
{
CXTPDockingPaneTabbedContainer* pHolder = (CXTPDockingPaneTabbedContainer*)m_pManager->_GetHolder(pActivePane, TRUE);
pSite = pHolder ? pHolder->GetDockingSite() : NULL;
if (pSite && pSite->IsKindOf(RUNTIME_CLASS(CXTPDockingPaneMiniWnd)))
{
CRect rcFloating = ((CXTPDockingPaneMiniWnd*)pSite)->GetPaneWindowRect();
rcPane.right = rcPane.left + rcFloating.Width();
rcPane.bottom = rcPane.top + rcFloating.Height();
}
else if (!pHolder)
{
rcPane.right = rcPane.left + pActivePane->m_szDocking.cx;
rcPane.bottom = rcPane.top + pActivePane->m_szDocking.cy;
}
}
}
Drag(pPane, point, rcPane);
}
void CXTPDockingPaneContext::Drag(CXTPDockingPaneBase* pPane, CPoint pt, CRect rect)
{
m_bDragKeyboard = (pt == CPoint(-1, -1));
if (m_bDragKeyboard)
{
pt.x = rect.CenterPoint().x;
pt.y = rect.top + 15;
SetCursorPos(pt.x, pt.y);
}
m_ptSticky = m_ptLast = pt;
AdjustRectangle(rect, pt);
m_pPane = pPane;
m_rectDragFrameScreen = m_rectDragFrame = rect;
m_pDC = 0;
m_pContainer = 0;
m_bAttach = m_bAttachLast = FALSE;
m_bFloatable = TRUE;
m_bDockable = TRUE;
m_bSideDock = FALSE;
m_bUseAlphaContext = m_pManager->IsAlphaDockingContext() && (m_pfnSetLayeredWindowAttributes != NULL);
m_bUseDockingStickers = m_pManager->IsShowDockingContextStickers() && m_bUseAlphaContext;
CXTPDockingPaneBaseList lst;
pPane->FindPane(xtpPaneTypeDockingPane, &lst);
POSITION pos = lst.GetHeadPosition();
while (pos)
{
CXTPDockingPane* pListPane = (CXTPDockingPane*)lst.GetNext(pos);
if (m_pManager->NotifyAction(xtpPaneActionFloating, pListPane))
m_bFloatable = FALSE;
if (pListPane->GetOptions() & xtpPaneNoFloatable)
m_bFloatable = FALSE;
if (pListPane->GetOptions() & xtpPaneNoDockable)
m_bDockable = FALSE;
}
if (m_pManager->m_bShowSizeCursorWhileDragging)
{
SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEALL));
}
InitLoop();
Track();
}
void CXTPDockingPaneContext::InitLoop()
{
m_rectLast.SetRectEmpty();
m_sizeLast.cx = m_sizeLast.cy = 0;
m_bDitherLast = FALSE;
m_rectStickerPane.SetRectEmpty();
m_pStickerPane = NULL;
m_pLastStickerPane = NULL;
m_bResetDC = FALSE;
if (!m_bUseAlphaContext)
{
// handle pending WM_PAINT messages
MSG msg;
while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE))
{
if (!GetMessage(&msg, NULL, WM_PAINT, WM_PAINT))
return;
DispatchMessage(&msg);
}
// lock window update while dragging
ASSERT(m_pDC == NULL);
CWnd* pWnd = CWnd::GetDesktopWindow();
if (pWnd->LockWindowUpdate())
m_pDC = pWnd->GetDCEx(NULL, DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE);
else
m_pDC = pWnd->GetDCEx(NULL, DCX_WINDOW | DCX_CACHE);
ASSERT(m_pDC != NULL);
}
}
void CXTPDockingPaneContext::CancelLoop()
{
ReleaseCapture();
if (m_bUseAlphaContext)
{
m_wndContext.DestroyWindow();
m_wndAttachedTab.DestroyWindow();
DestroyDockingStickers();
POSITION pos = m_rgnStickers.GetStartPosition();
while (pos)
{
UINT nKey;
CRgn* pRgn;
m_rgnStickers.GetNextAssoc(pos, nKey, pRgn);
delete pRgn;
}
m_rgnStickers.RemoveAll();
}
else
{
DrawFocusRect(TRUE); // gets rid of focus rect
CWnd* pWnd = CWnd::GetDesktopWindow();
pWnd->UnlockWindowUpdate();
if (m_pDC != NULL)
{
pWnd->ReleaseDC(m_pDC);
m_pDC = NULL;
}
}
}
void CXTPDockingPaneContext::_CreateRectangleRgn(CRgn& rgnResult, CRect rc)
{
CRgn rgnOutside, rgnInside;
rgnOutside.CreateRectRgnIndirect(&rc);
CRect rect = rc;
rect.DeflateRect(4, 4);
rect.IntersectRect(rect, rc);
rgnInside.CreateRectRgnIndirect(rect);
rgnResult.CreateRectRgn(0, 0, 0, 0);
rgnResult.CombineRgn(&rgnOutside, &rgnInside, RGN_XOR);
}
void CXTPDockingPaneContext::_CreateRgn(CRgn& rgnResult, CRect rc, BOOL bTabbedRgn, BOOL bRemove)
{
if (bRemove)
{
rgnResult.CreateRectRgn(0, 0, 0, 0);
return;
}
if (bTabbedRgn)
{
CSize szTab(min(50, rc.Width() - 5), min(20, rc.Height() / 2));
CRect rcIntersect, rcTop(rc.left, rc.top, rc.right, rc.bottom - szTab.cy),
rcBottom(rc.left + 5, rc.bottom - szTab.cy - 4, rc.left + 5 + szTab.cx, rc.bottom);
CRgn rgnTop, rgnBottom, rgnIntersect;
rcIntersect.IntersectRect(rcTop, rcBottom);
rcIntersect.DeflateRect(4, 0);
_CreateRectangleRgn(rgnTop, rcTop);
_CreateRectangleRgn(rgnBottom, rcBottom);
_CreateRectangleRgn(rgnIntersect, rcIntersect);
rgnResult.CreateRectRgn(0, 0, 0, 0);
rgnResult.CombineRgn(&rgnBottom, &rgnTop, RGN_OR);
rgnResult.CombineRgn(&rgnResult, &rgnIntersect, RGN_XOR);
}
else
{
_CreateRectangleRgn(rgnResult, rc);
}
}
void CXTPDockingPaneContext::DrawFocusRect(BOOL bRemoveRect)
{
if (m_pManager->m_bShowContentsWhileDragging && m_pContainer == NULL &&
m_bFloatable && !m_bAttach && !m_rectDragFrame.IsRectEmpty())
{
CRect rect = m_rectDragFrame;
m_wndAttachedTab.DestroyWindow();
m_wndContext.DestroyWindow();
if (!m_bUseAlphaContext && !m_bResetDC)
{
ASSERT(m_pDC != NULL);
// determine new rect and size
rect.SetRectEmpty();
// first, determine the update region and select it
CRgn rgnNew, rgnLast, rgnUpdate;
_CreateRgn(rgnNew, rect, m_bAttach, TRUE);
_CreateRgn(rgnLast, m_rectLast, m_bAttachLast);
rgnUpdate.CreateRectRgn(0, 0, 0, 0);
rgnUpdate.CombineRgn(&rgnLast, &rgnNew, RGN_XOR);
// draw into the update/new region
m_pDC->SelectClipRgn(&rgnUpdate);
m_pDC->GetClipBox(&rect);
CBrush* pBrushOld = m_pDC->SelectObject(CDC::GetHalftoneBrush());
m_pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT);
// cleanup DC
if (pBrushOld != NULL)
m_pDC->SelectObject(pBrushOld);
m_pDC->SelectClipRgn(NULL);
CWnd* pWnd = CWnd::GetDesktopWindow();
pWnd->UnlockWindowUpdate();
if (m_pDC != NULL)
{
pWnd->ReleaseDC(m_pDC);
m_pDC = NULL;
}
m_bResetDC = TRUE;
}
if (m_pPane->GetType() == xtpPaneTypeSplitterContainer)
{
if (m_rectDragFrame != m_rectLast)
{
m_pPane->GetDockingSite()->MoveWindow(m_rectDragFrame);
}
}
else if (!bRemoveRect)
{
XTPDockingPaneAction actionNotify = xtpPaneActionFloated;
CXTPDockingPaneBaseList lst;
m_pPane->FindPane(xtpPaneTypeDockingPane, &lst);
if (m_rectDragFrame.top < 0)
m_rectDragFrame.OffsetRect(0, -m_rectDragFrame.top);
CXTPDockingPaneMiniWnd* pMiniWnd = m_pManager->FloatPane(m_pPane, m_rectDragFrame);
m_pManager->RecalcFrameLayout(m_pPane);
SAFE_CALLPTR(pMiniWnd, RecalcLayout());
m_pPane = pMiniWnd->GetTopPane();
POSITION pos = lst.GetHeadPosition();
while (pos)
{
CXTPDockingPane* pPane = (CXTPDockingPane*)lst.GetNext(pos);
m_pManager->NotifyAction(actionNotify, pPane);
}
XTPGetThread()->PumpMessage();
XTPGetThread()->OnIdle(0);
}
m_rectLast = rect;
m_bAttachLast = FALSE;
return;
}
if (m_bResetDC)
{
ASSERT(m_pDC == NULL);
ASSERT(m_bUseAlphaContext == FALSE);
// handle pending WM_PAINT messages
MSG msg;
while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE))
{
if (!GetMessage(&msg, NULL, WM_PAINT, WM_PAINT))
return;
DispatchMessage(&msg);
}
// lock window update while dragging
CWnd* pWnd = CWnd::GetDesktopWindow();
if (pWnd->LockWindowUpdate())
m_pDC = pWnd->GetDCEx(NULL, DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE);
else
m_pDC = pWnd->GetDCEx(NULL, DCX_WINDOW | DCX_CACHE);
ASSERT(m_pDC != NULL);
m_bResetDC = FALSE;
m_sizeLast.cx = m_sizeLast.cy = 0;
m_bDitherLast = FALSE;
m_rectLast.SetRectEmpty();
}
if (m_bUseAlphaContext)
{
ASSERT(bRemoveRect == FALSE);
CRect rect = (m_pContainer == 0) ? m_rectDragFrame : m_rectContainer;
m_rectLast = rect;
if (!m_bFloatable && m_pContainer == 0)
{
rect.SetRectEmpty();
}
if (m_bAttach != m_bAttachLast)
{
m_bAttachLast = m_bAttach;
if (m_bAttach)
CreateContextWindow(&m_wndAttachedTab);
else
m_wndAttachedTab.DestroyWindow();
}
if (m_bAttach)
{
CSize szTab(min(50, rect.Width() - 5), min(20, rect.Height() / 2));
CRect rcTab;
if (m_pManager->GetPaintManager()->GetTabPaintManager()->GetPosition() == xtpTabPositionTop
&& m_pContainer && m_pContainer->GetType() == xtpPaneTypeTabbedContainer)
{
if (((CXTPDockingPaneTabbedContainer*)m_pContainer)->IsTitleVisible())
{
rect.top += m_pManager->GetPaintManager()->GetCaptionHeight() + 3;
}
rect.top += szTab.cy;
rcTab = CRect(rect.left + 5, rect.top - szTab.cy, rect.left + 5 + szTab.cx, rect.top);
}
else
{
rect.bottom -= szTab.cy;
rcTab = CRect(rect.left + 5, rect.bottom, rect.left + 5 + szTab.cx, rect.bottom + szTab.cy);
}
m_wndAttachedTab.SetWindowPos(0, rcTab.left, rcTab.top, rcTab.Width(), rcTab.Height(), SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW);
}
if (m_wndContext.GetSafeHwnd() == 0 || CXTPWindowRect(&m_wndContext).Size() != rect.Size())
{
m_wndContext.DestroyWindow();
CreateContextWindow(&m_wndContext);
}
m_wndContext.SetWindowPos(0, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW);
}
else
{
ASSERT(m_pDC != NULL);
// determine new rect and size
CRect rect = (m_pContainer == 0) ? m_rectDragFrame : m_rectContainer;
if (!m_bFloatable && m_pContainer == 0)
rect.SetRectEmpty();
// first, determine the update region and select it
CRgn rgnNew, rgnLast, rgnUpdate;
_CreateRgn(rgnNew, rect, m_bAttach, bRemoveRect);
_CreateRgn(rgnLast, m_rectLast, m_bAttachLast);
rgnUpdate.CreateRectRgn(0, 0, 0, 0);
rgnUpdate.CombineRgn(&rgnLast, &rgnNew, RGN_XOR);
m_rectLast = rect;
m_bAttachLast = m_bAttach;
// draw into the update/new region
m_pDC->SelectClipRgn(&rgnUpdate);
m_pDC->GetClipBox(&rect);
CBrush* pBrushOld = m_pDC->SelectObject(CDC::GetHalftoneBrush());
m_pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT);
// cleanup DC
if (pBrushOld != NULL)
m_pDC->SelectObject(pBrushOld);
m_pDC->SelectClipRgn(NULL);
}
}
BOOL CXTPDockingPaneContext::CanSideDock(CXTPDockingPaneBase* pPane, CRect rcFrame)
{
CRect rc = pPane->GetPaneWindowRect();
rc.DeflateRect(m_pManager->GetSideDockingMargin());
int dSize = 10;
if (rc.Height() == 0 || rc.Width() == 0 || rcFrame.Height() == 0 || rcFrame.Width() == 0)
return FALSE;
if (!CRect().IntersectRect(rc, rcFrame))
return FALSE;
m_rectContainer.SetRectEmpty();
if (abs(rcFrame.top - rc.top) < dSize)
{
m_containDirection = xtpPaneDockTop;
m_rectContainer = CRect(rcFrame.left, rc.top, rcFrame.right, rc.top + rcFrame.Height());
dSize = abs(rcFrame.top - rc.top);
}
if (abs(rc.bottom - rcFrame.bottom) < dSize)
{
m_containDirection = xtpPaneDockBottom;
m_rectContainer = CRect(rcFrame.left, rc.bottom - rcFrame.Height(), rcFrame.right, rc.bottom);
dSize = abs(rc.bottom - rcFrame.bottom);
}
if (abs(rcFrame.left - rc.left) < dSize)
{
m_containDirection = xtpPaneDockLeft;
m_rectContainer = CRect(rc.left, rcFrame.top, rc.left + rcFrame.Width(), rcFrame.bottom);
dSize = abs(rcFrame.left - rc.left);
}
if (abs(rc.right - rcFrame.right) < dSize)
{
m_containDirection = xtpPaneDockRight;
m_rectContainer = CRect(rc.right - rcFrame.Width(), rcFrame.top, rc.right, rcFrame.bottom);
}
if (!m_rectContainer.IsRectEmpty())
{
if (!IsAllowDockingTo(pPane, m_containDirection))
return FALSE;
m_pContainer = pPane;
return TRUE;
}
return FALSE;
}
BOOL CXTPDockingPaneContext::CanDock(CRect rc, CPoint pt, CXTPDockingPaneBase* pPane, BOOL bInside)
{
double dSize = 20.0;
double dRatio = 1.0;
if (bInside && !m_bFloatable)
{
if (rc.Width() > 1 && rc.Height() > 1) dRatio = (double)rc.Height() / (double)rc.Width();
dSize = 32000.0;
}
if (rc.Height() == 0 || rc.Width() == 0)
return FALSE;
if (bInside && !rc.PtInRect(pt))
return FALSE;
if (!bInside && !CRect(rc.left - 20, rc.top - 20, rc.right + 20, rc.bottom + 20).PtInRect(pt))
return FALSE;
int nInside = bInside ? 1 : -1;
BOOL bFound = FALSE;
if ((double)abs(pt.y - rc.top) < dSize && nInside * (pt.y - rc.top) >= 0)
{
m_containDirection = xtpPaneDockTop;
dSize = (double)abs(pt.y - rc.top);
bFound = TRUE;
}
if ((double)abs(rc.bottom - pt.y) < dSize && nInside * (rc.bottom - pt.y) >= 0)
{
m_containDirection = xtpPaneDockBottom;
dSize = (double)abs(rc.bottom - pt.y);
bFound = TRUE;
}
if ((double)abs(pt.x - rc.left) * dRatio < dSize && nInside * (pt.x - rc.left) >= 0)
{
m_containDirection = xtpPaneDockLeft;
dSize = (double)abs(pt.x - rc.left) * dRatio;
bFound = TRUE;
}
if ((double)abs(rc.right - pt.x) * dRatio < dSize && nInside * (rc.right- pt.x) >= 0)
{
m_containDirection = xtpPaneDockRight;
bFound = TRUE;
}
if (bFound)
{
if (!IsAllowDockingTo(pPane, m_containDirection))
return FALSE;
m_rectContainer = m_pManager->_CalculateResultDockingRect(m_pPane, m_containDirection, pPane);
m_pContainer = pPane;
}
return bFound;
}
BOOL CXTPDockingPaneContext::IsAllowDockingTo(CXTPDockingPaneBase* pPane, XTPDockingPaneDirection direction)
{
CXTPDockingPaneBaseList lst;
m_pPane->FindPane(xtpPaneTypeDockingPane, &lst);
POSITION pos = lst.GetHeadPosition();
while (pos)
{
CXTPDockingPane* p = (CXTPDockingPane*)lst.GetNext(pos);
if (m_pManager->NotifyAction(xtpPaneActionDocking, p, pPane, direction))
{
return FALSE;
}
}
return TRUE;
}
BOOL CXTPDockingPaneContext::IsAllowAttachTo(CXTPDockingPaneBase* pPane)
{
CXTPDockingPaneBaseList lst;
m_pPane->FindPane(xtpPaneTypeDockingPane, &lst);
POSITION pos = lst.GetHeadPosition();
while (pos)
{
CXTPDockingPane* p = (CXTPDockingPane*)lst.GetNext(pos);
if (m_pManager->NotifyAction(xtpPaneActionAttaching, p, pPane))
{
return FALSE;
}
}
return TRUE;
}
BOOL CXTPDockingPaneContext::IsBehind(CXTPDockingPaneBase* pPaneBase, CXTPDockingPaneBase* pPaneTest)
{
CWnd* pFrameBase = pPaneBase->GetDockingSite();
if (!pFrameBase || !pFrameBase->IsKindOf(RUNTIME_CLASS(CXTPDockingPaneMiniWnd)))
return TRUE;
CWnd* pFrameTest = pPaneTest->GetDockingSite();
if (!pFrameTest || !pFrameTest->IsKindOf(RUNTIME_CLASS(CXTPDockingPaneMiniWnd)))
return FALSE;
HWND hWndNext = ::GetWindow(pFrameBase->GetSafeHwnd(), GW_HWNDNEXT);
while (hWndNext)
{
if (hWndNext == pFrameTest->GetSafeHwnd())
return FALSE;
hWndNext = ::GetWindow(hWndNext, GW_HWNDNEXT);
}
return TRUE;
}
void CXTPDockingPaneContext::FindContainer(CPoint pt)
{
CXTPDockingPaneInfoList* pList = &m_pManager->GetPaneList();
CXTPDockingPaneBase* pFloatingPane = NULL;
POSITION pos = pList->GetHeadPosition();
while (pos)
{
CXTPDockingPane* pNextPane = pList->GetNext(pos);
CXTPDockingPaneBase* pPane = pNextPane->GetContainer();
if (pPane == NULL)
continue;
ASSERT(pPane->GetType() == xtpPaneTypeTabbedContainer);
if (pPane->GetContainer() == 0 || pPane->GetContainer()->GetType() != xtpPaneTypeSplitterContainer)
continue;
if (! (::GetWindowLong(((CXTPDockingPaneTabbedContainer*)pPane)->GetSafeHwnd(), GWL_STYLE) & WS_VISIBLE))
continue;
if (m_pPane->ContainPane(pPane))
continue;
CRect rcClient = pPane->GetPaneWindowRect();
if (rcClient.PtInRect(pt) && pNextPane->IsFloating())
{
if (pFloatingPane == NULL || IsBehind(pFloatingPane, pPane))
{
pFloatingPane = pPane;
}
}
}
pos = pList->GetHeadPosition();
while (pos)
{
CXTPDockingPane* pNextPane = pList->GetNext(pos);
if (pNextPane->GetOptions() & xtpPaneNoDockable)
continue;
CXTPDockingPaneBase* pPane = pNextPane->GetContainer();
if (pPane == NULL)
continue;
if (pFloatingPane != NULL && pFloatingPane != pPane)
continue;
ASSERT(pPane->GetType() == xtpPaneTypeTabbedContainer);
if (pPane->GetContainer() == 0 || (pPane->GetContainer()->GetType() != xtpPaneTypeSplitterContainer && pPane->GetContainer()->GetType() != xtpPaneTypeSidePanel))
continue;
if (! (::GetWindowLong(((CXTPDockingPaneTabbedContainer*)pPane)->GetSafeHwnd(), GWL_STYLE) & WS_VISIBLE))
continue;
CRect rcClient = m_rectContainer = pPane->GetPaneWindowRect();
if (m_pPane->ContainPane(pPane))
continue;
if (((CXTPDockingPaneTabbedContainer*)pPane)->CanAttach(rcClient, pt))
{
if (IsAllowAttachTo(pPane))
{
m_pContainer = pPane;
m_bAttach = TRUE;
m_pStickerPane = 0;
m_rectStickerPane.SetRectEmpty();
return;
}
else
{
rcClient = m_rectContainer;
}
}
if (pPane->GetContainer()->GetType() == xtpPaneTypeSidePanel)
continue;
if (m_bUseDockingStickers)
{
if (rcClient.PtInRect(pt))
{
if (m_pStickerPane == NULL || IsBehind(m_pStickerPane, pPane))
{
m_rectStickerPane = m_rectContainer;
m_pStickerPane = pPane;
}
}
}
else
{
if (CanDock(rcClient, pt, pPane))
return;
}
}
if (pFloatingPane && m_bUseDockingStickers && m_pStickerPane == NULL && m_rectStickerPane.IsRectEmpty())
{
CXTPDockingPaneBase* pPane = m_pManager->GetTopPane();
if (pPane->GetPaneWindowRect().PtInRect(pt))
{
m_rectStickerPane = pPane->GetPaneWindowRect();
}
}
if (pFloatingPane)
return;
if (m_pManager->IsSideDockingEnabled())
{
if (CanSideDock(m_pManager->GetClientPane(), m_rectDragFrame))
{
m_bSideDock = TRUE;
return;
}
}
if (m_bUseDockingStickers)
{
if (m_pStickerPane)
{
return;
}
if (m_rectStickerPane.IsRectEmpty())
{
CXTPDockingPaneBase* pPane = m_pManager->GetClientPane();
if (pPane->GetPaneWindowRect().PtInRect(pt))
{
m_rectStickerPane = pPane->GetPaneWindowRect();
m_pStickerPane = pPane;
return;
}
pPane = m_pManager->GetTopPane();
if (pPane->GetPaneWindowRect().PtInRect(pt))
{
m_rectStickerPane = pPane->GetPaneWindowRect();
}
}
}
else
{
CXTPDockingPaneBase* pPane;
pPane = m_pManager->GetClientPane();
m_rectContainer = pPane->GetPaneWindowRect();
if (CanDock(pPane->GetPaneWindowRect(), pt, pPane))
return;
pPane = m_pManager->GetTopPane();
m_rectContainer = pPane->GetPaneWindowRect();
if (CanDock(pPane->GetPaneWindowRect(), pt, pPane, FALSE))
return;
}
}
void CXTPDockingPaneContext::EnsureVisible(CRect& rectDragFrame)
{
CRect rcWork = XTPMultiMonitor()->GetWorkArea(rectDragFrame);
int nGap = 10;
if (rcWork.bottom - rectDragFrame.top < nGap)
{
rectDragFrame.OffsetRect(0, rcWork.bottom - rectDragFrame.top - nGap);
}
if (rectDragFrame.bottom - rcWork.top < nGap)
{
rectDragFrame.OffsetRect(0, rcWork.top - rectDragFrame.bottom + nGap);
}
if (rcWork.right - rectDragFrame.left < nGap)
{
rectDragFrame.OffsetRect(rcWork.right - rectDragFrame.left - nGap, 0);
}
if (rectDragFrame.right - rcWork.left < nGap)
{
rectDragFrame.OffsetRect(rcWork.left - rectDragFrame.right + nGap, 0);
}
}
void CXTPDockingPaneContext::UpdateStickyFrame(CRect& rectDragFrame, CWnd* pHost)
{
int nGap = m_pManager->m_nStickyGap;
CXTPWindowRect rcWork(pHost);
if (rectDragFrame.bottom < rcWork.top - nGap || rectDragFrame.top > rcWork.bottom + nGap)
return;
if (rectDragFrame.right < rcWork.left - nGap || rectDragFrame.left > rcWork.right + nGap)
return;
if (abs(rcWork.bottom - rectDragFrame.top) < nGap)
{
rectDragFrame.OffsetRect(0, rcWork.bottom - rectDragFrame.top);
}
if (abs(rectDragFrame.bottom - rcWork.top) < nGap)
{
rectDragFrame.OffsetRect(0, rcWork.top - rectDragFrame.bottom);
}
if (abs(rcWork.left - rectDragFrame.right) < nGap)
{
rectDragFrame.OffsetRect(rcWork.left - rectDragFrame.right, 0);
}
if (abs(rectDragFrame.left - rcWork.right) < nGap)
{
rectDragFrame.OffsetRect(rcWork.right - rectDragFrame.left, 0);
}
if (abs(rectDragFrame.left - rcWork.left) < nGap)
{
rectDragFrame.OffsetRect(rcWork.left - rectDragFrame.left, 0);
}
if (abs(rectDragFrame.right - rcWork.right) < nGap)
{
rectDragFrame.OffsetRect(rcWork.right - rectDragFrame.right, 0);
}
if (abs(rectDragFrame.bottom - rcWork.bottom) < nGap)
{
rectDragFrame.OffsetRect(0, rcWork.bottom - rectDragFrame.bottom);
}
if (abs(rectDragFrame.top - rcWork.top) < nGap)
{
rectDragFrame.OffsetRect(0, rcWork.top - rectDragFrame.top);
}
}
void CXTPDockingPaneContext::UpdateStickyFrame(CRect& rectDragFrame)
{
CRect rcWork = XTPMultiMonitor()->GetWorkArea(rectDragFrame);
int nGap = m_pManager->m_nStickyGap;
if (abs(rcWork.top - rectDragFrame.top) < nGap)
{
rectDragFrame.OffsetRect(0, rcWork.top - rectDragFrame.top);
}
if (abs(rectDragFrame.bottom - rcWork.bottom) < nGap)
{
rectDragFrame.OffsetRect(0, rcWork.bottom - rectDragFrame.bottom);
}
if (abs(rcWork.right - rectDragFrame.right) < nGap)
{
rectDragFrame.OffsetRect(rcWork.right - rectDragFrame.right, 0);
}
if (abs(rectDragFrame.left - rcWork.left) < nGap)
{
rectDragFrame.OffsetRect(rcWork.left - rectDragFrame.left, 0);
}
if ((m_pManager->GetSite()->GetStyle() & (WS_MAXIMIZE | WS_MINIMIZE)) == 0)
UpdateStickyFrame(rectDragFrame, m_pManager->GetSite());
CXTPDockingPaneBaseList* pList = &m_pManager->GetPaneStack();
POSITION pos = pList->GetHeadPosition();
while (pos)
{
CXTPDockingPaneBase* pNextPane = pList->GetNext(pos);
if (pNextPane->GetType() != xtpPaneTypeMiniWnd)
continue;
CXTPDockingPaneMiniWnd* pWnd = (CXTPDockingPaneMiniWnd*)pNextPane;
if (pWnd->GetSafeHwnd() && pWnd->IsWindowVisible() && m_pPane->GetDockingSite() != pWnd)
{
UpdateStickyFrame(rectDragFrame, pWnd);
}
}
}
void CXTPDockingPaneContext::UpdateSizingStickyFrame(UINT nSide, CRect& rectDragFrame, CWnd* pHost)
{
int nGap = m_pManager->m_nStickyGap;
CXTPWindowRect rcWork(pHost);
if (rectDragFrame.bottom < rcWork.top - nGap || rectDragFrame.top > rcWork.bottom + nGap)
return;
if (rectDragFrame.right < rcWork.left - nGap || rectDragFrame.left > rcWork.right + nGap)
return;
if (abs(rectDragFrame.top - rcWork.bottom) < nGap && (nSide == WMSZ_TOP || nSide == WMSZ_TOPLEFT || nSide == WMSZ_TOPRIGHT))
{
rectDragFrame.top = rcWork.bottom;
}
if (abs(rectDragFrame.bottom - rcWork.top) < nGap && (nSide == WMSZ_BOTTOM || nSide == WMSZ_BOTTOMLEFT || nSide == WMSZ_BOTTOMRIGHT))
{
rectDragFrame.bottom = rcWork.top;
}
if (abs(rectDragFrame.left - rcWork.left) < nGap && (nSide == WMSZ_LEFT || nSide == WMSZ_TOPLEFT || nSide == WMSZ_BOTTOMLEFT))
{
rectDragFrame.left = rcWork.left;
}
if (abs(rectDragFrame.left - rcWork.right) < nGap && (nSide == WMSZ_LEFT || nSide == WMSZ_TOPLEFT || nSide == WMSZ_BOTTOMLEFT))
{
rectDragFrame.left = rcWork.right;
}
if (abs(rectDragFrame.right - rcWork.left) < nGap && (nSide == WMSZ_RIGHT || nSide == WMSZ_TOPRIGHT|| nSide == WMSZ_BOTTOMRIGHT))
{
rectDragFrame.right = rcWork.left;
}
if (abs(rectDragFrame.right - rcWork.right) < nGap && (nSide == WMSZ_RIGHT || nSide == WMSZ_TOPRIGHT|| nSide == WMSZ_BOTTOMRIGHT))
{
rectDragFrame.right = rcWork.right;
}
}
void CXTPDockingPaneContext::OnSizingFloatingFrame(CXTPDockingPaneMiniWnd* pMiniWnd, UINT nSide, LPRECT lpRect)
{
if (!m_pManager->IsStickyFloatingFrames())
return;
CRect rectDragFrame(lpRect);
if ((m_pManager->GetSite()->GetStyle() & (WS_MAXIMIZE | WS_MINIMIZE)) == 0)
UpdateSizingStickyFrame(nSide, rectDragFrame, m_pManager->GetSite());
CXTPDockingPaneBaseList* pList = &m_pManager->GetPaneStack();
POSITION pos = pList->GetHeadPosition();
while (pos)
{
CXTPDockingPaneBase* pNextPane = pList->GetNext(pos);
if (pNextPane->GetType() != xtpPaneTypeMiniWnd)
continue;
CXTPDockingPaneMiniWnd* pWnd = (CXTPDockingPaneMiniWnd*)pNextPane;
if (pWnd->GetSafeHwnd() && pWnd->IsWindowVisible() && pMiniWnd != pWnd)
{
UpdateSizingStickyFrame(nSide, rectDragFrame, pWnd);
}
}
*lpRect = rectDragFrame;
}
void CXTPDockingPaneContext::Move(CPoint pt)
{
CPoint ptOffset = pt - m_ptLast;
m_rectDragFrameScreen.OffsetRect(ptOffset);
if (CRect().IntersectRect(m_rectDragFrameScreen, XTPMultiMonitor()->GetWorkArea(m_rectDragFrame)))
{
m_rectDragFrame = m_rectDragFrameScreen;
}
EnsureVisible(m_rectDragFrame);
if (!m_rectDragFrame.IsRectEmpty() && m_pManager->m_bStickyFloatingFrames)
{
UpdateStickyFrame(m_rectDragFrame);
}
m_pContainer = 0;
m_bAttach = FALSE;
m_rectStickerPane.SetRectEmpty();
m_pStickerPane = NULL;
m_bSideDock = FALSE;
if (GetKeyState(VK_CONTROL) >= 0 && m_bDockable)
{
FindContainer(pt);
}
m_ptLast = pt;
if (m_bUseDockingStickers)
{
UpdateDockingStickers();
BOOL bFound = FALSE;
POSITION pos = m_lstStickers.GetTailPosition();
while (pos)
{
CXTPDockingPaneContextStickerWnd* pSticker = m_lstStickers.GetPrev(pos);
XTPDockingPaneStickerType selectedSticker = xtpPaneStickerNone;
if (!bFound)
{
XTPDockingPaneStickerType ht = pSticker->HitTest(pt);
if (ht != xtpPaneStickerNone)
{
if ((pSticker->m_typeSticker & xtpPaneStickerClient) == xtpPaneStickerClient)
{
m_pContainer = m_pStickerPane;
m_rectContainer = m_rectStickerPane;
}
else
{
m_pContainer = m_pManager->GetTopPane();
m_rectContainer = m_pContainer->GetPaneWindowRect();
}
switch (ht)
{
case xtpPaneStickerTop:
m_rectContainer.bottom = m_rectContainer.CenterPoint().y;
m_containDirection = xtpPaneDockTop;
break;
case xtpPaneStickerBottom:
m_rectContainer.top = m_rectContainer.CenterPoint().y;
m_containDirection = xtpPaneDockBottom;
break;
case xtpPaneStickerLeft:
m_rectContainer.right = m_rectContainer.CenterPoint().x;
m_containDirection = xtpPaneDockLeft;
break;
case xtpPaneStickerRight:
m_rectContainer.left = m_rectContainer.CenterPoint().x;
m_containDirection = xtpPaneDockRight;
break;
case xtpPaneStickerCenter:
m_bAttach = TRUE;
break;
}
BOOL bAllow = TRUE;
if ((ht != xtpPaneStickerCenter) && !IsAllowDockingTo(m_pContainer, m_containDirection))
{
m_pContainer = NULL;
bAllow = FALSE;
}
if ((ht == xtpPaneStickerCenter) && !IsAllowAttachTo(m_pContainer))
{
m_pContainer = NULL;
m_bAttach = FALSE;
bAllow = FALSE;
}
if (bAllow)
{
if (ht != xtpPaneStickerCenter)
m_rectContainer = m_pManager->_CalculateResultDockingRect(m_pPane, m_containDirection, m_pContainer);
selectedSticker = ht;
}
bFound = TRUE;
}
}
if (pSticker->m_selectedSticker != selectedSticker)
{
pSticker->m_selectedSticker = selectedSticker;
pSticker->Invalidate(FALSE);
}
}
}
DrawFocusRect();
}
void CXTPDockingPaneContext::Track()
{
// don't handle if capture already set
if (::GetCapture() != NULL)
return;
HWND hwndCapture = m_pManager->GetSite()->GetSafeHwnd();
ASSERT(hwndCapture);
if (!hwndCapture)
return;
// set capture to the window which received this message
::SetCapture(hwndCapture);
ASSERT(hwndCapture == ::GetCapture());
BOOL bAccept = FALSE;
// get messages until capture lost or cancelled/accepted
while (::GetCapture() == hwndCapture)
{
MSG msg;
// handle pending WM_PAINT messages
while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_REMOVE | PM_NOYIELD))
{
DispatchMessage(&msg);
}
if (!::GetMessage(&msg, NULL, 0, 0))
{
AfxPostQuitMessage((int)msg.wParam);
break;
}
if (msg.message == WM_LBUTTONUP)
{
bAccept = TRUE;
break;
}
else if (msg.message == WM_MOUSEMOVE)
{
CSize sz = m_ptSticky - CPoint(msg.pt);
if (abs(sz.cx) > 4 || abs(sz.cy) > 4)
{
Move(msg.pt);
m_ptSticky = CPoint(0, 0);
}
}
else if (msg.message == WM_KEYDOWN || msg.message == WM_KEYUP)
{
if (m_bDragKeyboard && msg.message == WM_KEYDOWN)
{
if (msg.wParam == VK_RETURN)
{
bAccept = TRUE;
break;
}
if (msg.wParam >= VK_LEFT && msg.wParam <= VK_DOWN)
{
CPoint pt(m_ptLast);
if (msg.wParam == VK_LEFT)
pt.x -= 10;
else if (msg.wParam == VK_RIGHT)
pt.x += 10;
else if (msg.wParam == VK_UP)
pt.y -= 10;
else if (msg.wParam == VK_DOWN)
pt.y += 10;
AdjustCursor(pt);
SetCursorPos(pt.x, pt.y);
Move(pt);
m_ptSticky = CPoint(0, 0);
}
}
if (msg.wParam == VK_CONTROL)
{
Move(m_ptLast);
m_ptSticky = CPoint(0, 0);
}
if (msg.wParam == VK_ESCAPE)
{
break;
}
}
else
DispatchMessage(&msg);
}
CancelLoop();
if (bAccept && m_ptSticky == CPoint(0, 0))
{
XTPDockingPaneAction actionNotify = xtpPaneActionFloated;
CXTPDockingPaneBaseList lst;
m_pPane->FindPane(xtpPaneTypeDockingPane, &lst);
if (m_bAttach)
{
ASSERT(m_pContainer->GetType() == xtpPaneTypeTabbedContainer);
m_pManager->AttachPane(m_pPane, m_pContainer);
actionNotify = xtpPaneActionAttached;
}
else if (m_bSideDock && m_pContainer && m_pContainer == m_pManager->GetClientPane())
{
CRect rectSide(m_rectContainer);
rectSide.OffsetRect(-m_pContainer->GetPaneWindowRect().TopLeft());
if (m_pPane->GetContainer() && m_pPane->GetContainer()->GetType() == xtpPaneTypeSidePanel)
((CXTPDockingPaneSidePanel*)m_pPane->GetContainer())->MovePanel(m_containDirection, rectSide);
else
m_pManager->DockSidePane(m_pPane, m_containDirection, rectSide);
actionNotify = xtpPaneActionDocked;
}
else if (m_pContainer)
{
m_pManager->DockPane(m_pPane, m_pManager->GetRTLDirection(m_containDirection), m_pContainer);
m_pManager->EnsureVisible(m_pContainer);
actionNotify = xtpPaneActionDocked;
}
else if (m_bFloatable)
{
CRect rcWork = XTPMultiMonitor()->GetWorkArea(m_rectDragFrame);
if (m_rectDragFrame.top < rcWork.top)
m_rectDragFrame.OffsetRect(0, rcWork.top - m_rectDragFrame.top);
if (m_pPane->GetType() == xtpPaneTypeSplitterContainer)
m_pPane->GetDockingSite()->MoveWindow(m_rectDragFrame);
else
m_pManager->FloatPane(m_pPane, m_rectDragFrame);
}
else
{
bAccept = FALSE;
}
if (bAccept)
{
POSITION pos = lst.GetHeadPosition();
while (pos)
{
CXTPDockingPane* pPane = (CXTPDockingPane*)lst.GetNext(pos);
m_pManager->NotifyAction(actionNotify, pPane, m_pContainer, m_containDirection);
}
}
}
}
void CXTPDockingPaneContext::DestroyDockingStickers()
{
while (!m_lstStickers.IsEmpty())
{
CWnd* pWnd = m_lstStickers.RemoveHead();
pWnd->DestroyWindow();
delete pWnd;
}
}
void CXTPDockingPaneContext::IncludeRgnPart(CRgn* pRgn, int x1, int y, int x2)
{
if (x1 < x2)
{
CRgn rgnExclude;
rgnExclude.CreateRectRgn(x1, y, x2, y + 1);
pRgn->CombineRgn(pRgn, &rgnExclude, RGN_OR);
}
}
void CXTPDockingPaneContext::RegionFromBitmap(CRgn* pRgn, CDC* pDC, CRect rc)
{
CSize sz = rc.Size();
pRgn->CreateRectRgn(0, 0, 0, 0);
for (int y = 0; y < sz.cy; y++)
{
int nStart = 0, x = 0;
BOOL bTransparent = TRUE;
while (x < sz.cx)
{
BOOL bTransparentPixel = pDC->GetPixel(x, y) == 0;
if (bTransparent && !bTransparentPixel)
{
nStart = x;
bTransparent = FALSE;
}
else if (!bTransparent && bTransparentPixel)
{
IncludeRgnPart(pRgn, nStart, y, x);
bTransparent = TRUE;
}
x++;
}
if (!bTransparent)
{
IncludeRgnPart(pRgn, nStart, y, x);
}
}
}
CXTPDockingPaneContextStickerWnd* CXTPDockingPaneContext::CreateNewSticker(CRect rc, XTPDockingPaneStickerType typeSticker)
{
if (typeSticker == xtpPaneStickerNone || typeSticker == xtpPaneStickerClient)
return NULL;
CXTPDockingPaneContextStickerWnd* pWnd = new CXTPDockingPaneContextStickerWnd(this);
m_lstStickers.AddTail(pWnd);
pWnd->CreateEx(WS_EX_TOOLWINDOW, AfxRegisterWndClass(NULL, AfxGetApp()->LoadStandardCursor(IDC_ARROW)),
0, WS_POPUP, CRect(0, 0, 0, 0), m_pManager->GetSite(), 0);
pWnd->m_typeSticker = typeSticker;
CRgn* pRgn = NULL;
if (!m_rgnStickers.Lookup(typeSticker, pRgn))
{
pRgn = new CRgn;
m_rgnStickers.SetAt(typeSticker, pRgn);
}
ASSERT(pRgn != NULL);
if (!pRgn)
return NULL;
if (!pRgn->GetSafeHandle())
{
CClientDC dcClient(pWnd);
CBitmap bmp;
bmp.CreateCompatibleBitmap(&dcClient, rc.Width(), rc.Height());
if (bmp.GetSafeHandle())
{
CXTPCompatibleDC dc(&dcClient, &bmp);
dc.FillSolidRect(rc, RGB(0, 0, 0));
pWnd->OnDraw(&dc);
RegionFromBitmap(pRgn, &dc, rc);
}
}
HRGN hRgn = ::CreateRectRgn(0, 0, 0, 0);
::CombineRgn(hRgn, (HRGN)pRgn->GetSafeHandle(), NULL, RGN_COPY);
pWnd->SetWindowRgn(hRgn, FALSE);
pWnd->SetWindowPos(0, rc.left, rc.top, rc.Width(), rc.Height(), SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW);
return pWnd;
}
CSize CXTPDockingPaneContext::GetStickerSize(XTPDockingPaneStickerType type) const
{
int cx, cy, sz;
if (GetStickerStyle() == xtpPaneStickerStyleVisualStudio2005)
{
cx = 32;
cy = 29;
sz = 89;
}
else if (GetStickerStyle() == xtpPaneStickerStyleVisualStudio2008)
{
cx = 36;
cy = 35;
sz = 109;
}
else if (GetStickerStyle() == xtpPaneStickerStyleVisualStudio2010)
{
cx = 40;
cy = 40;
sz = 112;
}
else
{
cx = 30;
cy = 43;
sz = 93;
}
if (type == xtpPaneStickerTop) return CSize(cy, cx);
if (type == xtpPaneStickerLeft) return CSize(cx, cy);
if (type == xtpPaneStickerBottom) return CSize(cy, cx);
if (type == xtpPaneStickerRight) return CSize(cx, cy);
return CSize(sz, sz);
}
XTPDockingContextStickerStyle CXTPDockingPaneContext::GetStickerStyle() const
{
return m_pManager->GetDockingContextStickerStyle();
}
void CXTPDockingPaneContext::UpdateDockingStickers()
{
if (m_rectStickerPane.IsRectEmpty())
{
m_pLastStickerPane = NULL;
DestroyDockingStickers();
return;
}
CSize sz(GetStickerSize(xtpPaneStickerClient));
CRect rc(m_rectStickerPane.CenterPoint(), sz);
rc.OffsetRect(- sz.cx / 2, - sz.cy / 2);
if (m_pLastStickerPane != m_pStickerPane || m_lstStickers.IsEmpty())
{
DestroyDockingStickers();
if (m_pStickerPane)
{
UINT allowStickers = xtpPaneStickerNone;
if (IsAllowDockingTo(m_pStickerPane, xtpPaneDockLeft)) allowStickers = allowStickers + xtpPaneStickerLeft;
if (IsAllowDockingTo(m_pStickerPane, xtpPaneDockRight)) allowStickers = allowStickers + xtpPaneStickerRight;
if (IsAllowDockingTo(m_pStickerPane, xtpPaneDockBottom)) allowStickers = allowStickers + xtpPaneStickerBottom;
if (IsAllowDockingTo(m_pStickerPane, xtpPaneDockTop)) allowStickers = allowStickers + xtpPaneStickerTop;
CreateNewSticker(rc, m_pStickerPane == m_pManager->GetClientPane() || !IsAllowAttachTo(m_pStickerPane) ? XTPDockingPaneStickerType(xtpPaneStickerClient + allowStickers) : XTPDockingPaneStickerType(xtpPaneStickerClient + allowStickers + xtpPaneStickerCenter));
}
CXTPDockingPaneBase* pTopPane = m_pManager->GetTopPane();
CRect rcWindow = pTopPane->GetPaneWindowRect();
if (IsAllowDockingTo(pTopPane, xtpPaneDockTop))
CreateNewSticker(CRect(CPoint(rcWindow.CenterPoint().x - GetStickerSize(xtpPaneStickerTop).cx / 2, rcWindow.top + 16), GetStickerSize(xtpPaneStickerTop)), xtpPaneStickerTop);
if (IsAllowDockingTo(pTopPane, xtpPaneDockLeft))
CreateNewSticker(CRect(CPoint(rcWindow.left + 16, rcWindow.CenterPoint().y - GetStickerSize(xtpPaneStickerLeft).cy/ 2), GetStickerSize(xtpPaneStickerLeft)), xtpPaneStickerLeft);
if (IsAllowDockingTo(pTopPane, xtpPaneDockBottom))
CreateNewSticker(CRect(CPoint(rcWindow.CenterPoint().x - GetStickerSize(xtpPaneStickerBottom).cx / 2, rcWindow.bottom - 16 - GetStickerSize(xtpPaneStickerBottom).cy), GetStickerSize(xtpPaneStickerBottom)), xtpPaneStickerBottom);
if (IsAllowDockingTo(pTopPane, xtpPaneDockRight))
CreateNewSticker(CRect(CPoint(rcWindow.right - GetStickerSize(xtpPaneStickerRight).cx - 16, rcWindow.CenterPoint().y - GetStickerSize(xtpPaneStickerRight).cy/ 2), GetStickerSize(xtpPaneStickerRight)), xtpPaneStickerRight);
m_pLastStickerPane = m_pStickerPane;
}
ASSERT(m_lstStickers.GetCount() < 6);
}
void CXTPDockingPaneContext::CreateContextWindow(CXTPDockingPaneContextAlphaWnd* pWnd)
{
ASSERT(m_bUseAlphaContext);
if (pWnd->GetSafeHwnd())
return;
pWnd->CreateEx(WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW, AfxRegisterWndClass(NULL, AfxGetApp()->LoadStandardCursor(IDC_ARROW)),
0, WS_POPUP, CRect(0, 0, 0, 0), m_pManager->GetSite(), 0);
if (m_pfnSetLayeredWindowAttributes)
{
((PFNSETLAYEREDWINDOWATTRIBUTES)m_pfnSetLayeredWindowAttributes)
(pWnd->m_hWnd, 0, 100, LWA_ALPHA);
}
}