Sorry, I didn't notice question. I hardly had time for looking to codeproject
If you still need this info:
CPanel::PtInTriangle() has default second argument set to ANCHOR_BOTTOMRIGHT:
CPanel::PtInTriangle( CPoint point, UINT nEdge = ANCHOR_BOTTOMRIGHT) const;
and ResizeGripperPanelName was defined as used before but declared as public static member, along with RootPanelName.
class WndResizer
{
public:
static const TCHAR ResizeGripperPanelName[];
static const TCHAR RootPanelName[];
...
};
and in WndResizer.cpp:
const TCHAR CWndResizer::ResizeGripperPanelName[] = _T("_resizeGrip");
const TCHAR CWndResizer::RootPanelName[] = _T("_root");
and below is full implementation i case someone will need it.
WndResizer.h
#pragma once
#define ANCHOR_LEFT 1
#define ANCHOR_TOP 2
#define ANCHOR_RIGHT 4
#define ANCHOR_BOTTOM 8
#define ANCHOR_HORIZONTALLY_CENTERED 16
#define ANCHOR_VERTICALLY_CENTERED 32
#define ANCHOR_PRIORITY_RIGHT 64 // by defualt, left has higher priority
#define ANCHOR_PRIORITY_BOTTOM 128 // by defualt, top has higher priority
#define ANCHOR_IGNORE 256 // if set, panel is ignored in layout computations
#define ANCHOR_TOPLEFT (ANCHOR_LEFT | ANCHOR_TOP)
#define ANCHOR_TOPRIGHT (ANCHOR_RIGHT | ANCHOR_TOP)
#define ANCHOR_BOTTOMLEFT (ANCHOR_LEFT | ANCHOR_BOTTOM)
#define ANCHOR_BOTTOMRIGHT (ANCHOR_RIGHT | ANCHOR_BOTTOM)
#define ANCHOR_VERTICALLY (ANCHOR_TOP | ANCHOR_BOTTOM)
#define ANCHOR_HORIZONTALLY (ANCHOR_LEFT | ANCHOR_RIGHT)
#define ANCHOR_ALL (ANCHOR_VERTICALLY | ANCHOR_HORIZONTALLY)
#define DOCK_NONE 0
#define DOCK_LEFT 1
#define DOCK_TOP 2
#define DOCK_RIGHT 3
#define DOCK_BOTTOM 4
#define DOCK_FILL 5
class CPanel;
class CUIPanel;
typedef CList<CPanel *, CPanel *> CPanelList;
class CPanel : public CRect
{
public:
CPanel();
CPanel(const CRect * prc);
virtual ~CPanel();
UINT Anchor;
UINT Dock;
CString Name;
CPanel * Parent;
CPanelList Children;
int LeftOffset;
int TopOffset;
int RightOffset;
int BottomOffset;
CSize MinSize;
CSize MaxSize;
BOOL m_bVisible;
virtual void OnResized();
virtual BOOL AddChild(CPanel * prc);
virtual BOOL RemoveChild(CPanel * prc);
virtual BOOL SetAnchor(UINT anchor);
virtual BOOL SetMinSize(CSize & size);
virtual BOOL SetMaxSize(CSize & size);
virtual BOOL SetOffset(UINT anchor, int offset);
virtual BOOL SetVisible(BOOL bVisible);
virtual BOOL GetVisible(BOOL &bVisible);
virtual BOOL IsVisible();
virtual CString ToString();
virtual CString GetTypeName();
virtual CWnd * GetHookedWnd();
BOOL PtInTriangle( CPoint point, UINT nEdge = ANCHOR_BOTTOMRIGHT ) const;
static BOOL PtInTriangle( CPoint point, CPoint v1, CPoint v2, CPoint v3 );
private:
void Init();
};
class CRootPanel : public CPanel
{
public:
CRootPanel();
~CRootPanel();
virtual CWnd * GetHookedWnd();
CWnd * m_pHookWnd;
virtual CString GetTypeName();
};
class CWndResizer
{
public:
static const TCHAR ResizeGripperPanelName[];
static const TCHAR RootPanelName[];
enum SplitterOrientation
{
SPLIT_CONTAINER_H = 1,
SPLIT_CONTAINER_V = 2,
};
enum FlowDirection
{
LEFT_TO_RIGHT = 3,
TOP_TO_BOTTOM = 4,
};
enum FixedPanel
{
FIXED_NONE = 0,
FIXED_TOPLEFT = 1,
FIXED_BOTTOMRIGHT = 2,
FIXED_TOPLEFT_HIDDEN = 3,
FIXED_BOTTOMRIGHT_HIDDEN = 4,
FIXED_LEFT = FIXED_TOPLEFT,
FIXED_TOP = FIXED_TOPLEFT,
FIXED_RIGHT = FIXED_BOTTOMRIGHT,
FIXED_BOTTOM = FIXED_BOTTOMRIGHT,
FIXED_LEFT_HIDDEN = FIXED_TOPLEFT_HIDDEN,
FIXED_TOP_HIDDEN = FIXED_TOPLEFT_HIDDEN,
FIXED_RIGHT_HIDDEN = FIXED_BOTTOMRIGHT_HIDDEN,
FIXED_BOTTOM_HIDDEN = FIXED_BOTTOMRIGHT_HIDDEN,
};
enum ResizeGrip
{
RESIZE_GRIP_HIDDEN = 0,
RESIZE_GRIP_VISIBLE = 1,
RESIZE_GRIP_VISIBLE_ACTIVE_RECT = 2,
RESIZE_GRIP_VISIBLE_ACTIVE_TRIANGLE = 2
};
public:
CWndResizer(void);
~CWndResizer(void);
BOOL Hook(CWnd * pWnd);
BOOL Hook(CWnd * pWnd, CSize & size);
BOOL Unhook();
BOOL CreatePanel(UINT uID);
BOOL CreatePanel(LPCTSTR panelName, const CUIntArray * parrID, BOOL setAsChildren = FALSE);
BOOL CreatePanel(LPCTSTR panelName, const UINT * parrID, BOOL setAsChildren = FALSE);
BOOL CreatePanel(LPCTSTR panelName, const CRect * prcPanel);
BOOL CreateSplitContainer(LPCTSTR splitContainerName, LPCTSTR panelNameA, LPCTSTR panelNameB);
BOOL CreateSplitContainer(LPCTSTR splitContainerName, LPCTSTR panelNameA, UINT panelIDB);
BOOL CreateSplitContainer(LPCTSTR splitContainerName, UINT panelIDA, UINT panelIDB);
BOOL CreateSplitContainer(LPCTSTR splitContainerName, UINT panelIDA, LPCTSTR panelNameB);
BOOL CreateFlowLayoutPanel(LPCTSTR panelName, const CUIntArray * parrID, BOOL setAsChildren = FALSE);
BOOL CreateFlowLayoutPanel(LPCTSTR panelName, const UINT * parrID, BOOL setAsChildren = FALSE);
BOOL CreateFlowLayoutPanel(LPCTSTR panelName, const CRect * prcPanel);
BOOL SetAnchor(LPCTSTR panelName, UINT anchor);
BOOL SetAnchor(UINT panelID, UINT anchor);
BOOL GetAnchor(LPCTSTR panelName, UINT & anchor);
BOOL GetAnchor(UINT panelID, UINT & anchor);
BOOL SetOffset(LPCTSTR panelName, UINT anchor, int offset);
BOOL SetOffset(UINT panelID, UINT anchor, int offset);
BOOL SetDock(LPCTSTR panelName, UINT anchor);
BOOL SetDock(UINT panelID, UINT anchor);
BOOL GetDock(LPCTSTR panelName, UINT & anchor);
BOOL GetDock(UINT panelID, UINT & anchor);
BOOL SetParent(LPCTSTR panelName, LPCTSTR parentName);
BOOL SetParent(UINT panelID, LPCTSTR parentName);
BOOL SetParent(LPCTSTR panelName, UINT parentID);
BOOL SetParent(UINT panelID, UINT parentID);
BOOL GetParent(LPCTSTR panelName, CString & parentName);
BOOL GetParent(UINT panelID, CString & parentName);
BOOL SetMinimumSize(LPCTSTR panelName, CSize & size);
BOOL SetMinimumSize(UINT panelID, CSize & size);
BOOL GetMinimumSize(LPCTSTR panelName, CSize & size) ;
BOOL GetMinimumSize(UINT panelID, CSize & size) ;
BOOL SetMaximumSize(LPCTSTR panelName, CSize & size);
BOOL SetMaximumSize(UINT panelID, CSize & size);
BOOL GetMaximumSize(LPCTSTR panelName, CSize & size) ;
BOOL GetMaximumSize(UINT panelID, CSize & size) ;
BOOL SetFixedPanel(LPCTSTR splitContainerName, short panel);
BOOL GetFixedPanel(LPCTSTR splitContainerName, short & panel);
BOOL SetIsSplitterFixed(LPCTSTR splitContainerName, BOOL fixed);
BOOL GetIsSplitterFixed(LPCTSTR splitContainerName, BOOL &fixed);
BOOL SetFlowDirection(LPCTSTR flowPanelName, short direction);
BOOL GetFlowDirection(LPCTSTR flowPanelName, short &direction);
BOOL SetFlowItemSpacingX(LPCTSTR flowPanelName, int nSpacing);
BOOL GetFlowItemSpacingX(LPCTSTR flowPanelName, int &nSpacing);
BOOL SetFlowItemSpacingY(LPCTSTR flowPanelName, int nSpacing);
BOOL GetFlowItemSpacingY(LPCTSTR flowPanelName, int &nSpacing);
BOOL SetShowSplitterGrip(LPCTSTR splitContainerName, BOOL bShow);
BOOL GetShowSplitterGrip(LPCTSTR splitContainerName, BOOL & bShow);
void SetShowResizeGrip(ResizeGrip show = RESIZE_GRIP_VISIBLE_ACTIVE_TRIANGLE);
void SetShowResizeGrip(BOOL show);
ResizeGrip GetShowResizeGrip();
BOOL SetSplitterPosition(LPCTSTR splitContainerName, UINT position);
BOOL GetSplitterPosition(LPCTSTR splitContainerName, UINT & position);
BOOL InvokeOnResized();
CString GetDebugInfo();
private:
CWnd * m_pHookedWnd;
CRootPanel root;
CPanel * m_pCaptured;
HCURSOR m_hOldCursor;
int m_splitterOffset;
CUIPanel * CreateUIPanel(UINT uID);
CUIPanel * GetUIPanel(UINT uID);
CString IdToName(UINT uID);
CPanel * FindPanelByName(CPanel * pRoot, LPCTSTR name);
CPanel * FindSplitterFromPoint(CPanel * pRoot, CPoint point);
void GetUIPanels(CPanel * pRoot, CPanelList * pList, BOOL bOle);
void GetVisualPanels(CPanel * pRoot, CPanelList * pList);
void ResizeUI(CPanel * pRoot);
void GetTrueClientRect(CWnd * pWnd, CRect * prc);
void EnsureRootMinMax();
void UpdateSplitterOffset(CPoint ptCurr);
void GetDebugInfo(CPanel * pRoot, CString & info, CString indent);
void OnPaint();
void OnSize(UINT nType, int cx, int cy);
void OnSizing(UINT fwSide, LPRECT pRect);
void OnScroll();
void OnDestroy();
void OnLButtonDown(UINT nFlags, CPoint point);
void OnMouseMove(UINT nFlags, CPoint point);
void OnLButtonUp(UINT nFlags, CPoint point);
LRESULT OnNcHitTest( CPoint point ); void OnThemeChanged();
WNDPROC m_pfnWndProc;
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
};
WndResizer.cpp
#include "StdAfx.h"
#include "WndResizer.h"
#include "uxtheme.h"
#pragma comment(lib, "UxTheme.lib")
static CMap<HWND, HWND, CWndResizer *, CWndResizer *> WndResizerData;
class CUIPanel : public CPanel
{
public:
CUIPanel(const CRect * prc, UINT uID);
~CUIPanel();
UINT m_uID; BOOL m_bOle; virtual BOOL SetVisible(BOOL bVisible);
virtual BOOL GetVisible(BOOL &bVisible);
virtual BOOL IsVisible();
virtual CString GetTypeName();
};
class CVisualPanel : public CPanel
{
public:
CVisualPanel();
CVisualPanel(const CRect * prc);
~CVisualPanel();
virtual void Draw(CDC * pDC);
virtual CString GetTypeName();
virtual void OnResized();
private:
CRect m_rcPrev;
};
class CGripperPanel : public CVisualPanel
{
public:
CGripperPanel();
CGripperPanel(const CRect * prc);
~CGripperPanel();
virtual void Draw(CDC * pDC);
virtual CString GetTypeName();
private:
HTHEME m_hTheme;
};
class CSplitterGripperPanel : public CVisualPanel
{
public:
CSplitterGripperPanel(CWndResizer::SplitterOrientation type);
~CSplitterGripperPanel();
virtual void Draw(CDC * pDC);
virtual CString GetTypeName();
private:
CWndResizer::SplitterOrientation m_OrienType;
};
#ifdef USE_SPLIT_PANEL
class CSplitPanel : public CPanel
{
public:
CSplitPanel(CPanel * pPanel);
~CSplitPanel();
virtual BOOL SetAnchor(UINT anchor);
virtual BOOL AddChild(CPanel * prc);
virtual BOOL RemoveChild(CPanel * prc);
virtual CString GetTypeName();
virtual BOOL SetMinSize(CSize & size);
virtual BOOL SetMaxSize(CSize & size);
private:
CPanel * m_pOriginalPanel;
};
#else
typedef CPanel CSplitPanel;
#endif
class CSpitterPanel : public CPanel
{
public:
CSpitterPanel(CWndResizer::SplitterOrientation type);
CSpitterPanel(const CRect * prc, CWndResizer::SplitterOrientation type);
~CSpitterPanel();
virtual CString GetTypeName();
CSplitterGripperPanel * m_pGrippePanel;
private:
CWndResizer::SplitterOrientation m_OrienType;
};
class CSplitContainer : public CPanel
{
public:
CSplitContainer(CSplitPanel * pPanelA, CSplitPanel * pPanelB, CWndResizer::SplitterOrientation type);
~CSplitContainer();
virtual void OnResized();
virtual BOOL AddChild(CPanel * prc);
virtual BOOL RemoveChild(CPanel * prc);
virtual CString GetTypeName();
void SetSplitterPosition(int leftOfSpliter );
int GetSplitterPosition();
void SetFixedPanel(short nFixedPanel );
short GetFixedPanel();
void SetIsSplitterFixed(BOOL bFixed);
BOOL GetIsSplitterFixed();
void SetShowSplitterGrip(BOOL bShow);
BOOL GetShowSplitterGrip();
static CSplitContainer * Create(CPanel * pPanelA, CPanel * pPanelB);
CWndResizer::SplitterOrientation m_Orientation;
private:
BOOL m_IsSplitterFixed;
short m_FixedPanel;
double m_nRatio;
int m_nSplitterSize; void GetSplitArea(CRect * pSplitterPanel);
int GetSplitterSize(CPanel * pLeftPanel, CPanel * pRightPanel);
void UpdateRatio();
CSplitPanel * m_pPanelA;
CSplitPanel * m_pPanelB;
CSpitterPanel * m_pSplitter;
};
class CFlowLayoutPanel : public CPanel
{
public:
CFlowLayoutPanel();
CFlowLayoutPanel(const CRect * prc);
~CFlowLayoutPanel();
virtual void OnResized();
virtual CString GetTypeName();
void SetFlowDirection(CWndResizer::FlowDirection direction);
CWndResizer::FlowDirection GetFlowDirection();
void SetItemSpacingX(int nSpace);
int GetItemSpacingX();
void SetItemSpacingY(int nSpace);
int GetItemSpacingY();
private:
int m_nItemSpacingX;
int m_nItemSpacingY;
CWndResizer::FlowDirection m_nFlowDirection;
};
const TCHAR CWndResizer::ResizeGripperPanelName[] = _T("_resizeGrip");
const TCHAR CWndResizer::RootPanelName[] = _T("_root");
CWndResizer::CWndResizer(void)
{
m_pHookedWnd = NULL;
m_pfnWndProc = NULL;
root.Name = RootPanelName;
m_pCaptured = NULL;
m_hOldCursor = NULL;
m_splitterOffset = 0;
}
CWndResizer::~CWndResizer(void)
{
}
static BOOL CALLBACK MakeGroupBoxesTransparent(HWND hwnd, LPARAM)
{
TCHAR className[128] = _T("");
int iRet = GetClassName(hwnd, className, ARRAYSIZE(className) - 1);
LONG style = GetWindowLong(hwnd, GWL_STYLE);
if ( 0 == _tcscmp(className, _T("Button")) && BS_GROUPBOX == (style & BS_GROUPBOX) ){
CWnd::ModifyStyleEx(hwnd, NULL, WS_EX_TRANSPARENT, NULL);
}
return TRUE;
}
BOOL CWndResizer::Hook(CWnd * pParent)
{
ASSERT( m_pHookedWnd == NULL );
m_pHookedWnd = pParent;
GetTrueClientRect(m_pHookedWnd, &root);
root.m_pHookWnd = m_pHookedWnd;
CRect rcResziGrip(&root);
int cx = ::GetSystemMetrics(SM_CXHSCROLL);
int cy = ::GetSystemMetrics(SM_CYVSCROLL);
rcResziGrip.DeflateRect(root.Width() - cx, root.Height() - cy, 0, 0);
CGripperPanel * pResizeGripper = new CGripperPanel(&rcResziGrip);
pResizeGripper->SetAnchor( ANCHOR_RIGHT | ANCHOR_BOTTOM );
pResizeGripper->Name = ResizeGripperPanelName;
root.AddChild( pResizeGripper );
WndResizerData.SetAt(m_pHookedWnd->m_hWnd, this);
CWnd::ModifyStyle(pParent->GetSafeHwnd(), NULL, WS_CLIPCHILDREN | WS_CLIPSIBLINGS, NULL);
EnumChildWindows(pParent->GetSafeHwnd(), MakeGroupBoxesTransparent, NULL);
m_pfnWndProc = (WNDPROC)::SetWindowLongPtr(m_pHookedWnd->m_hWnd, GWLP_WNDPROC, (LONG_PTR)WindowProc);
return TRUE;
}
BOOL CWndResizer::Hook(CWnd * pParent, CSize & size)
{
ASSERT( m_pHookedWnd == NULL );
m_pHookedWnd = pParent;
GetTrueClientRect(m_pHookedWnd, &root);
root.right = root.left + size.cx;
root.bottom = root.top + size.cy;
root.m_pHookWnd = m_pHookedWnd;
CRect rcResziGrip(&root);
int cx = ::GetSystemMetrics(SM_CXHSCROLL);
int cy = ::GetSystemMetrics(SM_CYVSCROLL);
rcResziGrip.DeflateRect(root.Width() - cx, root.Height() - cy, 0, 0);
CGripperPanel * pResizeGripper = new CGripperPanel(&rcResziGrip);
pResizeGripper->SetAnchor( ANCHOR_RIGHT | ANCHOR_BOTTOM );
pResizeGripper->Name = ResizeGripperPanelName;
root.AddChild( pResizeGripper );
WndResizerData.SetAt(m_pHookedWnd->m_hWnd, this);
CWnd::ModifyStyle(pParent->GetSafeHwnd(), NULL, WS_CLIPCHILDREN | WS_CLIPSIBLINGS, NULL);
EnumChildWindows(pParent->GetSafeHwnd(), MakeGroupBoxesTransparent, NULL);
m_pfnWndProc = (WNDPROC)::SetWindowLongPtr(m_pHookedWnd->m_hWnd, GWLP_WNDPROC, (LONG_PTR)WindowProc);
return TRUE;
}
BOOL CWndResizer::Unhook()
{
if (m_pHookedWnd == NULL )
return FALSE;
WNDPROC pWndProc = (WNDPROC)::SetWindowLongPtr(m_pHookedWnd->m_hWnd, GWLP_WNDPROC, (LONG_PTR)m_pfnWndProc);
WndResizerData.RemoveKey(m_pHookedWnd->m_hWnd);
root.m_pHookWnd = NULL;
m_pHookedWnd = NULL;
while(root.Children.GetCount() > 0 )
{
CPanel * pChild = root.Children.RemoveHead();
delete pChild;
}
return TRUE;
}
BOOL CWndResizer::CreatePanel(UINT uID)
{
ASSERT(m_pHookedWnd != NULL);
if (FindPanelByName(&root, IdToName(uID)) != NULL)
{
return FALSE;
}
CUIPanel * pPanel = GetUIPanel(uID);
ASSERT(pPanel != NULL);
pPanel->m_bOle = TRUE;
return TRUE;
}
BOOL CWndResizer::CreatePanel(LPCTSTR panelName, const CUIntArray * parrID, BOOL setAsChildren)
{
ASSERT(m_pHookedWnd != NULL);
CRect rcFinal(0, 0, 0, 0);
for(int i = 0; i < parrID->GetCount(); i++)
{
CRect rc(0, 0, 0, 0);
m_pHookedWnd->GetDlgItem(parrID->GetAt(i))->GetWindowRect(&rc);
m_pHookedWnd->ScreenToClient(&rc);
rcFinal.UnionRect(&rcFinal, &rc);
}
BOOL bOk = CreatePanel(panelName, &rcFinal);
if (bOk == FALSE)
{
return FALSE;
}
if ( setAsChildren )
{
CPanel * pPanel = FindPanelByName(&root, panelName);
for(int i = 0; i < parrID->GetCount(); i++)
{
if (FindPanelByName(&root, IdToName(parrID->GetAt(i))) != NULL)
{
bOk = root.RemoveChild(pPanel);
ASSERT( bOk );
delete pPanel;
return FALSE;
}
CUIPanel * pUIPanel = GetUIPanel(parrID->GetAt(i));
ASSERT( pUIPanel != NULL);
bOk = pPanel->AddChild( pUIPanel );
ASSERT( bOk );
}
}
return TRUE;
}
BOOL CWndResizer::CreatePanel(LPCTSTR panelName, const UINT * parrID, BOOL setAsChildren)
{
ASSERT(m_pHookedWnd != NULL);
CRect rcFinal(0, 0, 0, 0);
for(int i = 0; parrID[i]; i++)
{
CRect rc(0, 0, 0, 0);
m_pHookedWnd->GetDlgItem(parrID[i])->GetWindowRect(&rc);
m_pHookedWnd->ScreenToClient(&rc);
rcFinal.UnionRect(&rcFinal, &rc);
}
BOOL bOk = CreatePanel(panelName, &rcFinal);
if (bOk == FALSE)
{
return FALSE;
}
if ( setAsChildren )
{
CPanel * pPanel = FindPanelByName(&root, panelName);
for(int i = 0; parrID[i]; i++)
{
if (FindPanelByName(&root, IdToName(parrID[i])) != NULL)
{
bOk = root.RemoveChild(pPanel);
ASSERT( bOk );
delete pPanel;
return FALSE;
}
CUIPanel * pUIPanel = GetUIPanel(parrID[i]);
ASSERT( pUIPanel != NULL);
bOk = pPanel->AddChild( pUIPanel );
ASSERT( bOk );
}
}
return TRUE;
}
BOOL CWndResizer::CreatePanel(LPCTSTR panelName, const CRect * prcPanel)
{
if (FindPanelByName(&root, panelName) != NULL)
return FALSE;
CPanel * pPanel = new CPanel(prcPanel);
pPanel->Name = panelName;
return root.AddChild(pPanel);
}
BOOL CWndResizer::CreateSplitContainer(LPCTSTR panelName, LPCTSTR panelNameA, LPCTSTR panelNameB)
{
CPanel * pPanel = NULL;
if ((pPanel = FindPanelByName(&root, panelName)) != NULL)
return FALSE;
CPanel * pPanelA = NULL;
if ((pPanelA = FindPanelByName(&root, panelNameA)) == NULL)
return FALSE;
CPanel * pPanelB = NULL;
if ((pPanelB = FindPanelByName(&root, panelNameB)) == NULL)
return FALSE;
if (pPanelA == pPanelB) return FALSE;
CPanel * pSplitterContainer = CSplitContainer::Create(pPanelA, pPanelB);
if (pSplitterContainer == NULL)
return FALSE;
pSplitterContainer->Name = panelName;
return root.AddChild(pSplitterContainer);
}
BOOL CWndResizer::CreateSplitContainer(LPCTSTR panelName, LPCTSTR panelNameA, UINT panelIDB)
{
CPanel * pPanel = NULL;
if ((pPanel = FindPanelByName(&root, panelName)) != NULL)
return FALSE;
CPanel * pPanelA = NULL;
if ((pPanelA = FindPanelByName(&root, panelNameA)) == NULL)
return FALSE;
CPanel * pPanelB = GetUIPanel(panelIDB);
if (pPanelB == NULL )
return FALSE;
if (pPanelA == pPanelB) return FALSE;
CPanel * pSplitterContainer = CSplitContainer::Create(pPanelA, pPanelB);
if (pSplitterContainer == NULL)
return FALSE;
pSplitterContainer->Name = panelName;
return root.AddChild(pSplitterContainer);
}
BOOL CWndResizer::CreateSplitContainer(LPCTSTR panelName, UINT panelIDA, LPCTSTR panelNameB)
{
CPanel * pPanel = NULL;
if ((pPanel = FindPanelByName(&root, panelName)) != NULL)
return FALSE;
CPanel * pPanelA = GetUIPanel(panelIDA);
if (pPanelA == NULL )
return FALSE;
CPanel * pPanelB = NULL;
if ((pPanelB = FindPanelByName(&root, panelNameB)) == NULL)
return FALSE;
if (pPanelA == pPanelB) return FALSE;
CPanel * pSplitterContainer = CSplitContainer::Create(pPanelA, pPanelB);
if (pSplitterContainer == NULL)
return FALSE;
pSplitterContainer->Name.Append(panelName);
return root.AddChild(pSplitterContainer);
}
BOOL CWndResizer::CreateSplitContainer(LPCTSTR panelName, UINT panelIDA, UINT panelIDB)
{
CPanel * pPanel = NULL;
if ((pPanel = FindPanelByName(&root, panelName)) != NULL)
return FALSE;
CPanel * pPanelA = GetUIPanel(panelIDA);
if (pPanelA == NULL )
return FALSE;
CPanel * pPanelB = GetUIPanel(panelIDB);
if (pPanelB == NULL )
return FALSE;
if (pPanelA == pPanelB) return FALSE;
CPanel * pSplitterContainer = CSplitContainer::Create(pPanelA, pPanelB);
if (pSplitterContainer == NULL)
return FALSE;
pSplitterContainer->Name = panelName;
return root.AddChild(pSplitterContainer);
}
BOOL CWndResizer::CreateFlowLayoutPanel(LPCTSTR panelName, const CUIntArray * parrID, BOOL setAsChildren)
{
ASSERT(m_pHookedWnd != NULL);
CRect rcFinal(0, 0, 0, 0);
for(int i = 0; i < parrID->GetCount(); i++)
{
CRect rc(0, 0, 0, 0);
m_pHookedWnd->GetDlgItem(parrID->GetAt(i))->GetWindowRect(&rc);
m_pHookedWnd->ScreenToClient(&rc);
rcFinal.UnionRect(&rcFinal, &rc);
}
BOOL bOk = CreateFlowLayoutPanel(panelName, &rcFinal);
if (bOk == FALSE)
{
return FALSE;
}
if ( setAsChildren )
{
CPanel * pPanel = FindPanelByName(&root, panelName);
for(int i = 0; i < parrID->GetCount(); i++)
{
if (FindPanelByName(&root, IdToName(parrID->GetAt(i))) != NULL)
{
bOk = root.RemoveChild(pPanel);
ASSERT( bOk );
delete pPanel;
return FALSE;
}
CUIPanel * pUIPanel = GetUIPanel(parrID->GetAt(i));
ASSERT( pUIPanel != NULL);
bOk = pPanel->AddChild( pUIPanel );
ASSERT( bOk );
}
}
return TRUE;
}
BOOL CWndResizer::CreateFlowLayoutPanel(LPCTSTR panelName, const UINT * parrID, BOOL setAsChildren)
{
ASSERT(m_pHookedWnd != NULL);
CRect rcFinal(0, 0, 0, 0);
for(int i = 0; parrID[i] != 0; i++)
{
CRect rc(0, 0, 0, 0);
m_pHookedWnd->GetDlgItem(parrID[i])->GetWindowRect(&rc);
m_pHookedWnd->ScreenToClient(&rc);
rcFinal.UnionRect(&rcFinal, &rc);
}
BOOL bOk = CreateFlowLayoutPanel(panelName, &rcFinal);
if (bOk == FALSE)
return FALSE;
if ( setAsChildren )
{
CPanel * pPanel = FindPanelByName(&root, panelName);
for(int i = 0; parrID[i] != 0; i++)
{
if (FindPanelByName(&root, IdToName(parrID[i])) != NULL)
{
bOk = root.RemoveChild(pPanel);
ASSERT( bOk );
delete pPanel;
return FALSE;
}
CUIPanel * pUIPanel = GetUIPanel(parrID[i]);
ASSERT( pUIPanel != NULL);
bOk = pPanel->AddChild( pUIPanel );
ASSERT( bOk );
}
}
return TRUE;
}
BOOL CWndResizer::CreateFlowLayoutPanel(LPCTSTR panelName, const CRect * prcPanel)
{
if (FindPanelByName(&root, panelName) != NULL)
{
return FALSE;
}
CPanel * pPanel = new CFlowLayoutPanel(prcPanel);
pPanel->Name = panelName;
return root.AddChild(pPanel);
}
BOOL CWndResizer::SetAnchor(LPCTSTR panelName, UINT uAnchor)
{
CPanel * pPanel = NULL;
if ( (pPanel = FindPanelByName(&root, panelName)) == NULL)
{
return FALSE;
}
return pPanel->SetAnchor(uAnchor);
}
BOOL CWndResizer::SetAnchor(UINT uID, UINT uAnchor)
{
ASSERT(m_pHookedWnd != NULL);
CUIPanel * pPanel = GetUIPanel(uID);
if (pPanel == NULL)
return FALSE;
pPanel->SetAnchor(uAnchor);
return TRUE;
}
BOOL CWndResizer::GetAnchor(LPCTSTR panelName, UINT & anchor)
{
CPanel * pPanel = NULL;
if ( (pPanel = FindPanelByName(&root, panelName)) == NULL) return FALSE;
anchor = pPanel->Anchor;
return TRUE;
}
BOOL CWndResizer::GetAnchor(UINT uID, UINT & anchor)
{
CPanel * pPanel = NULL;
if ( (pPanel = FindPanelByName(&root, IdToName(uID))) == NULL) return FALSE;
anchor = pPanel->Anchor;
return TRUE;
}
BOOL CWndResizer::SetOffset(LPCTSTR panelName, UINT anchor, int offset)
{
CPanel * pPanel = FindPanelByName(&root, panelName);
if (pPanel == NULL)
return FALSE;
return pPanel->SetOffset( anchor, offset );
}
BOOL CWndResizer::SetOffset(UINT uID, UINT anchor, int offset)
{
ASSERT(m_pHookedWnd != NULL);
CUIPanel * pPanel = GetUIPanel(uID);
if (pPanel == NULL)
return FALSE;
return pPanel->SetOffset( anchor, offset );
}
BOOL CWndResizer::SetDock(LPCTSTR panelName, UINT uDock)
{
CPanel * pPanel = NULL;
if ( (pPanel = FindPanelByName(&root, panelName)) == NULL)
{
return FALSE;
}
pPanel->Dock = uDock ;
return TRUE;
}
BOOL CWndResizer::SetDock(UINT uID, UINT uDock)
{
ASSERT(m_pHookedWnd != NULL);
CUIPanel * pPanel = GetUIPanel(uID);
if (pPanel == NULL)
{
return FALSE;
}
pPanel->Dock = uDock;
return TRUE;
}
BOOL CWndResizer::GetDock(LPCTSTR panelName, UINT & uDock)
{
CPanel * pPanel = NULL;
if ( (pPanel = FindPanelByName(&root, panelName)) == NULL) {
return FALSE;
}
uDock = pPanel->Dock;
return TRUE;
}
BOOL CWndResizer::GetDock(UINT uID, UINT & uDock)
{
CPanel * pPanel = NULL;
if ( (pPanel = FindPanelByName(&root, IdToName(uID))) == NULL) {
return FALSE;
}
uDock = pPanel->Dock;
return TRUE;
}
BOOL CWndResizer::SetParent(LPCTSTR panelName, LPCTSTR parentName)
{
ASSERT(m_pHookedWnd != NULL);
CPanel * pParent = NULL;
if ( (pParent = FindPanelByName(&root, parentName)) == NULL) {
return FALSE;
}
CPanel * pPanel = NULL;
if ((pPanel = FindPanelByName(&root, panelName)) == NULL)
{
return FALSE;
}
return pParent->AddChild(pPanel);
}
BOOL CWndResizer::SetParent(UINT uID, LPCTSTR parentName)
{
ASSERT(m_pHookedWnd != NULL);
CPanel * pParent = NULL;
if ( (pParent = FindPanelByName(&root, parentName)) == NULL) {
return FALSE;
}
CPanel * pPanel = NULL;
if ((pPanel = FindPanelByName(&root, IdToName(uID))) == NULL)
{
if ((pPanel = CreateUIPanel(uID)) == NULL)
{
return FALSE;
}
}
return pParent->AddChild(pPanel);
}
BOOL CWndResizer::SetParent(LPCTSTR panelName, UINT uParentID)
{
ASSERT(m_pHookedWnd != NULL);
CPanel * pParent = GetUIPanel(uParentID);
if ( pParent == NULL) {
return FALSE;
}
CPanel * pPanel = NULL;
if ((pPanel = FindPanelByName(&root, panelName)) == NULL)
{
return FALSE;
}
return pParent->AddChild(pPanel);
}
BOOL CWndResizer::SetParent(UINT uID, UINT uParentID)
{
CPanel * pParent = GetUIPanel(uParentID);
if (pParent == NULL)
{
return FALSE;
}
CPanel * pPanel = GetUIPanel(uID);;
if (pParent == NULL)
{
return FALSE;
}
return pParent->AddChild( pPanel );
}
BOOL CWndResizer::GetParent(LPCTSTR panelName, CString & parentName)
{
CPanel * pPanel = NULL;
if ( (pPanel = FindPanelByName(&root, panelName)) == NULL)
{
return FALSE;
}
parentName = pPanel->Parent->Name;
return TRUE;
}
BOOL CWndResizer::GetParent(UINT uID, CString & parentName)
{
CPanel * pPanel = NULL;
if ( (pPanel = FindPanelByName(&root, IdToName(uID))) == NULL) {
return FALSE;
}
parentName = pPanel->Parent->Name;
return TRUE;
}
BOOL CWndResizer::SetMinimumSize( LPCTSTR panelName, CSize & size)
{
CPanel * pPanel = NULL;
if ( (pPanel = FindPanelByName(&root, panelName)) == NULL)
{
return FALSE;
}
return pPanel->SetMinSize( size );
}
BOOL CWndResizer::SetMinimumSize(UINT uID, CSize & size)
{
CPanel * pPanel = NULL;
if ( (pPanel = FindPanelByName(&root, IdToName(uID))) == NULL)
{
if ((pPanel = CreateUIPanel(uID)) == NULL)
{
return FALSE;
}
}
return pPanel->SetMinSize( size );
}
BOOL CWndResizer::GetMinimumSize(LPCTSTR panelName, CSize & size)
{
CPanel * pPanel = NULL;
if ( (pPanel = FindPanelByName(&root, panelName)) == NULL)
{
return FALSE;
}
size = pPanel->MinSize;
return TRUE;
}
BOOL CWndResizer::GetMinimumSize(UINT uID, CSize & size)
{
const CPanel * pPanel = NULL;
if ( (pPanel = FindPanelByName(&root, IdToName(uID))) == NULL)
{
return FALSE;
}
size = pPanel->MinSize;
return TRUE;
}
BOOL CWndResizer::SetMaximumSize(UINT uID, CSize & size)
{
CPanel * pPanel = NULL;
if ( (pPanel = FindPanelByName(&root, IdToName(uID))) == NULL)
{
return FALSE;
}
return pPanel->SetMaxSize(size);
}
BOOL CWndResizer::SetMaximumSize( LPCTSTR panelName, CSize & size)
{
CPanel * pPanel = NULL;
if ( (pPanel = FindPanelByName(&root, panelName)) == NULL)
{
return FALSE;
}
return pPanel->SetMaxSize(size);
}
BOOL CWndResizer::GetMaximumSize( LPCTSTR panelName, CSize & size)
{
CPanel * pPanel = NULL;
if ( (pPanel = FindPanelByName(&root, panelName)) == NULL)
{
return FALSE;
}
size = pPanel->MaxSize;
return TRUE;
}
BOOL CWndResizer::GetMaximumSize( UINT uID, CSize & size)
{
CPanel * pPanel = NULL;
if ( (pPanel = FindPanelByName(&root, IdToName(uID))) == NULL)
{
return FALSE;
}
size = pPanel->MaxSize;
return TRUE;
}
BOOL CWndResizer::SetFixedPanel(LPCTSTR splitContainerName, short panel)
{
CPanel * pContainer = FindPanelByName(&root, splitContainerName);
if (pContainer == NULL)
{
return FALSE;
}
CSplitContainer * pSplitContainer = dynamic_cast<CSplitContainer *>( pContainer );
if (pSplitContainer == NULL)
{
return FALSE;
}
pSplitContainer->SetFixedPanel(panel);
return TRUE;
}
BOOL CWndResizer::GetFixedPanel(LPCTSTR splitContainerName, short & panel)
{
CPanel * pContainer = FindPanelByName(&root, splitContainerName);
if (pContainer == NULL)
{
return FALSE;
}
CSplitContainer * pSplitContainer = dynamic_cast<CSplitContainer *> (pContainer);
if (pSplitContainer == NULL)
{
return FALSE;
}
panel = pSplitContainer->GetFixedPanel();
return TRUE;
}
BOOL CWndResizer::SetIsSplitterFixed(LPCTSTR splitContainerName, BOOL fixed)
{
CPanel * pContainer = FindPanelByName(&root, splitContainerName);
if (pContainer == NULL)
{
return FALSE;
}
CSplitContainer * pSplitContainer = dynamic_cast<CSplitContainer *> (pContainer);
if (pSplitContainer == NULL)
{
return FALSE;
}
pSplitContainer->SetIsSplitterFixed( fixed );
return TRUE;
}
BOOL CWndResizer::GetIsSplitterFixed(LPCTSTR splitContainerName, BOOL &fixed)
{
CPanel * pContainer = FindPanelByName(&root, splitContainerName);
if (pContainer == NULL)
{
return FALSE;
}
CSplitContainer * pSplitContainer = dynamic_cast<CSplitContainer *> (pContainer);
if (pSplitContainer == NULL)
{
return FALSE;
}
fixed = pSplitContainer->GetIsSplitterFixed();
return TRUE;
}
BOOL CWndResizer::SetShowSplitterGrip(LPCTSTR splitContainerName, BOOL bShow)
{
CPanel * pContainer = FindPanelByName(&root, splitContainerName);
if (pContainer == NULL)
{
return FALSE;
}
CSplitContainer * pSplitContainer = dynamic_cast<CSplitContainer *> (pContainer);
if (pSplitContainer == NULL)
{
return FALSE;
}
pSplitContainer->SetShowSplitterGrip( bShow );
return TRUE;
}
BOOL CWndResizer::GetShowSplitterGrip(LPCTSTR splitContainerName, BOOL &bShow)
{
CPanel * pContainer = FindPanelByName(&root, splitContainerName);
if (pContainer == NULL)
{
return FALSE;
}
CSplitContainer * pSplitContainer = dynamic_cast<CSplitContainer *> (pContainer);
if (pSplitContainer == NULL)
{
return FALSE;
}
bShow = pSplitContainer->GetShowSplitterGrip();
return TRUE;
}
void CWndResizer::SetShowResizeGrip(CWndResizer::ResizeGrip show)
{
CGripperPanel * pPanel = (CGripperPanel *)FindPanelByName(&root, ResizeGripperPanelName);
ASSERT(pPanel != NULL);
if ( pPanel->m_bVisible != show )
{
pPanel->m_bVisible = show;
m_pHookedWnd->Invalidate(TRUE);
}
}
void CWndResizer::SetShowResizeGrip(BOOL show)
{
SetShowResizeGrip( show ? RESIZE_GRIP_VISIBLE_ACTIVE_TRIANGLE : RESIZE_GRIP_HIDDEN );
}
CWndResizer::ResizeGrip CWndResizer::GetShowResizeGrip()
{
CGripperPanel * pPanel = (CGripperPanel *)FindPanelByName(&root, ResizeGripperPanelName);
ASSERT(pPanel != NULL);
return (CWndResizer::ResizeGrip)pPanel->m_bVisible;
}
BOOL CWndResizer::SetFlowDirection(LPCTSTR flowPanelName, short direction)
{
ASSERT(m_pHookedWnd != NULL);
CPanel * pPanel = NULL;
if ((pPanel = FindPanelByName(&root, flowPanelName)) == NULL)
{
return FALSE;
}
CFlowLayoutPanel * pFlowLayout = dynamic_cast<CFlowLayoutPanel *> ( pPanel);
if (pFlowLayout == NULL)
{
return FALSE;
}
pFlowLayout->SetFlowDirection( direction == 1 ? CWndResizer::LEFT_TO_RIGHT : CWndResizer::TOP_TO_BOTTOM);
return TRUE;
}
BOOL CWndResizer::GetFlowDirection(LPCTSTR flowPanelName, short &direction)
{
ASSERT(m_pHookedWnd != NULL);
CPanel * pPanel = NULL;
if ((pPanel = FindPanelByName(&root, flowPanelName)) == NULL)
{
return FALSE;
}
CFlowLayoutPanel * pFlowLayout = dynamic_cast<CFlowLayoutPanel *> ( pPanel);
if (pFlowLayout == NULL)
{
return FALSE;
}
direction = (pFlowLayout->GetFlowDirection() == CWndResizer::LEFT_TO_RIGHT ? 1 : 2);
return TRUE;
}
BOOL CWndResizer::SetFlowItemSpacingX(LPCTSTR flowPanelName, int nSpacing)
{
ASSERT(m_pHookedWnd != NULL);
CPanel * pPanel = NULL;
if ((pPanel = FindPanelByName(&root, flowPanelName)) == NULL)
{
return FALSE;
}
CFlowLayoutPanel * pFlowLayout = dynamic_cast<CFlowLayoutPanel *> ( pPanel);
if (pFlowLayout == NULL)
{
return FALSE;
}
pFlowLayout->SetItemSpacingX(nSpacing);
return TRUE;
}
BOOL CWndResizer::GetFlowItemSpacingX(LPCTSTR flowPanelName, int &nSpacing)
{
ASSERT(m_pHookedWnd != NULL);
CPanel * pPanel = NULL;
if ((pPanel = FindPanelByName(&root, flowPanelName)) == NULL)
return FALSE;
CFlowLayoutPanel * pFlowLayout = dynamic_cast<CFlowLayoutPanel *> ( pPanel);
if (pFlowLayout == NULL)
return FALSE;
nSpacing = pFlowLayout->GetItemSpacingX();
return TRUE;
}
BOOL CWndResizer::SetFlowItemSpacingY(LPCTSTR flowPanelName, int nSpacing)
{
ASSERT(m_pHookedWnd != NULL);
CPanel * pPanel = NULL;
if ((pPanel = FindPanelByName(&root, flowPanelName)) == NULL)
return FALSE;
CFlowLayoutPanel * pFlowLayout = dynamic_cast<CFlowLayoutPanel *> ( pPanel);
if (pFlowLayout == NULL)
return FALSE;
pFlowLayout->SetItemSpacingY(nSpacing);
return TRUE;
}
BOOL CWndResizer::GetFlowItemSpacingY(LPCTSTR flowPanelName, int &nSpacing)
{
ASSERT(m_pHookedWnd != NULL);
CPanel * pPanel = NULL;
if ((pPanel = FindPanelByName(&root, flowPanelName)) == NULL)
return FALSE;
CFlowLayoutPanel * pFlowLayout = dynamic_cast<CFlowLayoutPanel *> ( pPanel);
if (pFlowLayout == NULL)
return FALSE;
nSpacing = pFlowLayout->GetItemSpacingY();
return TRUE;
}
CPanel * CWndResizer::FindPanelByName(CPanel * pRoot, LPCTSTR name)
{
if (CString(name).GetLength() == 0)
return NULL;
if (pRoot == NULL )
return NULL;
if (pRoot->Name.CompareNoCase(name) == 0)
return pRoot;
POSITION pos = pRoot->Children.GetHeadPosition();
while(pos != NULL)
{
CPanel * pChild = pRoot->Children.GetNext(pos);
CPanel * pFound = FindPanelByName(pChild, name);
if (pFound != NULL )
return pFound;
}
return NULL;
}
void CWndResizer::GetUIPanels(CPanel * pRoot, CPanelList * pList, BOOL bOle)
{
if (pRoot == NULL )
{
return ;
}
CUIPanel * pUIPanel = dynamic_cast<CUIPanel *> ( pRoot);
if (pUIPanel != NULL && pUIPanel->m_bOle == bOle)
{
pList->AddTail( pRoot );
}
POSITION pos = pRoot->Children.GetHeadPosition();
while(pos != NULL)
{
CPanel * pChild = pRoot->Children.GetNext(pos);
GetUIPanels(pChild, pList, bOle);
}
}
void CWndResizer::GetVisualPanels(CPanel * pRoot, CPanelList * pList)
{
if (pRoot == NULL )
{
return ;
}
CVisualPanel * pUIPanel = dynamic_cast<CVisualPanel *> ( pRoot);
if (pUIPanel != NULL)
{
pList->AddTail( pRoot );
}
POSITION pos = pRoot->Children.GetHeadPosition();
while(pos != NULL)
{
CPanel * pChild = pRoot->Children.GetNext(pos);
GetVisualPanels(pChild, pList);
}
}
CPanel * CWndResizer::FindSplitterFromPoint(CPanel * pRoot, CPoint point)
{
if (pRoot == NULL )
{
return NULL;
}
CSpitterPanel * pSpitterPanel = dynamic_cast<CSpitterPanel *>(pRoot);
if (pSpitterPanel != NULL && pRoot->PtInRect(point) == TRUE )
{
CSplitContainer * pContainer = (CSplitContainer *)pRoot->Parent;
if (!pContainer->GetIsSplitterFixed())
{
CPoint ptScreen = point;
m_pHookedWnd->ClientToScreen(&ptScreen);
HWND hWndFromPoint = ::WindowFromPoint(ptScreen);
if (m_pHookedWnd->m_hWnd == hWndFromPoint)
{
return pRoot;
}
}
}
POSITION pos = pRoot->Children.GetHeadPosition();
while(pos != NULL)
{
CPanel * pChild = pRoot->Children.GetNext(pos);
CPanel * pFound = FindSplitterFromPoint(pChild, point);
if (pFound != NULL )
{
return pFound;
}
}
return NULL;
}
CString CWndResizer::IdToName(UINT uID)
{
CString sName;
sName.Format(_T("%d"), uID);
return sName;
}
CUIPanel * CWndResizer::CreateUIPanel(UINT uID)
{
ASSERT(m_pHookedWnd != NULL);
CWnd * pWnd = m_pHookedWnd->GetDlgItem(uID);
if ( pWnd == NULL )
{
return NULL;
}
CRect rc(0, 0, 0, 0);
pWnd->GetWindowRect( &rc );
m_pHookedWnd->ScreenToClient( &rc );
CUIPanel * pPanel = new CUIPanel(&rc, uID);
pPanel->Name = IdToName(uID);
return pPanel ;
}
CUIPanel * CWndResizer::GetUIPanel(UINT uID)
{
CUIPanel * pPanel = NULL;
if ((pPanel = (CUIPanel *)FindPanelByName(&root, IdToName(uID))) == NULL)
{
pPanel = CreateUIPanel(uID);
if (pPanel != NULL)
{
root.AddChild( pPanel );
}
}
return pPanel;
}
BOOL CWndResizer::SetSplitterPosition(LPCTSTR splitContainerName, UINT position)
{
ASSERT(m_pHookedWnd != NULL);
CPanel * pPanel = NULL;
if ((pPanel = FindPanelByName(&root, splitContainerName)) == NULL)
return FALSE;
CSplitContainer * pContainer = dynamic_cast<CSplitContainer *> ( pPanel);
if (pContainer == NULL)
return FALSE;
pContainer->SetSplitterPosition( (int) position);
ResizeUI( pContainer );
return TRUE;
}
BOOL CWndResizer::GetSplitterPosition(LPCTSTR splitContainerName, UINT & position)
{
ASSERT(m_pHookedWnd != NULL);
CPanel * pPanel = NULL;
if ((pPanel = FindPanelByName(&root, splitContainerName)) == NULL)
return FALSE;
CSplitContainer * pContainer = dynamic_cast<CSplitContainer *> ( pPanel);
if (pContainer == NULL)
return FALSE;
position = (UINT) pContainer->GetSplitterPosition();
return TRUE;
}
BOOL CWndResizer::InvokeOnResized()
{
ASSERT(m_pHookedWnd != NULL);
OnSize(0, 0, 0);
return TRUE;
}
CString CWndResizer::GetDebugInfo()
{
ASSERT(m_pHookedWnd != NULL);
CString sInfo;
CString sIndent;
GetDebugInfo(&root, sInfo, sIndent);
return sInfo;
}
void CWndResizer::GetDebugInfo(CPanel * pRoot, CString & info, CString indent)
{
if (pRoot == NULL )
return ;
info.Append(_T("\n"));
info.Append(indent);
info.Append(pRoot->ToString() );
indent.Append(_T(" "));
for(int i = 0; i < pRoot->Children.GetCount(); i++)
{
CPanel * pChild = pRoot->Children.GetAt(pRoot->Children.FindIndex(i));
GetDebugInfo(pChild, info, indent);
}
}
void CWndResizer::ResizeUI(CPanel * pRoot)
{
CPanelList panels;
GetUIPanels(pRoot, &panels, FALSE);
POSITION pos = NULL;
if (panels.GetCount() > 0)
{
HDWP hDWP = ::BeginDeferWindowPos((int)panels.GetCount());
ASSERT( hDWP != NULL);
pos = panels.GetHeadPosition();
while (pos != NULL)
{
CUIPanel * pPanel = (CUIPanel *) panels.GetNext(pos);
::DeferWindowPos(hDWP, m_pHookedWnd->GetDlgItem(pPanel->m_uID)->m_hWnd, NULL,
pPanel->left , pPanel->top , pPanel->Width(), pPanel->Height(),
SWP_NOACTIVATE | SWP_NOZORDER );
}
BOOL bOk = ::EndDeferWindowPos(hDWP);
ASSERT( bOk );
m_pHookedWnd->InvalidateRect(pRoot, FALSE);
}
panels.RemoveAll();
GetUIPanels(pRoot, &panels, TRUE);
pos = panels.GetHeadPosition();
while (pos != NULL)
{
CUIPanel * pPanel = (CUIPanel *) panels.GetNext(pos);
m_pHookedWnd->GetDlgItem(pPanel->m_uID)->MoveWindow(pPanel);
}
}
void CWndResizer::OnLButtonDown(UINT nFlags, CPoint point)
{
UpdateSplitterOffset(point);
}
void CWndResizer::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_pCaptured != NULL )
{
if ((nFlags & MK_LBUTTON) <= 0)
{
CPoint ptScreen = point;
m_pHookedWnd->ClientToScreen(&ptScreen);
HWND hWndFromPoint = ::WindowFromPoint(ptScreen);
if (m_pCaptured->PtInRect( point ) == FALSE || hWndFromPoint != m_pHookedWnd->m_hWnd)
{
::ReleaseCapture();
m_pCaptured = NULL;
HCURSOR hCur = ::SetCursor(m_hOldCursor);
::DestroyCursor( hCur );
m_hOldCursor = NULL;
}
}
}
if (m_pCaptured == NULL )
{
m_pCaptured = FindSplitterFromPoint(&root, point);
if (m_pCaptured != NULL)
{
m_pHookedWnd->SetCapture();
LPCTSTR cursor = NULL;
CSplitContainer * pSplitContainer = (CSplitContainer *)m_pCaptured->Parent;
if (pSplitContainer->m_Orientation == CWndResizer::SPLIT_CONTAINER_H)
{
cursor = IDC_SIZEWE;
}
else
{
cursor = IDC_SIZENS;
}
HCURSOR hCur = AfxGetApp()->LoadStandardCursor(cursor);
HCURSOR m_hOldCursor = ::SetCursor(hCur);
}
}
if (m_pCaptured != NULL && (nFlags & MK_LBUTTON) > 0)
{
CSplitContainer * pSplitterContainer = (CSplitContainer *) m_pCaptured->Parent;
if (pSplitterContainer->m_Orientation == CWndResizer::SPLIT_CONTAINER_H)
{
pSplitterContainer->SetSplitterPosition( point.x - m_splitterOffset);
}
else
{
pSplitterContainer->SetSplitterPosition( point.y - m_splitterOffset);
}
UpdateSplitterOffset(point);
ResizeUI(pSplitterContainer);
}
}
void CWndResizer::OnLButtonUp(UINT nFlags, CPoint point)
{
OnMouseMove(nFlags, point);
}
void CWndResizer::GetTrueClientRect(CWnd * pWnd, CRect * prc)
{
int nMin = 0;
int nMax = 0;
int nCur = 0;
pWnd->GetClientRect(prc);
if ( (pWnd->GetStyle() & WS_HSCROLL) > 0)
{
pWnd->GetScrollRange(SB_HORZ, &nMin, &nMax);
nCur = pWnd->GetScrollPos(SB_HORZ);
prc->right = prc->left + nMax;
prc->OffsetRect( -nCur , 0);
}
if ( (pWnd->GetStyle() & WS_VSCROLL) > 0)
{
pWnd->GetScrollRange(SB_VERT, &nMin, &nMax);
nCur = pWnd->GetScrollPos(SB_VERT);
prc->bottom = prc->top + nMax;
prc->OffsetRect(0, -nCur);
}
}
void CWndResizer::EnsureRootMinMax()
{
if (root.Width() < root.MinSize.cx)
root.right = root.left + root.MinSize.cx;
if (root.Width() > root.MaxSize.cx)
root.right = root.left + root.MaxSize.cx;
if (root.Height() < root.MinSize.cy)
root.bottom = root.top + root.MinSize.cy;
if (root.Height() > root.MaxSize.cy)
root.bottom = root.top + root.MaxSize.cy;
}
void CWndResizer::UpdateSplitterOffset(CPoint ptCurr)
{
if (m_pCaptured == NULL )
return;
if (((CSplitContainer *)m_pCaptured->Parent)->m_Orientation == CWndResizer::SPLIT_CONTAINER_H)
{
if ( ptCurr.x < m_pCaptured->left)
{
m_splitterOffset = 0;
}
else if ( ptCurr.x > m_pCaptured->right)
{
m_splitterOffset = m_pCaptured->Width();
}
else
{
m_splitterOffset = ptCurr.x - m_pCaptured->left;
}
}
else
{
if ( ptCurr.y < m_pCaptured->top)
{
m_splitterOffset = 0;
}
else if ( ptCurr.y > m_pCaptured->bottom)
{
m_splitterOffset = m_pCaptured->Height();
}
else
{
m_splitterOffset = ptCurr.y - m_pCaptured->top;
}
}
}
void CWndResizer::OnSizing(UINT fwSide, LPRECT pRect)
{
CRect * prc = (CRect *) pRect;
CRect rcMin(0, 0, root.MinSize.cx, root.MinSize.cy);
CRect rcMax(0, 0, root.MaxSize.cx, root.MaxSize.cy);
LONG_PTR style = GetWindowLongPtr(m_pHookedWnd->m_hWnd , GWL_STYLE);
LONG_PTR styleEx = GetWindowLongPtr(m_pHookedWnd->m_hWnd, GWL_EXSTYLE);
::AdjustWindowRectEx(&rcMin, (DWORD)style, (m_pHookedWnd->GetMenu() != NULL), (DWORD)styleEx);
::AdjustWindowRectEx(&rcMax, (DWORD)style, (m_pHookedWnd->GetMenu() != NULL), (DWORD)styleEx);
switch (fwSide)
{
case WMSZ_BOTTOM:
if (prc->Height() < rcMin.Height() )
{
prc->bottom = prc->top + rcMin.Height();
}
if (prc->Height() > rcMax.Height() )
{
prc->bottom = prc->top + rcMax.Height();
}
break;
case WMSZ_BOTTOMLEFT:
if (prc->Height() < rcMin.Height() )
{
prc->bottom = prc->top + rcMin.Height();
}
if (prc->Width() < rcMin.Width() )
{
prc->left = prc->right - rcMin.Width();
}
if (prc->Height() > rcMax.Height() )
{
prc->bottom = prc->top + rcMax.Height();
}
if (prc->Width() > rcMax.Width() )
{
prc->left = prc->right - rcMax.Width();
}
break;
case WMSZ_BOTTOMRIGHT:
if (prc->Height() < rcMin.Height() )
{
prc->bottom = prc->top + rcMin.Height();
}
if (prc->Width() < rcMin.Width() )
{
prc->right = prc->left + rcMin.Width();
}
if (prc->Height() > rcMax.Height() )
{
prc->bottom = prc->top + rcMax.Height();
}
if (prc->Width() > rcMax.Width() )
{
prc->right = prc->left + rcMax.Width();
}
break;
case WMSZ_LEFT:
if (prc->Width() < rcMin.Width() )
{
prc->left = prc->right - rcMin.Width();
}
if (prc->Width() > rcMax.Width() )
{
prc->left = prc->right - rcMax.Width();
}
break;
case WMSZ_RIGHT:
if (prc->Width() < rcMin.Width() )
{
prc->right = prc->left + rcMin.Width();
}
if (prc->Width() > rcMax.Width() )
{
prc->right = prc->left + rcMax.Width();
}
break;
case WMSZ_TOP:
if (prc->Height() < rcMin.Height() )
{
prc->top = prc->bottom - rcMin.Height();
}
if (prc->Height() > rcMax.Height() )
{
prc->top = prc->bottom - rcMax.Height();
}
break;
case WMSZ_TOPLEFT:
if (prc->Height() < rcMin.Height() )
{
prc->top = prc->bottom - rcMin.Height();
}
if (prc->Width() < rcMin.Width() )
{
prc->left = prc->right - rcMin.Width();
}
if (prc->Height() > rcMax.Height() )
{
prc->top = prc->bottom - rcMax.Height();
}
if (prc->Width() > rcMax.Width() )
{
prc->left = prc->right - rcMax.Width();
}
break;
case WMSZ_TOPRIGHT:
if (prc->Height() < rcMin.Height() )
{
prc->top = prc->bottom - rcMin.Height();
}
if (prc->Width() < rcMin.Width() )
{
prc->right = prc->left + rcMin.Width();
}
if (prc->Height() > rcMax.Height() )
{
prc->top = prc->bottom - rcMax.Height();
}
if (prc->Width() > rcMax.Width() )
{
prc->right = prc->left + rcMax.Width();
}
break;
}
}
void CWndResizer::OnPaint()
{
if (m_pHookedWnd == NULL)
{
return;
}
CDC* pDC = m_pHookedWnd->GetDC();
CPanelList panelList;
GetVisualPanels(&root, &panelList);
POSITION pos = panelList.GetHeadPosition();
while (pos != NULL)
{
CVisualPanel * pPanel = (CVisualPanel *) panelList.GetNext(pos);
if (pPanel->m_bVisible)
{
pPanel->Draw(pDC);
}
}
}
void CWndResizer::OnThemeChanged()
{
if (m_pHookedWnd == NULL)
return;
CGripperPanel * pPanel = (CGripperPanel *)FindPanelByName(&root, ResizeGripperPanelName);
ASSERT(pPanel != NULL);
if( pPanel->m_bVisible != RESIZE_GRIP_HIDDEN )
{
GetTrueClientRect(m_pHookedWnd, &root);
EnsureRootMinMax();
root.OnResized();
ResizeUI(&root);
}
}
LRESULT CWndResizer::OnNcHitTest( CPoint point )
{
CGripperPanel * pPanel = (CGripperPanel *)FindPanelByName(&root, ResizeGripperPanelName);
if( !pPanel || !pPanel->m_bVisible )
return HTNOWHERE;
ASSERT( m_pHookedWnd != NULL );
m_pHookedWnd->ScreenToClient( &point );
if( pPanel->m_bVisible == RESIZE_GRIP_VISIBLE_ACTIVE_TRIANGLE )
{
if( pPanel->PtInTriangle(point) )
return HTBOTTOMRIGHT;
}
else if( pPanel->m_bVisible == RESIZE_GRIP_VISIBLE_ACTIVE_RECT )
{
if( pPanel->PtInRect( point ) )
return HTBOTTOMRIGHT;
}
return HTNOWHERE;
}
void CWndResizer::OnSize(UINT nType, int cx, int cy)
{
GetTrueClientRect(m_pHookedWnd, &root);
EnsureRootMinMax();
root.OnResized();
ResizeUI(&root);
}
void CWndResizer::OnScroll()
{
GetTrueClientRect(m_pHookedWnd, &root);
EnsureRootMinMax();
root.OnResized();
ResizeUI(&root);
}
void CWndResizer::OnDestroy()
{
if (m_pHookedWnd != NULL)
{
Unhook();
}
}
LRESULT CALLBACK CWndResizer::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CWndResizer * pResizer = NULL;
WndResizerData.Lookup(hWnd, pResizer);
ASSERT( pResizer != NULL);
LRESULT lResult;
switch (uMsg)
{
case WM_SIZE:
{
int cx = LOWORD(lParam);
int cy = HIWORD(lParam);
pResizer->OnSize((UINT) wParam, cx, cy);
break;
}
case WM_SIZING:
pResizer->OnSizing((UINT) wParam, (LPRECT)lParam);
break;
case WM_DESTROY:
pResizer->OnDestroy();
break;
case WM_MOUSEMOVE:
pResizer->OnMouseMove((UINT) wParam, CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
break;
case WM_LBUTTONDOWN:
pResizer->OnLButtonDown((UINT) wParam, CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
break;
case WM_LBUTTONUP:
pResizer->OnLButtonUp((UINT) wParam, CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
break;
case WM_PAINT:
pResizer->OnPaint();
break;
case WM_HSCROLL:
case WM_VSCROLL:
pResizer->OnScroll();
break;
case WM_NCHITTEST:
lResult = pResizer->OnNcHitTest( CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)) );
if( lResult != HTNOWHERE )
return lResult;
break;
default:
break;
}
lResult = ::CallWindowProc(pResizer->m_pfnWndProc, hWnd, uMsg, wParam, lParam);
switch( uMsg )
{
case WM_SYSCOLORCHANGE:
case WM_THEMECHANGED:
pResizer->OnThemeChanged();
break;
}
return lResult;
}
CPanel::CPanel() : CRect(0, 0, 0, 0)
{
Init();
}
CPanel::CPanel(const CRect * prc) : CRect(prc)
{
Init();
}
void CPanel::Init()
{
Parent = NULL;
LeftOffset = 0;
TopOffset = 0;
RightOffset = 0;
BottomOffset = 0;
MinSize.SetSize(10, 10);
MaxSize.SetSize(100000, 100000);
Anchor = (ANCHOR_LEFT | ANCHOR_TOP);
Dock = DOCK_NONE;
m_bVisible = TRUE;
}
CPanel::~CPanel()
{
while(Children.GetCount() > 0 )
{
delete Children.RemoveHead();
}
}
void CPanel::OnResized()
{
BOOL bOk = FALSE;
CRect rcEmpty(this);
POSITION pos = Children.GetHeadPosition();
while(pos != NULL)
{
CPanel * pChild = Children.GetNext(pos);
if (pChild->Dock != DOCK_NONE)
{
switch(pChild->Dock)
{
case DOCK_LEFT:
pChild->SetRect(rcEmpty.left, rcEmpty.top, rcEmpty.left + pChild->Width(), rcEmpty.bottom);
bOk = rcEmpty.SubtractRect(&rcEmpty, pChild);
break;
case DOCK_TOP:
pChild->SetRect(rcEmpty.left, rcEmpty.top, rcEmpty.right, rcEmpty.top + pChild->Height());
bOk = rcEmpty.SubtractRect(&rcEmpty, pChild);
break;
case DOCK_RIGHT:
pChild->SetRect(rcEmpty.right - pChild->Width(), rcEmpty.top, rcEmpty.right, rcEmpty.bottom);
bOk = rcEmpty.SubtractRect(&rcEmpty, pChild);
break;
case DOCK_BOTTOM:
pChild->SetRect(rcEmpty.left, rcEmpty.bottom - pChild->Height(), rcEmpty.right, rcEmpty.bottom);
bOk = rcEmpty.SubtractRect(&rcEmpty, pChild);
break;
case DOCK_FILL:
pChild->SetRect(rcEmpty.left, rcEmpty.top, rcEmpty.right, rcEmpty.bottom);
break;
}
pChild->OnResized();
continue;
}
CRect rc(0, 0, 0, 0);
if ((pChild->Anchor & ANCHOR_HORIZONTALLY_CENTERED) == ANCHOR_HORIZONTALLY_CENTERED )
{
rc.left = this->left + ((int)( (this->Width() - pChild->Width()) / 2));
rc.right = rc.left + pChild->Width();
BOOL bReposition = FALSE;
if (pChild->MinSize.cx > rc.Width() )
{
bReposition = TRUE;
rc.right = rc.left + pChild->MinSize.cx;
}
if (pChild->MaxSize.cx < rc.Width() )
{
bReposition = TRUE;
rc.right = rc.left + pChild->MaxSize.cx;
}
if (bReposition)
{
int nWidth = rc.Width();
rc.left = (int)( (this->Width() - nWidth) / 2) ;
rc.right = rc.left + nWidth;
}
}
else if ((pChild->Anchor & ANCHOR_HORIZONTALLY) == ANCHOR_HORIZONTALLY )
{
rc.left = this->left + pChild->LeftOffset;
rc.right = this->right - pChild->RightOffset;
if ((pChild->Anchor & ANCHOR_PRIORITY_RIGHT) == ANCHOR_PRIORITY_RIGHT)
{
if (pChild->MinSize.cx > rc.Width() )
{
rc.left = rc.right - pChild->MinSize.cx;
}
if (pChild->MaxSize.cx < rc.Width() )
{
rc.left = rc.right - pChild->MaxSize.cx;
}
}
else
{
if (pChild->MinSize.cx > rc.Width() )
{
rc.right = rc.left + pChild->MinSize.cx;
}
if (pChild->MaxSize.cx < rc.Width() )
{
rc.right = rc.left + pChild->MaxSize.cx;
}
}
}
else if ((pChild->Anchor & ANCHOR_RIGHT) == ANCHOR_RIGHT )
{
rc.right = this->right - pChild->RightOffset;
rc.left = rc.right - pChild->Width();
if (pChild->MinSize.cx > rc.Width() )
{
rc.left = rc.right - pChild->MinSize.cx;
}
if (pChild->MaxSize.cx < rc.Width() )
{
rc.left = rc.right - pChild->MaxSize.cx;
}
}
else if ((pChild->Anchor & ANCHOR_LEFT) == ANCHOR_LEFT )
{
rc.left = this->left + pChild->LeftOffset;
rc.right = rc.left + pChild->Width();
if (pChild->MinSize.cx > rc.Width() )
{
rc.right = rc.left + pChild->MinSize.cx;
}
if (pChild->MaxSize.cx < rc.Width() )
{
rc.right = rc.left + pChild->MaxSize.cx;
}
}
else
{
ASSERT( FALSE );
}
if ((pChild->Anchor & ANCHOR_VERTICALLY_CENTERED) == ANCHOR_VERTICALLY_CENTERED )
{
rc.top = this->top + ((int)( (this->Height() - pChild->Height()) / 2));
rc.bottom = rc.top + pChild->Height();
BOOL bReposition = FALSE;
if (pChild->MinSize.cy > rc.Height() )
{
bReposition = TRUE;
rc.bottom = rc.top + pChild->MinSize.cy;
}
if (pChild->MaxSize.cy < rc.Height() )
{
bReposition = TRUE;
rc.bottom = rc.top + pChild->MaxSize.cy;
}
if (bReposition)
{
int nHeight = rc.Height();
rc.top = (int)( (this->Height() - nHeight) / 2);
rc.bottom = rc.top + nHeight;
}
}
else if ((pChild->Anchor & ANCHOR_VERTICALLY ) == ANCHOR_VERTICALLY )
{
rc.top = this->top + pChild->TopOffset;
rc.bottom = this->bottom - pChild->BottomOffset;
if ((pChild->Anchor & ANCHOR_PRIORITY_BOTTOM) == ANCHOR_PRIORITY_BOTTOM)
{
if (pChild->MinSize.cy > rc.Height() )
{
rc.top = rc.bottom - pChild->MinSize.cy;
}
if (pChild->MaxSize.cy < rc.Height() )
{
rc.top = rc.bottom - pChild->MaxSize.cy;
}
}
else
{
if (pChild->MinSize.cy > rc.Height() )
{
rc.bottom = rc.top + pChild->MinSize.cy;
}
if (pChild->MaxSize.cy < rc.Height() )
{
rc.bottom = rc.top + pChild->MaxSize.cy;
}
}
}
else if ((pChild->Anchor & ANCHOR_BOTTOM) == ANCHOR_BOTTOM )
{
rc.bottom = this->bottom - pChild->BottomOffset;
rc.top = rc.bottom - pChild->Height();
if (pChild->MinSize.cy > rc.Height() )
{
rc.top = rc.bottom - pChild->MinSize.cy;
}
if (pChild->MaxSize.cy < rc.Height() )
{
rc.top = rc.bottom - pChild->MaxSize.cy;
}
}
else if ((pChild->Anchor & ANCHOR_TOP) == ANCHOR_TOP )
{
rc.top = this->top + pChild->TopOffset;
rc.bottom = rc.top + pChild->Height();
if (pChild->MinSize.cy > rc.Height() )
{
rc.bottom = rc.top + pChild->MinSize.cy;
}
if (pChild->MaxSize.cy < rc.Height() )
{
rc.bottom = rc.top + pChild->MaxSize.cy;
}
}
else
{
ASSERT( FALSE );
}
pChild->SetRect(rc.TopLeft(), rc.BottomRight());
pChild->OnResized();
}
}
BOOL CPanel::AddChild(CPanel * pChild)
{
if (pChild->Parent != NULL)
{
BOOL bOk = pChild->Parent->RemoveChild(pChild);
if (bOk == FALSE)
{
return FALSE;
}
}
pChild->LeftOffset = pChild->left - this->left;
pChild->TopOffset = pChild->top - this->top;
pChild->RightOffset = this->right - pChild->right;
pChild->BottomOffset = this->bottom - pChild->bottom;
pChild->Parent = this;
Children.AddTail( pChild );
return TRUE;
}
BOOL CPanel::RemoveChild(CPanel * pChild)
{
POSITION pos = Children.Find(pChild);
if (pos == NULL)
{
return FALSE;
}
Children.RemoveAt(pos);
return TRUE;
}
BOOL CPanel::SetAnchor(UINT anchor)
{
if ((anchor & ANCHOR_VERTICALLY_CENTERED) <= 0 )
{
if ((anchor & ANCHOR_TOP) <= 0 )
{
if ((anchor & ANCHOR_BOTTOM) <= 0 )
{
anchor |= ANCHOR_TOP; }
}
}
if ((anchor & ANCHOR_HORIZONTALLY_CENTERED) <= 0 )
{
if ((anchor & ANCHOR_LEFT) <= 0 )
{
if ((anchor & ANCHOR_RIGHT) <= 0 )
{
anchor |= ANCHOR_LEFT; }
}
}
Anchor = anchor;
return TRUE;
}
BOOL CPanel::SetMinSize(CSize & size)
{
if (MaxSize.cx < size.cx)
{
return FALSE;
}
if (MaxSize.cy < size.cy)
{
return FALSE;
}
MinSize = size;
return TRUE;
}
BOOL CPanel::SetMaxSize(CSize & size)
{
if (MinSize.cx > size.cx)
{
return FALSE;
}
if (MinSize.cy > size.cy)
{
return FALSE;
}
MaxSize = size;
return TRUE;
}
BOOL CPanel::SetOffset(UINT anchor, int offset)
{
BOOL bRes = FALSE;
if (anchor & ANCHOR_TOP)
{
TopOffset = offset;
bRes = TRUE;
}
if (anchor & ANCHOR_LEFT)
{
LeftOffset = offset;
bRes = TRUE;
}
if (anchor & ANCHOR_BOTTOM)
{
BottomOffset = offset;
bRes = TRUE;
}
if (anchor & ANCHOR_RIGHT)
{
RightOffset = offset;
bRes = TRUE;
}
return bRes;
}
BOOL CPanel::SetVisible(BOOL bVisible)
{
m_bVisible = bVisible;
POSITION pos = Children.GetHeadPosition();
while( pos )
{
CPanel *pPanel = Children.GetNext( pos );
pPanel->SetVisible( bVisible );
}
return TRUE;
}
BOOL CPanel::GetVisible(BOOL &bVisible)
{
bVisible = m_bVisible;
return TRUE;
}
BOOL CPanel::IsVisible()
{
return m_bVisible;
}
CString CPanel::ToString()
{
CString sFormat(_T("Name(%s), Type(%s), Anchor(%d), Size(w:%d, h:%d), Area(l:%d, t:%d, r:%d, b:%d), MinSize(w:%d, h:%d), MaxSize(w:%d, h:%d), Parent(%s), ChildrenCount(%d)"));
CString sTo;
sTo.Format(sFormat, Name, GetTypeName(), Anchor, Width(), Height(), left, top, right, bottom, MinSize.cx, MinSize.cy, MaxSize.cx, MaxSize.cy, (Parent == NULL? _T("NULL") : Parent->Name), Children.GetCount());
return sTo;
}
CString CPanel::GetTypeName()
{
return _T("CPanel");
}
CWnd * CPanel::GetHookedWnd()
{
if (Parent != NULL)
return Parent->GetHookedWnd();
return NULL;
}
BOOL CPanel::PtInTriangle( CPoint point, UINT nEdge ) const
{
switch( nEdge )
{
case ANCHOR_TOPLEFT:
return PtInTriangle( point, CPoint(left,top), CPoint(right,top), CPoint(left,bottom) );
case ANCHOR_TOPRIGHT:
return PtInTriangle( point, CPoint(left,top), CPoint(right,top), CPoint(right,bottom) );
case ANCHOR_BOTTOMLEFT:
return PtInTriangle( point, CPoint(left,top), CPoint(left,bottom), CPoint(right,bottom) );
case ANCHOR_BOTTOMRIGHT:
return PtInTriangle( point, CPoint(left,bottom), CPoint(right,top), CPoint(right,bottom) );
default:
return FALSE;
}
}
static int GetSign( const CPoint &a, const CPoint &b, const CPoint &c )
{
return (a.x - c.x) * (b.y - c.y) - (b.x - c.x) * (a.y - c.y);
}
BOOL CPanel::PtInTriangle( CPoint point, CPoint v1, CPoint v2, CPoint v3 )
{
bool b1 = GetSign(point, v1, v2) < 0;
bool b2 = GetSign(point, v2, v3) < 0;
bool b3 = GetSign(point, v3, v1) < 0;
return ((b1 == b2) && (b2 == b3));
}
CRootPanel::CRootPanel() : CPanel()
{
m_pHookWnd = NULL;
}
CRootPanel::~CRootPanel()
{
}
CWnd * CRootPanel::GetHookedWnd()
{
return m_pHookWnd;
}
CString CRootPanel::GetTypeName()
{
return _T("CRootPanel");
}
CUIPanel::CUIPanel(const CRect * prc, UINT uID) : CPanel(prc)
{
m_uID = uID;
m_bOle = FALSE;
}
CUIPanel::~CUIPanel()
{
}
CString CUIPanel::GetTypeName()
{
return _T("CUIPanel");
}
BOOL CUIPanel::SetVisible(BOOL bVisible)
{
BOOL bRes = FALSE;
CPanel::SetVisible( bVisible );
CWnd *wnd = GetHookedWnd();
if( wnd )
{
CWnd *ctl = wnd->GetDlgItem( m_uID );
if( ctl )
bRes = ctl->ShowWindow( bVisible ? SW_SHOW : SW_HIDE );
}
return bRes;
}
BOOL CUIPanel::GetVisible(BOOL &bVisible)
{
bVisible = m_bVisible;
return TRUE;
}
BOOL CUIPanel::IsVisible()
{
return m_bVisible;
}
CVisualPanel::CVisualPanel() : CPanel()
{
m_bVisible = FALSE;
m_rcPrev.SetRect(0, 0, 0, 0);
}
CVisualPanel::CVisualPanel(const CRect * prc) : CPanel(prc)
{
m_bVisible = FALSE;
m_rcPrev.SetRect(this->left, this->top, this->right, this->bottom);
}
CVisualPanel::~CVisualPanel()
{
}
void CVisualPanel::Draw(CDC * pDC)
{
}
CString CVisualPanel::GetTypeName()
{
return _T("CVisualPanel");
}
void CVisualPanel::OnResized()
{
CWnd * pWnd = NULL;
if ((pWnd = GetHookedWnd()) != NULL)
{
pWnd->InvalidateRect( &m_rcPrev, FALSE );
pWnd->InvalidateRect( this, FALSE );
}
m_rcPrev.SetRect(this->left, this->top, this->right, this->bottom);
}
CGripperPanel::CGripperPanel() : CVisualPanel()
{
m_hTheme = NULL;
}
CGripperPanel::CGripperPanel(const CRect * prc) : CVisualPanel(prc)
{
m_hTheme = NULL;
}
CGripperPanel::~CGripperPanel()
{
if (m_hTheme != NULL)
{
(void)::CloseThemeData(m_hTheme);
m_hTheme = NULL;
}
}
void CGripperPanel::Draw(CDC * pDC)
{
int iPartId = SBP_SIZEBOX;
int iStateId = 5; LPCWSTR wClassName = L"SCROLLBAR";
HWND hwnd = NULL;
if (m_hTheme == NULL)
{
hwnd = GetHookedWnd()->GetSafeHwnd();
if (hwnd == NULL)
return;
m_hTheme = ::OpenThemeData(hwnd, wClassName);
}
BOOL bDrawStd = TRUE;
if (m_hTheme)
{
HRESULT lres = ::DrawThemeBackground(m_hTheme, pDC->m_hDC, iPartId, iStateId, this, this);
if (!SUCCEEDED(lres))
{
(void)::CloseThemeData(m_hTheme);
m_hTheme = NULL;
if( hwnd )
{
m_hTheme = ::OpenThemeData(hwnd, wClassName);
if( m_hTheme )
lres = ::DrawThemeBackground(m_hTheme, pDC->m_hDC, iPartId, iStateId, this, this);
}
}
if (SUCCEEDED(lres))
bDrawStd = FALSE;
}
if (bDrawStd)
(void)pDC->DrawFrameControl(this, DFC_SCROLL, DFCS_SCROLLSIZEGRIP );
}
CString CGripperPanel::GetTypeName()
{
return _T("CGripperPanel");
}
CSplitterGripperPanel::CSplitterGripperPanel(CWndResizer::SplitterOrientation type) : CVisualPanel()
{
m_OrienType = type;
}
CSplitterGripperPanel::~CSplitterGripperPanel()
{
}
void CSplitterGripperPanel::Draw(CDC * pDC)
{
CPen penDark(PS_SOLID, 1, ::GetSysColor(COLOR_3DSHADOW));
CPen penWhite(PS_SOLID, 1, ::GetSysColor(COLOR_3DHIGHLIGHT));
if (m_OrienType == CWndResizer::SPLIT_CONTAINER_H )
{
CPen * pOrigPen = pDC->SelectObject(&penWhite);
CRect rc(0, 0, 0, 0);
rc.SetRect(left + 1, top + 1, left + 3, top + 3);
while(rc.bottom <= bottom + 1)
{
pDC->Rectangle(&rc);
rc.OffsetRect(0, 4);
}
pDC->SelectObject(&penDark);
rc.SetRect(left, top, left + 2, top + 2);
while(rc.bottom <= bottom)
{
pDC->Rectangle(&rc);
rc.OffsetRect(0, 4);
}
pDC->SelectObject(pOrigPen);
}
else
{
CPen * pOrigPen = pDC->SelectObject(&penWhite);
CRect rc(0, 0, 0, 0);
rc.SetRect(left + 1, top + 1, left + 3, top + 3);
while(rc.right <= right + 1)
{
pDC->Rectangle(&rc);
rc.OffsetRect(4, 0);
}
pDC->SelectObject(&penDark);
rc.SetRect(left, top, left + 2, top + 2);
while(rc.right <= right)
{
pDC->Rectangle(&rc);
rc.OffsetRect(4, 0);
}
pDC->SelectObject(pOrigPen);
}
}
CString CSplitterGripperPanel::GetTypeName()
{
return _T("CSplitterGripperPanel");
}
CSpitterPanel::CSpitterPanel(const CRect * prc, CWndResizer::SplitterOrientation type) : CPanel(prc)
{
m_OrienType = type;
m_pGrippePanel = NULL;
if (m_pGrippePanel == NULL)
{
m_pGrippePanel = new CSplitterGripperPanel(type);
if (m_OrienType == CWndResizer::SPLIT_CONTAINER_H )
{
m_pGrippePanel->SetRect(0, 0, 3, 12);
}
else
{
m_pGrippePanel->SetRect(0, 0, 12, 3);
}
m_pGrippePanel->SetAnchor ( ANCHOR_HORIZONTALLY_CENTERED | ANCHOR_VERTICALLY_CENTERED );
m_pGrippePanel->SetMinSize(CSize(2,2));
BOOL bOk = AddChild(m_pGrippePanel);
ASSERT( bOk);
}
}
CSpitterPanel::CSpitterPanel(CWndResizer::SplitterOrientation type) : CPanel()
{
m_OrienType = type;
m_pGrippePanel = NULL;
}
CSpitterPanel::~CSpitterPanel()
{
}
CString CSpitterPanel::GetTypeName()
{
return _T("CSpitterPanel");
}
#ifdef USE_SPLIT_PANEL
CSplitPanel::CSplitPanel(CPanel * pPanel) : CPanel(pPanel)
{
pPanel->LeftOffset = 0;
pPanel->TopOffset = 0;
pPanel->RightOffset = 0;
pPanel->BottomOffset = 0;
pPanel->Anchor = ANCHOR_ALL;
Name = pPanel->Name;
pPanel->Name = _T("");
m_pOriginalPanel = pPanel;
MaxSize = pPanel->MaxSize;
MinSize = pPanel->MinSize;
Children.AddTail( pPanel );
}
CSplitPanel::~CSplitPanel()
{
}
BOOL CSplitPanel::SetAnchor(UINT anchor)
{
return FALSE;
}
BOOL CSplitPanel::AddChild(CPanel * prc)
{
return m_pOriginalPanel->AddChild(prc);
}
BOOL CSplitPanel::RemoveChild(CPanel * prc)
{
return m_pOriginalPanel->RemoveChild(prc);
}
CString CSplitPanel::GetTypeName()
{
return _T("CSplitPanel");
}
BOOL CSplitPanel::SetMinSize(CSize & size)
{
if( !CPanel::SetMinSize( size ) )
return FALSE;
if( m_pOriginalPanel )
return m_pOriginalPanel->SetMinSize( size );
return TRUE;
}
BOOL CSplitPanel::SetMaxSize(CSize & size)
{
if( !CPanel::SetMaxSize( size ) )
return FALSE;
if( m_pOriginalPanel )
return m_pOriginalPanel->SetMaxSize( size );
return TRUE;
}
#endif
CSplitContainer::CSplitContainer(CSplitPanel * pPanelA, CSplitPanel * pPanelB, CWndResizer::SplitterOrientation type) : CPanel()
{
m_IsSplitterFixed = FALSE;
m_FixedPanel = 0;
m_pPanelA = NULL;
m_pPanelB = NULL;
m_pSplitter = NULL;
m_Orientation = type;
m_pPanelA = pPanelA;
m_pPanelB = pPanelB;
UnionRect(m_pPanelA, m_pPanelB);
CRect rc(0, 0, 0, 0);
GetSplitArea(&rc);
m_pSplitter = new CSpitterPanel(&rc, type);
m_pSplitter->m_pGrippePanel->m_bVisible = FALSE;
if (m_Orientation == CWndResizer::SPLIT_CONTAINER_H)
{
m_pPanelA->Anchor = (ANCHOR_LEFT | ANCHOR_TOP | ANCHOR_BOTTOM);
m_pPanelB->Anchor = (ANCHOR_RIGHT | ANCHOR_TOP | ANCHOR_BOTTOM);
}
else
{
m_pPanelA->Anchor = (ANCHOR_LEFT | ANCHOR_TOP | ANCHOR_RIGHT);
m_pPanelB->Anchor = (ANCHOR_LEFT | ANCHOR_BOTTOM | ANCHOR_RIGHT);
}
m_nSplitterSize = GetSplitterSize(m_pPanelA, m_pPanelB);
BOOL bOk = AddChild(m_pPanelA);
ASSERT( bOk);
bOk = AddChild(m_pSplitter);
ASSERT( bOk);
bOk = AddChild(m_pPanelB);
ASSERT( bOk);
UpdateRatio();
}
CSplitContainer::~CSplitContainer()
{
}
void CSplitContainer::OnResized()
{
CPanel::OnResized();
BOOL bShowA = TRUE;
BOOL bShowB = TRUE;
BOOL bShowS = TRUE;
if (m_Orientation == CWndResizer::SPLIT_CONTAINER_H)
{
if (Width() < MinSize.cx)
return;
if (m_FixedPanel == CWndResizer::FIXED_LEFT ) {
m_pPanelB->left = m_pPanelA->right + m_nSplitterSize;
if (m_pPanelB->MinSize.cx > m_pPanelB->Width() )
{
m_pPanelB->left = m_pPanelB->right - m_pPanelB->MinSize.cx;
m_pPanelA->right = m_pPanelB->left - m_nSplitterSize;
}
}
else if (m_FixedPanel == CWndResizer::FIXED_RIGHT ) {
m_pPanelA->right = m_pPanelB->left - m_nSplitterSize;
if (m_pPanelA->MinSize.cx > m_pPanelA->Width() )
{
m_pPanelA->right = m_pPanelA->left + m_pPanelA->MinSize.cx;
m_pPanelB->left = m_pPanelA->right + m_nSplitterSize;
}
}
else if (m_FixedPanel == CWndResizer::FIXED_LEFT_HIDDEN ) {
m_pPanelB->left = m_pPanelA->left;
m_pPanelA->right = m_pPanelA->left;
bShowS = FALSE;
}
else if (m_FixedPanel == CWndResizer::FIXED_RIGHT_HIDDEN ) {
m_pPanelA->right = m_pPanelB->right;
m_pPanelB->left = m_pPanelB->right;
bShowS = FALSE;
}
else
{
m_pPanelA->right = (LONG) ((double)m_pPanelA->left + ((double)this->Width() * m_nRatio));
if (m_pPanelA->MinSize.cx > m_pPanelA->Width() )
{
m_pPanelA->right = m_pPanelA->left + m_pPanelA->MinSize.cx;
}
m_pPanelB->left = m_pPanelA->right + m_nSplitterSize;
if (m_pPanelB->MinSize.cx > m_pPanelB->Width() )
{
m_pPanelB->left = m_pPanelB->right - m_pPanelB->MinSize.cx;
m_pPanelA->right = m_pPanelB->left - m_nSplitterSize;
}
}
if (m_pPanelA->Width() <= 2)
bShowA = FALSE;
if (m_pPanelB->Width() <= 2)
bShowB = FALSE;
}
else
{
if (Height() < MinSize.cy)
{
return;
}
if (m_FixedPanel == CWndResizer::FIXED_TOP ) {
m_pPanelB->top = m_pPanelA->bottom + m_nSplitterSize;
if (m_pPanelB->MinSize.cy > m_pPanelB->Height() )
{
m_pPanelB->top = m_pPanelB->bottom - m_pPanelB->MinSize.cy;
m_pPanelA->bottom = m_pPanelB->top - m_nSplitterSize;
}
}
else if (m_FixedPanel == CWndResizer::FIXED_BOTTOM ) {
m_pPanelA->bottom = m_pPanelB->top - m_nSplitterSize;
if (m_pPanelA->MinSize.cy > m_pPanelA->Height() )
{
m_pPanelA->bottom = m_pPanelA->top + m_pPanelA->MinSize.cy;
m_pPanelB->top = m_pPanelA->bottom + m_nSplitterSize;
}
}
else if (m_FixedPanel == CWndResizer::FIXED_TOP_HIDDEN ) {
m_pPanelB->top = m_pPanelA->top;
bShowA = FALSE;
bShowS = FALSE;
}
else if (m_FixedPanel == CWndResizer::FIXED_BOTTOM_HIDDEN ) {
m_pPanelA->bottom = m_pPanelB->bottom;
bShowS = FALSE;
bShowB = FALSE;
}
else
{
m_pPanelA->bottom = (LONG) ((double)m_pPanelA->top + ((double)this->Height() * m_nRatio));
if (m_pPanelA->MinSize.cy > m_pPanelA->Height() )
{
m_pPanelA->bottom = m_pPanelA->top + m_pPanelA->MinSize.cy;
}
m_pPanelB->top = m_pPanelA->bottom + m_nSplitterSize;
if (m_pPanelB->MinSize.cy > m_pPanelB->Height() )
{
m_pPanelB->top = m_pPanelB->bottom - m_pPanelB->MinSize.cy;
m_pPanelA->bottom = m_pPanelB->top - m_nSplitterSize;
}
}
if (m_pPanelA->Height() <= 2)
bShowA = FALSE;
if (m_pPanelB->Height() <= 2)
bShowB = FALSE;
}
#if 0
GetSplitArea(m_pSplitter);
m_pPanelA->OnResized();
m_pPanelB->OnResized();
m_pSplitter->OnResized();
#else
m_pPanelA->SetVisible( bShowA );
if( bShowA )
m_pPanelA->OnResized();
m_pPanelB->SetVisible( bShowB );
if( bShowB )
m_pPanelB->OnResized();
if( bShowS )
{
if( !bShowA )
m_nRatio = 0;
else if( !bShowB )
m_nRatio = 100;
GetSplitArea(m_pSplitter);
m_pSplitter->SetVisible( !m_IsSplitterFixed );
m_pSplitter->OnResized();
}
else
m_pSplitter->SetVisible( FALSE );
#endif
}
void CSplitContainer::SetSplitterPosition(int leftOfSplitter)
{
short nFixedPanel = m_FixedPanel;
m_FixedPanel = 0;
if (m_Orientation == CWndResizer::SPLIT_CONTAINER_H )
{
m_pPanelA->right = leftOfSplitter;
m_pPanelB->left = m_pPanelA->right + m_nSplitterSize;
}
else
{
m_pPanelA->bottom = leftOfSplitter;
m_pPanelB->top = m_pPanelA->bottom + m_nSplitterSize;
}
UpdateRatio();
OnResized();
UpdateRatio();
m_FixedPanel = nFixedPanel;
}
int CSplitContainer::GetSplitterPosition()
{
if (m_Orientation == CWndResizer::SPLIT_CONTAINER_H )
return m_pPanelA->right;
return m_pPanelA->bottom;
}
BOOL CSplitContainer::AddChild(CPanel * prc)
{
if (Children.GetCount() == 3)
return FALSE;
return CPanel::AddChild(prc);
}
BOOL CSplitContainer::RemoveChild(CPanel * prc)
{
return FALSE; }
void CSplitContainer::GetSplitArea(CRect * pSplitterPanel)
{
if (m_Orientation == CWndResizer::SPLIT_CONTAINER_H)
{
pSplitterPanel->left = m_pPanelA->right;
pSplitterPanel->top = this->top;
pSplitterPanel->right = m_pPanelB->left;
pSplitterPanel->bottom = this->bottom;
}
else {
pSplitterPanel->left = this->left;
pSplitterPanel->top = m_pPanelA->bottom;
pSplitterPanel->right = this->right;
pSplitterPanel->bottom = m_pPanelB->top;
}
}
int CSplitContainer::GetSplitterSize(CPanel * m_pPanelA, CPanel * m_pPanelB)
{
if (m_Orientation == CWndResizer::SPLIT_CONTAINER_H)
{
int nWidth = m_pPanelB->left - m_pPanelA->right;
return nWidth;
}
else {
int nHeight = m_pPanelB->top - m_pPanelA->bottom;
return nHeight;
}
}
void CSplitContainer::UpdateRatio()
{
if (m_Orientation == CWndResizer::SPLIT_CONTAINER_H )
{
m_nRatio = (double)m_pPanelA->Width() / (double)this->Width();
}
else
{
m_nRatio = (double)m_pPanelA->Height() / (double)this->Height();
}
}
CSplitContainer * CSplitContainer::Create(CPanel * pPanelA, CPanel * pPanelB)
{
#ifdef USE_SPLIT_PANEL
CSplitPanel * pSplitPanelA = dynamic_cast<CSplitPanel *>( pPanelA );
if (pSplitPanelA != NULL)
{
return NULL; }
CSplitPanel * pSplitPanelB = dynamic_cast<CSplitPanel *>( pPanelB );
if (pSplitPanelB != NULL)
{
return NULL; }
#endif
CRect rcDest(0, 0, 0, 0);
CWndResizer::SplitterOrientation orien = CWndResizer::SPLIT_CONTAINER_H;
if (::IntersectRect(&rcDest, pPanelA, pPanelB) == TRUE) {
return NULL;
}
if (pPanelA->right < pPanelB->left)
{
orien = CWndResizer::SPLIT_CONTAINER_H;
}
else if (pPanelA->bottom < pPanelB->top)
{
orien = CWndResizer::SPLIT_CONTAINER_V;
}
else
{
return NULL;
}
#ifdef USE_SPLIT_PANEL
if (pPanelA->Parent != NULL)
{
if (pPanelA->Parent->RemoveChild( pPanelA ) == FALSE)
{
return NULL;
}
}
if (pPanelB->Parent != NULL)
{
if (pPanelB->Parent->RemoveChild( pPanelB ) == FALSE)
{
return NULL;
}
}
#endif
CSplitContainer * pSpliter = new CSplitContainer(pPanelA, pPanelB, orien);
return pSpliter;
}
CString CSplitContainer::GetTypeName()
{
return _T("CSplitContainer");
}
void CSplitContainer::SetFixedPanel(short nFixedPanel )
{
m_FixedPanel = nFixedPanel;
}
short CSplitContainer::GetFixedPanel()
{
return m_FixedPanel;
}
void CSplitContainer::SetIsSplitterFixed(BOOL bFixed)
{
m_IsSplitterFixed = bFixed;
}
BOOL CSplitContainer::GetIsSplitterFixed()
{
return m_IsSplitterFixed;
}
void CSplitContainer::SetShowSplitterGrip(BOOL bShow)
{
m_pSplitter->m_pGrippePanel->m_bVisible = bShow;
}
BOOL CSplitContainer::GetShowSplitterGrip()
{
return m_pSplitter->m_pGrippePanel->m_bVisible;
}
CFlowLayoutPanel::CFlowLayoutPanel() : CPanel()
{
m_nItemSpacingX = 0;
m_nItemSpacingY = 0;
m_nFlowDirection = CWndResizer::LEFT_TO_RIGHT;
}
CFlowLayoutPanel::CFlowLayoutPanel(const CRect * prc) : CPanel(prc)
{
m_nItemSpacingX = 0;
m_nItemSpacingY = 0;
m_nFlowDirection = CWndResizer::LEFT_TO_RIGHT;
}
CFlowLayoutPanel::~CFlowLayoutPanel()
{
}
void CFlowLayoutPanel::OnResized()
{
int max = 0; int x = left;
int y = top;
POSITION pos = Children.GetHeadPosition();
if (pos != NULL)
{
CPanel * pPanel = Children.GetNext(pos);
pPanel->MoveToXY(x, y);
pPanel->OnResized();
if (m_nFlowDirection == CWndResizer::LEFT_TO_RIGHT)
{
x += pPanel->Width() + m_nItemSpacingX;
max = (pPanel->Height() > max ? pPanel->Height() : max);
}
else
{
y += pPanel->Height() + m_nItemSpacingY;
max = (pPanel->Width() > max ? pPanel->Width() : max);
}
}
if (m_nFlowDirection == CWndResizer::LEFT_TO_RIGHT)
{
while(pos != NULL)
{
CPanel * pPanel = Children.GetNext(pos);
if (x + pPanel->Width() > right)
{
x = left;
y += (max + m_nItemSpacingY);
max = 0;
}
pPanel->MoveToXY(x, y);
pPanel->OnResized();
x += pPanel->Width() + m_nItemSpacingX;
max = (pPanel->Height() > max ? pPanel->Height() : max);
}
}
else
{
while(pos != NULL)
{
CPanel * pPanel = Children.GetNext(pos);
if (y + pPanel->Height() > bottom)
{
x += (max + m_nItemSpacingX);
y = top;
max = 0;
}
pPanel->MoveToXY(x, y);
pPanel->OnResized();
y += pPanel->Height() + m_nItemSpacingY;
max = (pPanel->Width() > max ? pPanel->Width() : max);
}
}
}
CString CFlowLayoutPanel::GetTypeName()
{
return _T("CFlowLayoutPanel");
}
void CFlowLayoutPanel::SetFlowDirection(CWndResizer::FlowDirection direction)
{
m_nFlowDirection = direction;
}
CWndResizer::FlowDirection CFlowLayoutPanel::GetFlowDirection()
{
return m_nFlowDirection;
}
void CFlowLayoutPanel::SetItemSpacingX(int nSpace)
{
m_nItemSpacingX = nSpace;
}
int CFlowLayoutPanel::GetItemSpacingX()
{
return m_nItemSpacingX;
}
void CFlowLayoutPanel::SetItemSpacingY(int nSpace)
{
m_nItemSpacingY = nSpace;
}
int CFlowLayoutPanel::GetItemSpacingY()
{
return m_nItemSpacingY;
}
|