首页 > 代码库 > 窗口浮动4生1模式

窗口浮动4生1模式

//////////////////////////scbarg.h////////////////////

//Download by http://www.NewXing.com
#if !defined(__SCBARG_H__)
#define __SCBARG_H__

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

/////////////////////////////////////////////////////////////////////////
// CSCBButton (button info) helper class

class CSCBButton
{
public:
CSCBButton();

void Move(CPoint ptTo) {ptOrg = ptTo; };
CRect GetRect() { return CRect(ptOrg, CSize(13, 13)); };
void Paint(CDC* pDC);

BOOL bPushed;
BOOL bRaised;

protected:
CPoint ptOrg;
};

/////////////////////////////////////////////////////////////////////////
// CSizingControlBar control bar

#ifndef baseCCoolBar
#define baseCCoolBar CSizingControlBar
#endif

class CCoolBar : public baseCCoolBar
{
DECLARE_DYNAMIC(CCoolBar);

// Construction
public:
CCoolBar();

// Attributes
public:
virtual BOOL HasGripper() const;

// Operations
public:

// Overridables
virtual void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);
virtual BOOL Create(LPCTSTR lpszWindowName, CWnd* pParentWnd,
CSize sizeDefault, BOOL bHasGripper,
UINT nID, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP);
virtual BOOL Create(LPCTSTR lpszWindowName, CWnd* pParentWnd,
UINT nID, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP);

// Overrides
public:
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCoolBar)
//}}AFX_VIRTUAL

// Implementation
public:
void SetNotifyWindow(HWND hNotifyWnd);
HWND GetNotifyWindow() { return m_hNotifyWnd; };
virtual ~CCoolBar();

protected:
// implementation helpers
virtual void NcPaintGripper(CDC* pDC, CRect rcClient);
virtual void NcCalcClient(LPRECT pRc, UINT nDockBarID);

protected:
int m_cyGripper;
CSCBButton m_biHide;
BOOL m_bActive; // a child has focus
CString m_sFontFace;
HWND m_hNotifyWnd; // 消息通知窗口,默认为父窗口

// Generated message map functions
protected:
//{{AFX_MSG(CCoolBar)
afx_msg UINT OnNcHitTest(CPoint point);
afx_msg void OnNcLButtonUp(UINT nHitTest, CPoint point);
afx_msg LRESULT OnSetText(WPARAM wParam, LPARAM lParam);
afx_msg BOOL OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* pResult );
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
};

#endif // !defined(__SCBARG_H__)

////////////////////////////////////////////scbarg.cpp/////////////////////////////////

//Download by http://www.NewXing.com
// sizecbar.cpp : implementation file
//

#include "stdafx.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

int CALLBACK EnumFontFamProc(ENUMLOGFONT FAR *lpelf,
NEWTEXTMETRIC FAR *lpntm,
int FontType,
LPARAM lParam)
{
UNUSED_ALWAYS(lpelf);
UNUSED_ALWAYS(lpntm);
UNUSED_ALWAYS(FontType);
UNUSED_ALWAYS(lParam);

return 0;
}

/////////////////////////////////////////////////////////////////////////
// CCoolBar

IMPLEMENT_DYNAMIC(CCoolBar, baseCCoolBar);

CCoolBar::CCoolBar()
{
m_hNotifyWnd = NULL;
m_cyGripper = 12;
SetSCBStyle(GetSCBStyle() | SCBS_SIZECHILD);
m_bActive = FALSE;
CDC dc;
dc.CreateCompatibleDC(NULL);
m_sFontFace = (::EnumFontFamilies(dc.m_hDC,
_T("宋体"), (FONTENUMPROC) EnumFontFamProc, 0) == 0) ?
_T("宋体") : _T("Tahoma");
dc.DeleteDC();
}

CCoolBar::~CCoolBar()
{
}

BEGIN_MESSAGE_MAP(CCoolBar, baseCCoolBar)
//{{AFX_MSG_MAP(CCoolBar)
ON_WM_NCLBUTTONUP()
ON_WM_NCHITTEST()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_SETTEXT, OnSetText)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////
// CCoolBar message handlers

BOOL CCoolBar::Create(LPCTSTR lpszWindowName, CWnd* pParentWnd,
CSize sizeDefault, BOOL bHasGripper,
UINT nID, DWORD dwStyle)
{
ASSERT_VALID(pParentWnd);
m_hNotifyWnd = pParentWnd->m_hWnd;

return baseCCoolBar::Create(lpszWindowName, pParentWnd, sizeDefault, bHasGripper, nID, dwStyle);
}

BOOL CCoolBar::Create(LPCTSTR lpszWindowName,
CWnd* pParentWnd, UINT nID,
DWORD dwStyle)
{
ASSERT_VALID(pParentWnd);
m_hNotifyWnd = pParentWnd->m_hWnd;

return baseCCoolBar::Create(lpszWindowName, pParentWnd, nID, dwStyle);
}

/////////////////////////////////////////////////////////////////////////
// Mouse Handling
//

void CCoolBar::OnNcLButtonUp(UINT nHitTest, CPoint point)
{
if (nHitTest == HTCLOSE)
m_pDockSite->ShowControlBar(this, FALSE, FALSE); // hide

baseCCoolBar::OnNcLButtonUp(nHitTest, point);
}

#ifndef COLOR_GRADIENTACTIVECAPTION
#define COLOR_GRADIENTACTIVECAPTION 27
#define COLOR_GRADIENTINACTIVECAPTION 28
#define SPI_GETGRADIENTCAPTIONS 0x1008
#endif

void CCoolBar::NcCalcClient(LPRECT pRc, UINT nDockBarID)
{
CRect rcBar(pRc); // save the bar rect

// subtract edges
baseCCoolBar::NcCalcClient(pRc, nDockBarID);

if (!HasGripper())
return;

CRect rc(pRc); // the client rect as calculated by the base class

BOOL bHorz = (nDockBarID == AFX_IDW_DOCKBAR_TOP) ||
(nDockBarID == AFX_IDW_DOCKBAR_BOTTOM);

if (bHorz)
rc.DeflateRect(m_cyGripper, 0, 0, 0);
else
rc.DeflateRect(0, m_cyGripper, 0, 0);

// set position for the "x" (hide bar) button
CPoint ptOrgBtn;
if (bHorz)
ptOrgBtn = CPoint(rc.left - 14, rc.top);
else
ptOrgBtn = CPoint(rc.right - 12, rc.top - 14);

m_biHide.Move(ptOrgBtn - rcBar.TopLeft());

*pRc = rc;
}

void CCoolBar::NcPaintGripper(CDC* pDC, CRect rcClient)
{
if (!HasGripper())
return;
#ifndef _SCB_STYLE_FLAT
CRect gripper = rcClient;
CRect rcbtn = m_biHide.GetRect();
BOOL bHorz = IsHorzDocked();

gripper.DeflateRect(1, 1);
if (bHorz)
{ // gripper at left
gripper.left -= m_cyGripper;
gripper.right = gripper.left + 3;
gripper.top = rcbtn.bottom + 3;
}
else
{ // gripper at top
gripper.top -= m_cyGripper;
gripper.bottom = gripper.top + 3;
gripper.right = rcbtn.left - 3;
}

pDC->Draw3dRect(gripper, ::GetSysColor(COLOR_BTNHIGHLIGHT),
::GetSysColor(COLOR_BTNSHADOW));

gripper.OffsetRect(bHorz ? 3 : 0, bHorz ? 0 : 3);

pDC->Draw3dRect(gripper, ::GetSysColor(COLOR_BTNHIGHLIGHT),
::GetSysColor(COLOR_BTNSHADOW));

m_biHide.Paint(pDC);

#else

// compute the caption rectangle
BOOL bHorz = IsHorzDocked();
CRect rcGrip = rcClient;
CRect rcBtn = m_biHide.GetRect();
if (bHorz)
{ // right side gripper
rcGrip.left -= m_cyGripper + 1;
rcGrip.right = rcGrip.left + 11;
rcGrip.top = rcBtn.bottom + 3;
}
else
{ // gripper at top
rcGrip.top -= m_cyGripper + 1;
rcGrip.bottom = rcGrip.top + 11;
rcGrip.right = rcBtn.left - 3;
}
rcGrip.InflateRect(bHorz ? 1 : 0, bHorz ? 0 : 1);

// draw the caption background
//CBrush br;
COLORREF clrCptn = m_bActive ?
::GetSysColor(COLOR_ACTIVECAPTION) :
::GetSysColor(COLOR_INACTIVECAPTION);

// query gradient info (usually TRUE for Win98/Win2k)
BOOL bGradient = FALSE;
::SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &bGradient, 0);

if (!bGradient)
pDC->FillSolidRect(&rcGrip, clrCptn); // solid color
else
{
// gradient from left to right or from bottom to top
// get second gradient color (the right end)
COLORREF clrCptnRight = m_bActive ?
::GetSysColor(COLOR_GRADIENTACTIVECAPTION) :
::GetSysColor(COLOR_GRADIENTINACTIVECAPTION);

// this will make 2^6 = 64 fountain steps
int nShift = 6;
int nSteps = 1 << nShift;

for (int i = 0; i < nSteps; i++)
{
// do a little alpha blending
int nR = (GetRValue(clrCptn) * (nSteps - i) +
GetRValue(clrCptnRight) * i) >> nShift;
int nG = (GetGValue(clrCptn) * (nSteps - i) +
GetGValue(clrCptnRight) * i) >> nShift;
int nB = (GetBValue(clrCptn) * (nSteps - i) +
GetBValue(clrCptnRight) * i) >> nShift;

COLORREF cr = RGB(nR, nG, nB);

// then paint with the resulting color
CRect r2 = rcGrip;
if (bHorz)
{
r2.bottom = rcGrip.bottom -
((i * rcGrip.Height()) >> nShift);
r2.top = rcGrip.bottom -
(((i + 1) * rcGrip.Height()) >> nShift);
if (r2.Height() > 0)
pDC->FillSolidRect(r2, cr);
}
else
{
r2.left = rcGrip.left +
((i * rcGrip.Width()) >> nShift);
r2.right = rcGrip.left +
(((i + 1) * rcGrip.Width()) >> nShift);
if (r2.Width() > 0)
pDC->FillSolidRect(r2, cr);
}
}
}

// draw the caption text - first select a font
CFont font;
int ppi = pDC->GetDeviceCaps(LOGPIXELSX);
int pointsize = MulDiv(96, 96, ppi); // 8.5 points at 96 ppi

LOGFONT lf;
BOOL bFont = font.CreatePointFont(pointsize, m_sFontFace);
if (bFont)
{
// get the text color
COLORREF clrCptnText = m_bActive ?
::GetSysColor(COLOR_CAPTIONTEXT) :
::GetSysColor(COLOR_INACTIVECAPTIONTEXT);

int nOldBkMode = pDC->SetBkMode(TRANSPARENT);
COLORREF clrOldText = pDC->SetTextColor(clrCptnText);

if (bHorz)
{
// rotate text 90 degrees CCW if horizontally docked
font.GetLogFont(&lf);
font.DeleteObject();
lf.lfEscapement = 900;
font.CreateFontIndirect(&lf);
}

CFont* pOldFont = pDC->SelectObject(&font);
CString sTitle;
GetWindowText(sTitle);

CPoint ptOrg = bHorz ?
CPoint(rcGrip.left - 1, rcGrip.bottom - 3) :
CPoint(rcGrip.left + 3, rcGrip.top - 1);

pDC->ExtTextOut(ptOrg.x, ptOrg.y,
ETO_CLIPPED, rcGrip, sTitle, NULL);

pDC->SelectObject(pOldFont);
pDC->SetBkMode(nOldBkMode);
pDC->SetTextColor(clrOldText);
}

// draw the button
m_biHide.Paint(pDC);
#endif
}

UINT CCoolBar::OnNcHitTest(CPoint point)
{
CRect rcBar;
GetWindowRect(rcBar);

UINT nRet = baseCCoolBar::OnNcHitTest(point);
if (nRet != HTCLIENT)
return nRet;

CRect rc = m_biHide.GetRect();
rc.OffsetRect(rcBar.TopLeft());
if (rc.PtInRect(point))
return HTCLOSE;

return HTCLIENT;
}

/////////////////////////////////////////////////////////////////////////
// CCoolBar implementation helpers

void CCoolBar::OnUpdateCmdUI(CFrameWnd* pTarget,
BOOL bDisableIfNoHndler)
{
UNUSED_ALWAYS(bDisableIfNoHndler);
UNUSED_ALWAYS(pTarget);

if (!HasGripper())
return;

BOOL bNeedPaint = FALSE;

CPoint pt;
::GetCursorPos(&pt);
BOOL bHit = (OnNcHitTest(pt) == HTCLOSE);
BOOL bLButtonDown = (::GetKeyState(VK_LBUTTON) < 0);

BOOL bWasPushed = m_biHide.bPushed;
m_biHide.bPushed = bHit && bLButtonDown;

BOOL bWasRaised = m_biHide.bRaised;
m_biHide.bRaised = bHit && !bLButtonDown;

CWnd* pFocus = GetFocus();
BOOL bActiveOld = m_bActive;
m_bActive = (pFocus->GetSafeHwnd() && IsChild(pFocus));
if (m_bActive != bActiveOld)
bNeedPaint = TRUE;

bNeedPaint |= (m_biHide.bPushed ^ bWasPushed) ||
(m_biHide.bRaised ^ bWasRaised);

if (bNeedPaint)
SendMessage(WM_NCPAINT);
}

/////////////////////////////////////////////////////////////////////////
// CSCBButton

CSCBButton::CSCBButton()
{
bRaised = FALSE;
bPushed = FALSE;
}

void CSCBButton::Paint(CDC* pDC)
{
CRect rc = GetRect();

if (bPushed)
pDC->Draw3dRect(rc, ::GetSysColor(COLOR_BTNSHADOW),
::GetSysColor(COLOR_BTNHIGHLIGHT));
else
if (bRaised)
pDC->Draw3dRect(rc, ::GetSysColor(COLOR_BTNHIGHLIGHT),
::GetSysColor(COLOR_BTNSHADOW));

COLORREF clrOldTextColor = pDC->GetTextColor();
pDC->SetTextColor(::GetSysColor(COLOR_BTNTEXT));
int nPrevBkMode = pDC->SetBkMode(TRANSPARENT);
CFont font;
int ppi = pDC->GetDeviceCaps(LOGPIXELSX);
int pointsize = MulDiv(60, 96, ppi); // 6 points at 96 ppi
font.CreatePointFont(pointsize, _T("Marlett"));
CFont* oldfont = pDC->SelectObject(&font);

pDC->TextOut(ptOrg.x + 3, ptOrg.y + 3, CString(_T("r"))); // x-like

pDC->SelectObject(oldfont);
pDC->SetBkMode(nPrevBkMode);
pDC->SetTextColor(clrOldTextColor);
}

BOOL CCoolBar::HasGripper() const
{
#if defined(_SCB_MINIFRAME_CAPTION) || !defined(_SCB_REPLACE_MINIFRAME)
// if the miniframe has a caption, don‘t display the gripper
if (IsFloating())
return FALSE;
#endif //_SCB_MINIFRAME_CAPTION

return TRUE;
}

LRESULT CCoolBar::OnSetText(WPARAM wParam, LPARAM lParam)
{
LRESULT lResult = baseCCoolBar::OnSetText(wParam, lParam);

SendMessage(WM_NCPAINT);

return lResult;
}

BOOL CCoolBar::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// 将WM_NOTIFY消息转交给消息通知窗口处理

::SendMessage(m_hNotifyWnd, WM_NOTIFY, wParam, lParam);
*pResult = 0;

return TRUE;
}

void CCoolBar::SetNotifyWindow(HWND hNotifyWnd)
{
m_hNotifyWnd = hNotifyWnd;
}

/////////////////////////////////////////////////////////sizecbar.h///////////////////////////////////////

//Download by http://www.NewXing.com

#if !defined(__SIZECBAR_H__)
#define __SIZECBAR_H__

#include <afxpriv.h> // for CDockContext
#include <afxtempl.h> // for CTypedPtrArray

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000


#if defined(_SCB_MINIFRAME_CAPTION) && !defined(_SCB_REPLACE_MINIFRAME)
#error "_SCB_MINIFRAME_CAPTION requires _SCB_REPLACE_MINIFRAME"
#endif

/////////////////////////////////////////////////////////////////////////
// CSCBDockBar dummy class for access to protected members

class CSCBDockBar : public CDockBar
{
friend class CSizingControlBar;
};

/////////////////////////////////////////////////////////////////////////
// CSizingControlBar control bar styles

#define SCBS_EDGELEFT 0x00000001
#define SCBS_EDGERIGHT 0x00000002
#define SCBS_EDGETOP 0x00000004
#define SCBS_EDGEBOTTOM 0x00000008
#define SCBS_EDGEALL 0x0000000F
#define SCBS_SHOWEDGES 0x00000010
#define SCBS_SIZECHILD 0x00000020

/////////////////////////////////////////////////////////////////////////
// CSizingControlBar control bar

#ifndef baseCSizingControlBar
#define baseCSizingControlBar CControlBar
#endif

class CSizingControlBar;
typedef CTypedPtrArray <CPtrArray, CSizingControlBar*> CSCBArray;

class CSizingControlBar : public baseCSizingControlBar
{
DECLARE_DYNAMIC(CSizingControlBar);

// Construction
public:
CSizingControlBar();

virtual BOOL Create(LPCTSTR lpszWindowName, CWnd* pParentWnd,
CSize sizeDefault, BOOL bHasGripper,
UINT nID, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP);
virtual BOOL Create(LPCTSTR lpszWindowName, CWnd* pParentWnd,
UINT nID, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP);

// Attributes
public:
const BOOL IsFloating() const;
const BOOL IsHorzDocked() const;
const BOOL IsVertDocked() const;
const BOOL IsSideTracking() const;
const BOOL GetSCBStyle() const {return m_dwSCBStyle;}

// Operations
public:
#if defined(_SCB_REPLACE_MINIFRAME) && !defined(_SCB_MINIFRAME_CAPTION)
void EnableDocking(DWORD dwDockStyle);
#endif
virtual void LoadState(LPCTSTR lpszProfileName);
virtual void SaveState(LPCTSTR lpszProfileName);
static void GlobalLoadState(CFrameWnd* pFrame, LPCTSTR lpszProfileName);
static void GlobalSaveState(CFrameWnd* pFrame, LPCTSTR lpszProfileName);
void SetSCBStyle(DWORD dwSCBStyle)
{m_dwSCBStyle = (dwSCBStyle & ~SCBS_EDGEALL);}

// Overridables
virtual void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);

// Overrides
public:
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSizingControlBar)
public:
virtual CSize CalcFixedLayout(BOOL bStretch, BOOL bHorz);
virtual CSize CalcDynamicLayout(int nLength, DWORD dwMode);
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~CSizingControlBar();

protected:
// implementation helpers
UINT GetEdgeHTCode(int nEdge);
BOOL GetEdgeRect(CRect rcWnd, UINT nHitTest, CRect& rcEdge);
virtual void StartTracking(UINT nHitTest, CPoint point);
virtual void StopTracking();
virtual void OnTrackUpdateSize(CPoint& point);
virtual void OnTrackInvertTracker();
virtual void NcPaintGripper(CDC* pDC, CRect rcClient);
virtual void NcCalcClient(LPRECT pRc, UINT nDockBarID);

virtual void AlignControlBars();
void GetRowInfo(int& nFirst, int& nLast, int& nThis);
void GetRowSizingBars(CSCBArray& arrSCBars);
void GetRowSizingBars(CSCBArray& arrSCBars, int& nThis);
BOOL NegotiateSpace(int nLengthTotal, BOOL bHorz);

protected:
DWORD m_dwSCBStyle;
UINT m_htEdge;

CSize m_szHorz;
CSize m_szVert;
CSize m_szFloat;
CSize m_szMinHorz;
CSize m_szMinVert;
CSize m_szMinFloat;
int m_nTrackPosMin;
int m_nTrackPosMax;
int m_nTrackPosOld;
int m_nTrackEdgeOfs;
BOOL m_bTracking;
BOOL m_bKeepSize;
BOOL m_bParentSizing;
BOOL m_bDragShowContent;
UINT m_nDockBarID;
int m_cxEdge;

// Generated message map functions
protected:
//{{AFX_MSG(CSizingControlBar)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnNcPaint();
afx_msg void OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp);
afx_msg UINT OnNcHitTest(CPoint point);
afx_msg void OnCaptureChanged(CWnd *pWnd);
afx_msg void OnSettingChange(UINT uFlags, LPCTSTR lpszSection);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void onm ouseMove(UINT nFlags, CPoint point);
afx_msg void OnNcLButtonDown(UINT nHitTest, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnWindowPosChanging(WINDOWPOS FAR* lpwndpos);
afx_msg void OnPaint();
afx_msg void OnClose();
afx_msg void OnSize(UINT nType, int cx, int cy);
//}}AFX_MSG
afx_msg LRESULT OnSetText(WPARAM wParam, LPARAM lParam);

DECLARE_MESSAGE_MAP()

#ifdef _SCB_REPLACE_MINIFRAME
friend class CSCBMiniDockFrameWnd;
#endif //_SCB_REPLACE_MINIFRAME
};

#ifdef _SCB_REPLACE_MINIFRAME
#ifndef _SCB_MINIFRAME_CAPTION
/////////////////////////////////////////////////////////////////////////
// CSCBDockContext dockcontext

class CSCBDockContext : public CDockContext
{
public:
// Construction
CSCBDockContext(CControlBar* pBar) : CDockContext(pBar) {}

// Drag Operations
virtual void StartDrag(CPoint pt);
};
#endif //_SCB_MINIFRAME_CAPTION

/////////////////////////////////////////////////////////////////////////
// CSCBMiniDockFrameWnd miniframe

#ifndef baseCSCBMiniDockFrameWnd
#define baseCSCBMiniDockFrameWnd CMiniDockFrameWnd
#endif

class CSCBMiniDockFrameWnd : public baseCSCBMiniDockFrameWnd
{
DECLARE_DYNCREATE(CSCBMiniDockFrameWnd)

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSCBMiniDockFrameWnd)
public:
virtual BOOL Create(CWnd* pParent, DWORD dwBarStyle);
//}}AFX_VIRTUAL

// Implementation
public:
CSizingControlBar* GetSizingControlBar();

//{{AFX_MSG(CSCBMiniDockFrameWnd)
afx_msg void OnNcLButtonDown(UINT nHitTest, CPoint point);
afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);
afx_msg void OnWindowPosChanging(WINDOWPOS FAR* lpwndpos);
afx_msg void OnSize(UINT nType, int cx, int cy);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif //_SCB_REPLACE_MINIFRAME

#endif // !defined(__SIZECBAR_H__)

///////////////////////////////////////////////////sizecbar.cpp///////////////////////////////////

//Download by http://www.NewXing.com
// sizecbar.cpp : implementation file
//

#include "stdafx.h"
#include "sizecbar.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////
// CSizingControlBar

IMPLEMENT_DYNAMIC(CSizingControlBar, baseCSizingControlBar);

CSizingControlBar::CSizingControlBar()
{
m_szMinHorz = CSize(33, 32);
m_szMinVert = CSize(33, 32);
m_szMinFloat = CSize(37, 32);
m_szHorz = CSize(200, 200);
m_szVert = CSize(200, 200);
m_szFloat = CSize(200, 200);
m_bTracking = FALSE;
m_bKeepSize = FALSE;
m_bParentSizing = FALSE;
m_cxEdge = 5;
m_bDragShowContent = FALSE;
m_nDockBarID = 0;
m_dwSCBStyle = 0;
}

CSizingControlBar::~CSizingControlBar()
{
}

BEGIN_MESSAGE_MAP(CSizingControlBar, baseCSizingControlBar)
//{{AFX_MSG_MAP(CSizingControlBar)
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_NCPAINT()
ON_WM_NCCALCSIZE()
ON_WM_WINDOWPOSCHANGING()
ON_WM_CAPTURECHANGED()
ON_WM_SETTINGCHANGE()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_NCLBUTTONDOWN()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONDBLCLK()
ON_WM_RBUTTONDOWN()
ON_WM_NCMOUSEMOVE()
ON_WM_NCHITTEST()
ON_WM_CLOSE()
ON_WM_SIZE()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_SETTEXT, OnSetText)
END_MESSAGE_MAP()

// old creation method, still here for compatibility reasons
BOOL CSizingControlBar::Create(LPCTSTR lpszWindowName, CWnd* pParentWnd,
CSize sizeDefault, BOOL bHasGripper,
UINT nID, DWORD dwStyle)
{
UNUSED_ALWAYS(bHasGripper);

m_szHorz = m_szVert = m_szFloat = sizeDefault;
return Create(lpszWindowName, pParentWnd, nID, dwStyle);
}

// preffered creation method
BOOL CSizingControlBar::Create(LPCTSTR lpszWindowName,
CWnd* pParentWnd, UINT nID,
DWORD dwStyle)
{
// must have a parent
ASSERT_VALID(pParentWnd);
// cannot be both fixed and dynamic
// (CBRS_SIZE_DYNAMIC is used for resizng when floating)
ASSERT (!((dwStyle & CBRS_SIZE_FIXED) &&
(dwStyle & CBRS_SIZE_DYNAMIC)));

m_dwStyle = dwStyle & CBRS_ALL; // save the control bar styles

// register and create the window - skip CControlBar::Create()
CString wndclass = ::AfxRegisterWndClass(CS_DBLCLKS,
::LoadCursor(NULL, IDC_ARROW),
::GetSysColorBrush(COLOR_BTNFACE), 0);

dwStyle &= ~CBRS_ALL; // keep only the generic window styles
dwStyle |= WS_CLIPCHILDREN; // prevents flashing
if (!CWnd::Create(wndclass, lpszWindowName, dwStyle,
CRect(0, 0, 0, 0), pParentWnd, nID))
return FALSE;

return TRUE;
}

/////////////////////////////////////////////////////////////////////////
// CSizingControlBar operations
#if defined(_SCB_REPLACE_MINIFRAME) && !defined(_SCB_MINIFRAME_CAPTION)
void CSizingControlBar::EnableDocking(DWORD dwDockStyle)
{
// must be CBRS_ALIGN_XXX or CBRS_FLOAT_MULTI only
ASSERT((dwDockStyle & ~(CBRS_ALIGN_ANY|CBRS_FLOAT_MULTI)) == 0);
// cannot have the CBRS_FLOAT_MULTI style
ASSERT((dwDockStyle & CBRS_FLOAT_MULTI) == 0);
// the bar must have CBRS_SIZE_DYNAMIC style
ASSERT((m_dwStyle & CBRS_SIZE_DYNAMIC) != 0);

m_dwDockStyle = dwDockStyle;
if (m_pDockContext == NULL)
m_pDockContext = new CSCBDockContext(this);

// permanently wire the bar‘s owner to its current parent
if (m_hWndOwner == NULL)
m_hWndOwner = ::GetParent(m_hWnd);
}
#endif

/////////////////////////////////////////////////////////////////////////
// CSizingControlBar message handlers

int CSizingControlBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (baseCSizingControlBar::OnCreate(lpCreateStruct) == -1)
return -1;

// query SPI_GETDRAGFULLWINDOWS system parameter
// OnSettingChange() will update m_bDragShowContent
m_bDragShowContent = FALSE;
::SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0,
&m_bDragShowContent, 0);

// uncomment this line if you want raised borders
// m_dwSCBStyle |= SCBS_SHOWEDGES;

return 0;
}


LRESULT CSizingControlBar::OnSetText(WPARAM wParam, LPARAM lParam)
{
UNUSED_ALWAYS(wParam);

LRESULT lResult = CWnd::Default();

if (IsFloating() &&
GetParentFrame()->IsKindOf(RUNTIME_CLASS(CMiniDockFrameWnd)))
{
m_pDockBar->SetWindowText((LPCTSTR) lParam); // update dockbar
GetParentFrame()->DelayRecalcLayout(); // refresh miniframe
}

return lResult;
}

const BOOL CSizingControlBar::IsFloating() const
{
return !IsHorzDocked() && !IsVertDocked();
}

const BOOL CSizingControlBar::IsHorzDocked() const
{
return (m_nDockBarID == AFX_IDW_DOCKBAR_TOP ||
m_nDockBarID == AFX_IDW_DOCKBAR_BOTTOM);
}

const BOOL CSizingControlBar::IsVertDocked() const
{
return (m_nDockBarID == AFX_IDW_DOCKBAR_LEFT ||
m_nDockBarID == AFX_IDW_DOCKBAR_RIGHT);
}

const BOOL CSizingControlBar::IsSideTracking() const
{
// don‘t call this when not tracking
ASSERT(m_bTracking && !IsFloating());

return (m_htEdge == HTLEFT || m_htEdge == HTRIGHT) ?
IsHorzDocked() : IsVertDocked();
}

CSize CSizingControlBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
{
if (bStretch) // the bar is stretched (is not the child of a dockbar)
if (bHorz)
return CSize(32767, m_szHorz.cy);
else
return CSize(m_szVert.cx, 32767);

// dirty cast - we need access to protected CDockBar members
CSCBDockBar* pDockBar = (CSCBDockBar*) m_pDockBar;

// force imediate RecalcDelayShow() for all sizing bars on the row
// with delayShow/delayHide flags set to avoid IsVisible() problems
CSCBArray arrSCBars;
GetRowSizingBars(arrSCBars);
AFX_SIZEPARENTPARAMS layout;
layout.hDWP = pDockBar->m_bLayoutQuery ?
NULL : ::BeginDeferWindowPos(arrSCBars.GetSize());
for (int i = 0; i < arrSCBars.GetSize(); i++)
if (arrSCBars[i]->m_nStateFlags & (delayHide|delayShow))
arrSCBars[i]->RecalcDelayShow(&layout);
if (layout.hDWP != NULL)
::EndDeferWindowPos(layout.hDWP);

// get available length
CRect rc = pDockBar->m_rectLayout;
if (rc.IsRectEmpty())
m_pDockSite->GetClientRect(&rc);
int nLengthTotal = bHorz ? rc.Width() + 2 : rc.Height() - 2;

if (IsVisible() && !IsFloating() &&
m_bParentSizing && arrSCBars[0] == this)
if (NegotiateSpace(nLengthTotal, (bHorz != FALSE)))
AlignControlBars();

m_bParentSizing = FALSE;

if (bHorz)
return CSize(max(m_szMinHorz.cx, m_szHorz.cx),
max(m_szMinHorz.cy, m_szHorz.cy));

return CSize(max(m_szMinVert.cx, m_szVert.cx),
max(m_szMinVert.cy, m_szVert.cy));
}

CSize CSizingControlBar::CalcDynamicLayout(int nLength, DWORD dwMode)
{
if (dwMode & (LM_HORZDOCK | LM_VERTDOCK)) // docked ?
{
if (nLength == -1)
m_bParentSizing = TRUE;

return baseCSizingControlBar::CalcDynamicLayout(nLength, dwMode);
}

if (dwMode & LM_MRUWIDTH) return m_szFloat;
if (dwMode & LM_COMMIT) return m_szFloat; // already committed

#ifndef _SCB_REPLACE_MINIFRAME
// check for dialgonal resizing hit test
int nHitTest = m_pDockContext->m_nHitTest;
if (IsFloating() &&
(nHitTest == HTTOPLEFT || nHitTest == HTBOTTOMLEFT ||
nHitTest == HTTOPRIGHT || nHitTest == HTBOTTOMRIGHT))
{
CPoint ptCursor;
::GetCursorPos(&ptCursor);

CRect rFrame, rBar;
GetParentFrame()->GetWindowRect(&rFrame);
GetWindowRect(&rBar);

if (nHitTest == HTTOPLEFT || nHitTest == HTBOTTOMLEFT)
{
m_szFloat.cx = rFrame.left + rBar.Width() - ptCursor.x;
m_pDockContext->m_rectFrameDragHorz.left =
min(ptCursor.x, rFrame.left + rBar.Width() - m_szMinFloat.cx);
}

if (nHitTest == HTTOPLEFT || nHitTest == HTTOPRIGHT)
{
m_szFloat.cy = rFrame.top + rBar.Height() - ptCursor.y;
m_pDockContext->m_rectFrameDragHorz.top =
min(ptCursor.y, rFrame.top + rBar.Height() - m_szMinFloat.cy);
}

if (nHitTest == HTTOPRIGHT || nHitTest == HTBOTTOMRIGHT)
m_szFloat.cx = rBar.Width() + ptCursor.x - rFrame.right;

if (nHitTest == HTBOTTOMLEFT || nHitTest == HTBOTTOMRIGHT)
m_szFloat.cy = rBar.Height() + ptCursor.y - rFrame.bottom;
}
else
#endif //_SCB_REPLACE_MINIFRAME
((dwMode & LM_LENGTHY) ? m_szFloat.cy : m_szFloat.cx) = nLength;

m_szFloat.cx = max(m_szFloat.cx, m_szMinFloat.cx);
m_szFloat.cy = max(m_szFloat.cy, m_szMinFloat.cy);

return m_szFloat;
}

void CSizingControlBar::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
{
// force non-client recalc if moved or resized
lpwndpos->flags |= SWP_FRAMECHANGED;

baseCSizingControlBar::OnWindowPosChanging(lpwndpos);

// find on which side are we docked
m_nDockBarID = GetParent()->GetDlgCtrlID();

if (!IsFloating())
if (lpwndpos->flags & SWP_SHOWWINDOW)
m_bKeepSize = TRUE;
}

/////////////////////////////////////////////////////////////////////////
// Mouse Handling
//
void CSizingControlBar::OnLButtonDown(UINT nFlags, CPoint point)
{
if (m_pDockBar != NULL)
{
// start the drag
ASSERT(m_pDockContext != NULL);
ClientToScreen(&point);
m_pDockContext->StartDrag(point);
}
else
CWnd::OnLButtonDown(nFlags, point);
}

void CSizingControlBar::OnLButtonDblClk(UINT nFlags, CPoint point)
{
if (m_pDockBar != NULL)
{
// toggle docking
ASSERT(m_pDockContext != NULL);
m_pDockContext->ToggleDocking();
}
else
CWnd::OnLButtonDblClk(nFlags, point);
}

void CSizingControlBar::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
UNUSED_ALWAYS(point);

if (m_bTracking || IsFloating())
return;

if ((nHitTest >= HTSIZEFIRST) && (nHitTest <= HTSIZELAST))
StartTracking(nHitTest, point); // sizing edge hit
}

void CSizingControlBar::OnLButtonUp(UINT nFlags, CPoint point)
{
if (m_bTracking)
StopTracking();

baseCSizingControlBar::OnLButtonUp(nFlags, point);
}

void CSizingControlBar::OnRButtonDown(UINT nFlags, CPoint point)
{
if (m_bTracking)
StopTracking();

baseCSizingControlBar::OnRButtonDown(nFlags, point);
}

void CSizingControlBar::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_bTracking)
{
CPoint ptScreen = point;
ClientToScreen(&ptScreen);

OnTrackUpdateSize(ptScreen);
}

baseCSizingControlBar::OnMouseMove(nFlags, point);
}

void CSizingControlBar::OnCaptureChanged(CWnd *pWnd)
{
if (m_bTracking && (pWnd != this))
StopTracking();

baseCSizingControlBar::OnCaptureChanged(pWnd);
}

void CSizingControlBar::OnNcCalcSize(BOOL bCalcValidRects,
NCCALCSIZE_PARAMS FAR* lpncsp)
{
UNUSED_ALWAYS(bCalcValidRects);

#ifndef _SCB_REPLACE_MINIFRAME
// Enable diagonal resizing for floating miniframe
if (IsFloating())
{
CFrameWnd* pFrame = GetParentFrame();
if (pFrame != NULL &&
pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)))
{
DWORD dwStyle = ::GetWindowLong(pFrame->m_hWnd, GWL_STYLE);
if ((dwStyle & MFS_4THICKFRAME) != 0)
{
pFrame->ModifyStyle(MFS_4THICKFRAME, 0); // clear
GetParent()->ModifyStyle(0, WS_CLIPCHILDREN);
}
}
}
#endif _SCB_REPLACE_MINIFRAME

// compute the the client area
m_dwSCBStyle &= ~SCBS_EDGEALL;

// add resizing edges between bars on the same row
if (!IsFloating() && m_pDockBar != NULL)
{
CSCBArray arrSCBars;
int nThis;
GetRowSizingBars(arrSCBars, nThis);

BOOL bHorz = IsHorzDocked();
if (nThis > 0)
m_dwSCBStyle |= bHorz ? SCBS_EDGELEFT : SCBS_EDGETOP;

if (nThis < arrSCBars.GetUpperBound())
m_dwSCBStyle |= bHorz ? SCBS_EDGERIGHT : SCBS_EDGEBOTTOM;
}

NcCalcClient(&lpncsp->rgrc[0], m_nDockBarID);
}

void CSizingControlBar::NcCalcClient(LPRECT pRc, UINT nDockBarID)
{
CRect rc(pRc);

rc.DeflateRect(3, 5, 3, 3);
if (nDockBarID != AFX_IDW_DOCKBAR_FLOAT)
rc.DeflateRect(2, 0, 2, 2);

switch(nDockBarID)
{
case AFX_IDW_DOCKBAR_TOP:
m_dwSCBStyle |= SCBS_EDGEBOTTOM;
break;
case AFX_IDW_DOCKBAR_BOTTOM:
m_dwSCBStyle |= SCBS_EDGETOP;
break;
case AFX_IDW_DOCKBAR_LEFT:
m_dwSCBStyle |= SCBS_EDGERIGHT;
break;
case AFX_IDW_DOCKBAR_RIGHT:
m_dwSCBStyle |= SCBS_EDGELEFT;
break;
}

// make room for edges only if they will be painted
if (m_dwSCBStyle & SCBS_SHOWEDGES)
rc.DeflateRect(
(m_dwSCBStyle & SCBS_EDGELEFT) ? m_cxEdge : 0,
(m_dwSCBStyle & SCBS_EDGETOP) ? m_cxEdge : 0,
(m_dwSCBStyle & SCBS_EDGERIGHT) ? m_cxEdge : 0,
(m_dwSCBStyle & SCBS_EDGEBOTTOM) ? m_cxEdge : 0);

*pRc = rc;
}

void CSizingControlBar::OnNcPaint()
{
// get window DC that is clipped to the non-client area
CWindowDC dc(this);

CRect rcClient, rcBar;
GetClientRect(rcClient);
ClientToScreen(rcClient);
GetWindowRect(rcBar);
rcClient.OffsetRect(-rcBar.TopLeft());
rcBar.OffsetRect(-rcBar.TopLeft());

CDC mdc;
mdc.CreateCompatibleDC(&dc);

CBitmap bm;
bm.CreateCompatibleBitmap(&dc, rcBar.Width(), rcBar.Height());
CBitmap* pOldBm = mdc.SelectObject(&bm);

// draw borders in non-client area
CRect rcDraw = rcBar;
DrawBorders(&mdc, rcDraw);

// erase the NC background
mdc.FillRect(rcDraw, CBrush::FromHandle(
(HBRUSH) GetClassLong(m_hWnd, GCL_HBRBACKGROUND)));

if (m_dwSCBStyle & SCBS_SHOWEDGES)
{
CRect rcEdge; // paint the sizing edges
for (int i = 0; i < 4; i++)
if (GetEdgeRect(rcBar, GetEdgeHTCode(i), rcEdge))
mdc.Draw3dRect(rcEdge, ::GetSysColor(COLOR_BTNHIGHLIGHT),
::GetSysColor(COLOR_BTNSHADOW));
}

NcPaintGripper(&mdc, rcClient);

// client area is not our bussiness :)
dc.IntersectClipRect(rcBar);
dc.ExcludeClipRect(rcClient);

dc.BitBlt(0, 0, rcBar.Width(), rcBar.Height(), &mdc, 0, 0, SRCCOPY);

ReleaseDC(&dc);

mdc.SelectObject(pOldBm);
bm.DeleteObject();
mdc.DeleteDC();
}

void CSizingControlBar::NcPaintGripper(CDC* pDC, CRect rcClient)
{
UNUSED_ALWAYS(pDC);
UNUSED_ALWAYS(rcClient);
}

void CSizingControlBar::OnPaint()
{
// overridden to skip border painting based on clientrect
CPaintDC dc(this);
}

UINT CSizingControlBar::OnNcHitTest(CPoint point)
{
CRect rcBar, rcEdge;
GetWindowRect(rcBar);

if (!IsFloating())
for (int i = 0; i < 4; i++)
if (GetEdgeRect(rcBar, GetEdgeHTCode(i), rcEdge))
if (rcEdge.PtInRect(point))
return GetEdgeHTCode(i);

return HTCLIENT;
}

void CSizingControlBar::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
{
baseCSizingControlBar::OnSettingChange(uFlags, lpszSection);

m_bDragShowContent = FALSE;
::SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0,
&m_bDragShowContent, 0); // update
}

void CSizingControlBar::OnSize(UINT nType, int cx, int cy)
{
UNUSED_ALWAYS(nType);

if ((m_dwSCBStyle & SCBS_SIZECHILD) != 0)
{
// automatic child resizing - only one child is allowed
CWnd* pWnd = GetWindow(GW_CHILD);
if (pWnd != NULL)
{
pWnd->MoveWindow(0, 0, cx, cy);
ASSERT(pWnd->GetWindow(GW_HWNDNEXT) == NULL);
}
}
}

void CSizingControlBar::OnClose()
{
// do nothing: protection against accidentally destruction by the
// child control (i.e. if user hits Esc in a child editctrl)
}

/////////////////////////////////////////////////////////////////////////
// CSizingControlBar implementation helpers

void CSizingControlBar::StartTracking(UINT nHitTest, CPoint point)
{
SetCapture();

// make sure no updates are pending
if (!m_bDragShowContent)
RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW);

m_htEdge = nHitTest;
m_bTracking = TRUE;

BOOL bHorz = IsHorzDocked();
BOOL bHorzTracking = m_htEdge == HTLEFT || m_htEdge == HTRIGHT;

m_nTrackPosOld = bHorzTracking ? point.x : point.y;

CRect rcBar, rcEdge;
GetWindowRect(rcBar);
GetEdgeRect(rcBar, m_htEdge, rcEdge);
m_nTrackEdgeOfs = m_nTrackPosOld -
(bHorzTracking ? rcEdge.CenterPoint().x : rcEdge.CenterPoint().y);

CSCBArray arrSCBars;
int nThis;
GetRowSizingBars(arrSCBars, nThis);

m_nTrackPosMin = m_nTrackPosMax = m_nTrackPosOld;
if (!IsSideTracking())
{
// calc minwidth as the max minwidth of the sizing bars on row
int nMinWidth = bHorz ? m_szMinHorz.cy : m_szMinVert.cx;
for (int i = 0; i < arrSCBars.GetSize(); i++)
nMinWidth = max(nMinWidth, bHorz ?
arrSCBars[i]->m_szMinHorz.cy :
arrSCBars[i]->m_szMinVert.cx);
int nExcessWidth = (bHorz ? m_szHorz.cy : m_szVert.cx) - nMinWidth;

// the control bar cannot grow with more than the width of
// remaining client area of the mainframe
CRect rcT;
m_pDockSite->RepositionBars(0, 0xFFFF, AFX_IDW_PANE_FIRST,
reposQuery, &rcT, NULL, TRUE);
int nMaxWidth = bHorz ? rcT.Height() - 2 : rcT.Width() - 2;

BOOL bTopOrLeft = m_htEdge == HTTOP || m_htEdge == HTLEFT;

m_nTrackPosMin -= bTopOrLeft ? nMaxWidth : nExcessWidth;
m_nTrackPosMax += bTopOrLeft ? nExcessWidth : nMaxWidth;
}
else
{
// side tracking:
// max size is the actual size plus the amount the other
// sizing bars can be decreased until they reach their minsize
if (m_htEdge == HTBOTTOM || m_htEdge == HTRIGHT)
nThis++;

for (int i = 0; i < arrSCBars.GetSize(); i++)
{
CSizingControlBar* pBar = arrSCBars[i];

int nExcessWidth = bHorz ?
pBar->m_szHorz.cx - pBar->m_szMinHorz.cx :
pBar->m_szVert.cy - pBar->m_szMinVert.cy;

if (i < nThis)
m_nTrackPosMin -= nExcessWidth;
else
m_nTrackPosMax += nExcessWidth;
}
}

OnTrackInvertTracker(); // draw tracker
}

void CSizingControlBar::StopTracking()
{
OnTrackInvertTracker(); // erase tracker

m_bTracking = FALSE;
ReleaseCapture();

m_pDockSite->DelayRecalcLayout();
}

void CSizingControlBar::OnTrackUpdateSize(CPoint& point)
{
ASSERT(!IsFloating());

BOOL bHorzTrack = m_htEdge == HTLEFT || m_htEdge == HTRIGHT;

int nTrackPos = bHorzTrack ? point.x : point.y;
nTrackPos = max(m_nTrackPosMin, min(m_nTrackPosMax, nTrackPos));

int nDelta = nTrackPos - m_nTrackPosOld;

if (nDelta == 0)
return; // no pos change

OnTrackInvertTracker(); // erase tracker

m_nTrackPosOld = nTrackPos;

BOOL bHorz = IsHorzDocked();

CSize sizeNew = bHorz ? m_szHorz : m_szVert;
switch (m_htEdge)
{
case HTLEFT: sizeNew -= CSize(nDelta, 0); break;
case HTTOP: sizeNew -= CSize(0, nDelta); break;
case HTRIGHT: sizeNew += CSize(nDelta, 0); break;
case HTBOTTOM: sizeNew += CSize(0, nDelta); break;
}

CSCBArray arrSCBars;
int nThis;
GetRowSizingBars(arrSCBars, nThis);

if (!IsSideTracking())
for (int i = 0; i < arrSCBars.GetSize(); i++)
{
CSizingControlBar* pBar = arrSCBars[i];
// make same width (or height)
(bHorz ? pBar->m_szHorz.cy : pBar->m_szVert.cx) =
bHorz ? sizeNew.cy : sizeNew.cx;
}
else
{
int nGrowingBar = nThis;
BOOL bBefore = m_htEdge == HTTOP || m_htEdge == HTLEFT;
if (bBefore && nDelta > 0)
nGrowingBar--;
if (!bBefore && nDelta < 0)
nGrowingBar++;
if (nGrowingBar != nThis)
bBefore = !bBefore;

// nGrowing is growing
nDelta = abs(nDelta);
CSizingControlBar* pBar = arrSCBars[nGrowingBar];
(bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy) += nDelta;

// the others are shrinking
int nFirst = bBefore ? nGrowingBar - 1 : nGrowingBar + 1;
int nLimit = bBefore ? -1 : arrSCBars.GetSize();

for (int i = nFirst; nDelta != 0 && i != nLimit; i += (bBefore ? -1 : 1))
{
CSizingControlBar* pBar = arrSCBars[i];

int nDeltaT = min(nDelta,
(bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy) -
(bHorz ? pBar->m_szMinHorz.cx : pBar->m_szMinVert.cy));

(bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy) -= nDeltaT;
nDelta -= nDeltaT;
}
}

OnTrackInvertTracker(); // redraw tracker at new pos

if (m_bDragShowContent)
m_pDockSite->DelayRecalcLayout();
}

void CSizingControlBar::OnTrackInvertTracker()
{
ASSERT(m_bTracking);

if (m_bDragShowContent)
return; // don‘t show tracker if DragFullWindows is on

BOOL bHorz = IsHorzDocked();
CRect rc, rcBar, rcDock, rcFrame;
GetWindowRect(rcBar);
m_pDockBar->GetWindowRect(rcDock);
m_pDockSite->GetWindowRect(rcFrame);
VERIFY(GetEdgeRect(rcBar, m_htEdge, rc));
if (!IsSideTracking())
rc = bHorz ?
CRect(rcDock.left + 1, rc.top, rcDock.right - 1, rc.bottom) :
CRect(rc.left, rcDock.top + 1, rc.right, rcDock.bottom - 1);

BOOL bHorzTracking = m_htEdge == HTLEFT || m_htEdge == HTRIGHT;
int nOfs = m_nTrackPosOld - m_nTrackEdgeOfs;
nOfs -= bHorzTracking ? rc.CenterPoint().x : rc.CenterPoint().y;
rc.OffsetRect(bHorzTracking ? nOfs : 0, bHorzTracking ? 0 : nOfs);
rc.OffsetRect(-rcFrame.TopLeft());

CDC *pDC = m_pDockSite->GetDCEx(NULL,
DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE);
CBrush* pBrush = CDC::GetHalftoneBrush();
CBrush* pBrushOld = pDC->SelectObject(pBrush);

pDC->PatBlt(rc.left, rc.top, rc.Width(), rc.Height(), PATINVERT);

pDC->SelectObject(pBrushOld);
m_pDockSite->ReleaseDC(pDC);
}

BOOL CSizingControlBar::GetEdgeRect(CRect rcWnd, UINT nHitTest,
CRect& rcEdge)
{
rcEdge = rcWnd;
if (m_dwSCBStyle & SCBS_SHOWEDGES)
rcEdge.DeflateRect(1, 1);
BOOL bHorz = IsHorzDocked();

switch (nHitTest)
{
case HTLEFT:
if (!(m_dwSCBStyle & SCBS_EDGELEFT)) return FALSE;
rcEdge.right = rcEdge.left + m_cxEdge;
rcEdge.DeflateRect(0, bHorz ? m_cxEdge: 0);
break;
case HTTOP:
if (!(m_dwSCBStyle & SCBS_EDGETOP)) return FALSE;
rcEdge.bottom = rcEdge.top + m_cxEdge;
rcEdge.DeflateRect(bHorz ? 0 : m_cxEdge, 0);
break;
case HTRIGHT:
if (!(m_dwSCBStyle & SCBS_EDGERIGHT)) return FALSE;
rcEdge.left = rcEdge.right - m_cxEdge;
rcEdge.DeflateRect(0, bHorz ? m_cxEdge: 0);
break;
case HTBOTTOM:
if (!(m_dwSCBStyle & SCBS_EDGEBOTTOM)) return FALSE;
rcEdge.top = rcEdge.bottom - m_cxEdge;
rcEdge.DeflateRect(bHorz ? 0 : m_cxEdge, 0);
break;
default:
ASSERT(FALSE); // invalid hit test code
}
return TRUE;
}

UINT CSizingControlBar::GetEdgeHTCode(int nEdge)
{
if (nEdge == 0) return HTLEFT;
if (nEdge == 1) return HTTOP;
if (nEdge == 2) return HTRIGHT;
if (nEdge == 3) return HTBOTTOM;
ASSERT(FALSE); // invalid edge code
return HTNOWHERE;
}

void CSizingControlBar::GetRowInfo(int& nFirst, int& nLast, int& nThis)
{
ASSERT_VALID(m_pDockBar); // verify bounds

nThis = m_pDockBar->FindBar(this);
ASSERT(nThis != -1);

int i, nBars = m_pDockBar->m_arrBars.GetSize();

// find the first and the last bar in row
for (nFirst = -1, i = nThis - 1; i >= 0 && nFirst == -1; i--)
if (m_pDockBar->m_arrBars[i] == NULL)
nFirst = i + 1;
for (nLast = -1, i = nThis + 1; i < nBars && nLast == -1; i++)
if (m_pDockBar->m_arrBars[i] == NULL)
nLast = i - 1;

ASSERT((nLast != -1) && (nFirst != -1));
}

void CSizingControlBar::GetRowSizingBars(CSCBArray& arrSCBars)
{
int nThis; // dummy
GetRowSizingBars(arrSCBars, nThis);
}

void CSizingControlBar::GetRowSizingBars(CSCBArray& arrSCBars, int& nThis)
{
arrSCBars.RemoveAll();

int nFirstT, nLastT, nThisT;
GetRowInfo(nFirstT, nLastT, nThisT);

nThis = -1;
for (int i = nFirstT; i <= nLastT; i++)
{
CSizingControlBar* pBar =
(CSizingControlBar*) m_pDockBar->m_arrBars[i];
if (HIWORD(pBar) == 0) continue; // placeholder
if (!pBar->IsVisible()) continue;
if (pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
{
if (pBar == this)
nThis = arrSCBars.GetSize();

arrSCBars.Add(pBar);
}
}
}

BOOL CSizingControlBar::NegotiateSpace(int nLengthTotal, BOOL bHorz)
{
ASSERT(bHorz == IsHorzDocked());

int nFirst, nLast, nThis;
GetRowInfo(nFirst, nLast, nThis);

int nLengthAvail = nLengthTotal;
int nLengthActual = 0;
int nLengthMin = 2;
int nWidthMax = 0;
CSizingControlBar* pBar;

for (int i = nFirst; i <= nLast; i++)
{
pBar = (CSizingControlBar*) m_pDockBar->m_arrBars[i];
if (HIWORD(pBar) == 0) continue; // placeholder
if (!pBar->IsVisible()) continue;
BOOL bIsSizingBar =
pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar));

int nLengthBar; // minimum length of the bar
if (bIsSizingBar)
nLengthBar = bHorz ? pBar->m_szMinHorz.cx - 2 :
pBar->m_szMinVert.cy - 2;
else
{
CRect rcBar;
pBar->GetWindowRect(&rcBar);
nLengthBar = bHorz ? rcBar.Width() - 2 : rcBar.Height() - 2;
}

nLengthMin += nLengthBar;
if (nLengthMin > nLengthTotal)
{
// split the row after fixed bar
if (i < nThis)
{
m_pDockBar->m_arrBars.InsertAt(i + 1,
(CControlBar*) NULL);
return FALSE;
}

// only this sizebar remains on the row, adjust it to minsize
if (i == nThis)
{
if (bHorz)
m_szHorz.cx = m_szMinHorz.cx;
else
m_szVert.cy = m_szMinVert.cy;

return TRUE; // the dockbar will split the row for us
}

// we have enough bars - go negotiate with them
m_pDockBar->m_arrBars.InsertAt(i, (CControlBar*) NULL);
nLast = i - 1;
break;
}

if (bIsSizingBar)
{
nLengthActual += bHorz ? pBar->m_szHorz.cx - 2 :
pBar->m_szVert.cy - 2;
nWidthMax = max(nWidthMax, bHorz ? pBar->m_szHorz.cy :
pBar->m_szVert.cx);
}
else
nLengthAvail -= nLengthBar;
}

CSCBArray arrSCBars;
GetRowSizingBars(arrSCBars);
int nNumBars = arrSCBars.GetSize();
int nDelta = nLengthAvail - nLengthActual;

// return faster when there is only one sizing bar per row (this one)
if (nNumBars == 1)
{
ASSERT(arrSCBars[0] == this);

if (nDelta == 0)
return TRUE;

m_bKeepSize = FALSE;
(bHorz ? m_szHorz.cx : m_szVert.cy) += nDelta;

return TRUE;
}

// make all the bars the same width
for (i = 0; i < nNumBars; i++)
if (bHorz)
arrSCBars[i]->m_szHorz.cy = nWidthMax;
else
arrSCBars[i]->m_szVert.cx = nWidthMax;

// distribute the difference between the bars,
// but don‘t shrink them below their minsizes
while (nDelta != 0)
{
int nDeltaOld = nDelta;
for (i = 0; i < nNumBars; i++)
{
pBar = arrSCBars[i];
int nLMin = bHorz ?
pBar->m_szMinHorz.cx : pBar->m_szMinVert.cy;
int nL = bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy;

if ((nL == nLMin) && (nDelta < 0) || // already at min length
pBar->m_bKeepSize) // or wants to keep its size
continue;

// sign of nDelta
int nDelta2 = (nDelta == 0) ? 0 : ((nDelta < 0) ? -1 : 1);

(bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy) += nDelta2;
nDelta -= nDelta2;
if (nDelta == 0) break;
}
// clear m_bKeepSize flags
if ((nDeltaOld == nDelta) || (nDelta == 0))
for (i = 0; i < nNumBars; i++)
arrSCBars[i]->m_bKeepSize = FALSE;
}

return TRUE;
}

void CSizingControlBar::AlignControlBars()
{
int nFirst, nLast, nThis;
GetRowInfo(nFirst, nLast, nThis);

BOOL bHorz = IsHorzDocked();
BOOL bNeedRecalc = FALSE;
int nAlign = bHorz ? -2 : 0;

CRect rc, rcDock;
m_pDockBar->GetWindowRect(&rcDock);

for (int i = nFirst; i <= nLast; i++)
{
CSizingControlBar* pBar =
(CSizingControlBar*) m_pDockBar->m_arrBars[i];
if (HIWORD(pBar) == 0) continue; // placeholder
if (!pBar->IsVisible()) continue;

pBar->GetWindowRect(&rc);
rc.OffsetRect(-rcDock.TopLeft());

if (pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
rc = CRect(rc.TopLeft(),
bHorz ? pBar->m_szHorz : pBar->m_szVert);

if ((bHorz ? rc.left : rc.top) != nAlign)
{
if (!bHorz)
rc.OffsetRect(0, nAlign - rc.top - 2);
else if (m_nDockBarID == AFX_IDW_DOCKBAR_TOP)
rc.OffsetRect(nAlign - rc.left, -2);
else
rc.OffsetRect(nAlign - rc.left, 0);
pBar->MoveWindow(rc);
bNeedRecalc = TRUE;
}
nAlign += (bHorz ? rc.Width() : rc.Height()) - 2;
}

if (bNeedRecalc)
m_pDockSite->DelayRecalcLayout();
}

void CSizingControlBar::OnUpdateCmdUI(CFrameWnd* pTarget,
BOOL bDisableIfNoHndler)
{
UNUSED_ALWAYS(bDisableIfNoHndler);
UNUSED_ALWAYS(pTarget);
}

void CSizingControlBar::LoadState(LPCTSTR lpszProfileName)
{
ASSERT_VALID(this);
ASSERT(GetSafeHwnd()); // must be called after Create()

#if defined(_SCB_REPLACE_MINIFRAME) && !defined(_SCB_MINIFRAME_CAPTION)
// compensate the caption miscalculation in CFrameWnd::SetDockState()
CDockState state;
state.LoadState(lpszProfileName);

UINT nID = GetDlgCtrlID();
for (int i = 0; i < state.m_arrBarInfo.GetSize(); i++)
{
CControlBarInfo* pInfo = (CControlBarInfo*)state.m_arrBarInfo[i];
ASSERT(pInfo != NULL);
if (!pInfo->m_bFloating)
continue;

// this is a floating dockbar - check the ID array
for (int j = 0; j < pInfo->m_arrBarID.GetSize(); j++)
if ((DWORD) pInfo->m_arrBarID[j] == nID)
{
// found this bar - offset origin and save settings
pInfo->m_pointPos.x++;
pInfo->m_pointPos.y +=
::GetSystemMetrics(SM_CYSMCAPTION) + 1;
pInfo->SaveState(lpszProfileName, i);
}
}
#endif //_SCB_REPLACE_MINIFRAME && !_SCB_MINIFRAME_CAPTION

CWinApp* pApp = AfxGetApp();

TCHAR szSection[256];
wsprintf(szSection, _T("%s-SCBar-%d"), lpszProfileName,
GetDlgCtrlID());

m_szHorz.cx = max(m_szMinHorz.cx, (int) pApp->GetProfileInt(
szSection, _T("sizeHorzCX"), m_szHorz.cx));
m_szHorz.cy = max(m_szMinHorz.cy, (int) pApp->GetProfileInt(
szSection, _T("sizeHorzCY"), m_szHorz.cy));

m_szVert.cx = max(m_szMinVert.cx, (int) pApp->GetProfileInt(
szSection, _T("sizeVertCX"), m_szVert.cx));
m_szVert.cy = max(m_szMinVert.cy, (int) pApp->GetProfileInt(
szSection, _T("sizeVertCY"), m_szVert.cy));

m_szFloat.cx = max(m_szMinFloat.cx, (int) pApp->GetProfileInt(
szSection, _T("sizeFloatCX"), m_szFloat.cx));
m_szFloat.cy = max(m_szMinFloat.cy, (int) pApp->GetProfileInt(
szSection, _T("sizeFloatCY"), m_szFloat.cy));
}

void CSizingControlBar::SaveState(LPCTSTR lpszProfileName)
{
// place your SaveState or GlobalSaveState call in
// CMainFrame‘s OnClose() or DestroyWindow(), not in OnDestroy()
ASSERT_VALID(this);
ASSERT(GetSafeHwnd());

CWinApp* pApp = AfxGetApp();

TCHAR szSection[256];
wsprintf(szSection, _T("%s-SCBar-%d"), lpszProfileName,
GetDlgCtrlID());

pApp->WriteProfileInt(szSection, _T("sizeHorzCX"), m_szHorz.cx);
pApp->WriteProfileInt(szSection, _T("sizeHorzCY"), m_szHorz.cy);

pApp->WriteProfileInt(szSection, _T("sizeVertCX"), m_szVert.cx);
pApp->WriteProfileInt(szSection, _T("sizeVertCY"), m_szVert.cy);

pApp->WriteProfileInt(szSection, _T("sizeFloatCX"), m_szFloat.cx);
pApp->WriteProfileInt(szSection, _T("sizeFloatCY"), m_szFloat.cy);
}

void CSizingControlBar::GlobalLoadState(CFrameWnd* pFrame,
LPCTSTR lpszProfileName)
{
POSITION pos = pFrame->m_listControlBars.GetHeadPosition();
while (pos != NULL)
{
CSizingControlBar* pBar =
(CSizingControlBar*) pFrame->m_listControlBars.GetNext(pos);
ASSERT(pBar != NULL);
if (pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
pBar->LoadState(lpszProfileName);
}
}

void CSizingControlBar::GlobalSaveState(CFrameWnd* pFrame,
LPCTSTR lpszProfileName)
{
POSITION pos = pFrame->m_listControlBars.GetHeadPosition();
while (pos != NULL)
{
CSizingControlBar* pBar =
(CSizingControlBar*) pFrame->m_listControlBars.GetNext(pos);
ASSERT(pBar != NULL);
if (pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
pBar->SaveState(lpszProfileName);
}
}

#ifdef _SCB_REPLACE_MINIFRAME
#ifndef _SCB_MINIFRAME_CAPTION
/////////////////////////////////////////////////////////////////////////////
// CSCBDockContext Drag Operations

static void AdjustRectangle(CRect& rect, CPoint pt)
{
int nXOffset = (pt.x < rect.left) ? (pt.x - rect.left) :
(pt.x > rect.right) ? (pt.x - rect.right) : 0;
int nYOffset = (pt.y < rect.top) ? (pt.y - rect.top) :
(pt.y > rect.bottom) ? (pt.y - rect.bottom) : 0;
rect.OffsetRect(nXOffset, nYOffset);
}

void CSCBDockContext::StartDrag(CPoint pt)
{
ASSERT_VALID(m_pBar);
m_bDragging = TRUE;

InitLoop();

ASSERT((m_pBar->m_dwStyle & CBRS_SIZE_DYNAMIC) != 0);

// get true bar size (including borders)
CRect rect;
m_pBar->GetWindowRect(rect);
m_ptLast = pt;
CSize sizeHorz = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_HORZDOCK);
CSize sizeVert = m_pBar->CalcDynamicLayout(0, LM_VERTDOCK);
CSize sizeFloat = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_MRUWIDTH);

m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz);
m_rectDragVert = CRect(rect.TopLeft(), sizeVert);

// calculate frame dragging rectangle
m_rectFrameDragHorz = CRect(rect.TopLeft(), sizeFloat);

#ifdef _MAC
CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz,
WS_THICKFRAME, WS_EX_FORCESIZEBOX);
#else
CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz, WS_THICKFRAME);
#endif
m_rectFrameDragHorz.DeflateRect(2, 2);
m_rectFrameDragVert = m_rectFrameDragHorz;

// adjust rectangles so that point is inside
AdjustRectangle(m_rectDragHorz, pt);
AdjustRectangle(m_rectDragVert, pt);
AdjustRectangle(m_rectFrameDragHorz, pt);
AdjustRectangle(m_rectFrameDragVert, pt);

// initialize tracking state and enter tracking loop
m_dwOverDockStyle = CanDock();
Move(pt); // call it here to handle special keys
Track();
}
#endif //_SCB_MINIFRAME_CAPTION

/////////////////////////////////////////////////////////////////////////////
// CSCBMiniDockFrameWnd

IMPLEMENT_DYNCREATE(CSCBMiniDockFrameWnd, baseCSCBMiniDockFrameWnd);

BEGIN_MESSAGE_MAP(CSCBMiniDockFrameWnd, baseCSCBMiniDockFrameWnd)
//{{AFX_MSG_MAP(CSCBMiniDockFrameWnd)
ON_WM_NCLBUTTONDOWN()
ON_WM_GETMINMAXINFO()
ON_WM_WINDOWPOSCHANGING()
ON_WM_SIZE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CSCBMiniDockFrameWnd::Create(CWnd* pParent, DWORD dwBarStyle)
{
// set m_bInRecalcLayout to avoid flashing during creation
// RecalcLayout will be called once something is docked
m_bInRecalcLayout = TRUE;

DWORD dwStyle = WS_POPUP|WS_CAPTION|WS_SYSMENU|MFS_MOVEFRAME|
MFS_4THICKFRAME|MFS_SYNCACTIVE|MFS_BLOCKSYSMENU|
FWS_SNAPTOBARS;

if (dwBarStyle & CBRS_SIZE_DYNAMIC)
dwStyle &= ~MFS_MOVEFRAME;

DWORD dwExStyle = 0;
#ifdef _MAC
if (dwBarStyle & CBRS_SIZE_DYNAMIC)
dwExStyle |= WS_EX_FORCESIZEBOX;
else
dwStyle &= ~(MFS_MOVEFRAME|MFS_4THICKFRAME);
#endif

if (!CMiniFrameWnd::CreateEx(dwExStyle,
NULL, &afxChNil, dwStyle, rectDefault, pParent))
{
m_bInRecalcLayout = FALSE;
return FALSE;
}
dwStyle = dwBarStyle & (CBRS_ALIGN_LEFT|CBRS_ALIGN_RIGHT) ?
CBRS_ALIGN_LEFT : CBRS_ALIGN_TOP;
dwStyle |= dwBarStyle & CBRS_FLOAT_MULTI;
CMenu* pSysMenu = GetSystemMenu(FALSE);
//pSysMenu->DeleteMenu(SC_SIZE, MF_BYCOMMAND);
CString strHide;
if (strHide.LoadString(AFX_IDS_HIDE))
{
pSysMenu->DeleteMenu(SC_CLOSE, MF_BYCOMMAND);
pSysMenu->AppendMenu(MF_STRING|MF_ENABLED, SC_CLOSE, strHide);
}

// must initially create with parent frame as parent
if (!m_wndDockBar.Create(pParent, WS_CHILD | WS_VISIBLE | dwStyle,
AFX_IDW_DOCKBAR_FLOAT))
{
m_bInRecalcLayout = FALSE;
return FALSE;
}

// set parent to CMiniDockFrameWnd
m_wndDockBar.SetParent(this);
m_bInRecalcLayout = FALSE;

return TRUE;
}

void CSCBMiniDockFrameWnd::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
if (nHitTest == HTCAPTION || nHitTest == HTCLOSE)
{
baseCSCBMiniDockFrameWnd::OnNcLButtonDown(nHitTest, point);
return;
}

if (GetSizingControlBar() != NULL)
CMiniFrameWnd::OnNcLButtonDown(nHitTest, point);
else
baseCSCBMiniDockFrameWnd::OnNcLButtonDown(nHitTest, point);
}

CSizingControlBar* CSCBMiniDockFrameWnd::GetSizingControlBar()
{
CWnd* pWnd = GetWindow(GW_CHILD); // get the dockbar
if (pWnd == NULL)
return NULL;

pWnd = pWnd->GetWindow(GW_CHILD); // get the controlbar
if (pWnd == NULL)
return NULL;

if (!pWnd->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
return NULL;

return (CSizingControlBar*) pWnd;
}

void CSCBMiniDockFrameWnd::OnSize(UINT nType, int cx, int cy)
{
CSizingControlBar* pBar = GetSizingControlBar();
if ((pBar != NULL) && (GetStyle() & MFS_4THICKFRAME) == 0
&& pBar->IsVisible())
pBar->m_szFloat = CSize(cx + 4, cy + 4);

baseCSCBMiniDockFrameWnd::OnSize(nType, cx, cy);
}

void CSCBMiniDockFrameWnd::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
{
baseCSCBMiniDockFrameWnd::OnGetMinMaxInfo(lpMMI);

CSizingControlBar* pBar = GetSizingControlBar();
if (pBar != NULL)
{
CRect r(CPoint(0, 0), pBar->m_szMinFloat - CSize(4, 4));
#ifndef _SCB_MINIFRAME_CAPTION
CMiniFrameWnd::CalcBorders(&r, WS_THICKFRAME);
#else
CMiniFrameWnd::CalcBorders(&r, WS_THICKFRAME|WS_CAPTION);
#endif //_SCB_MINIFRAME_CAPTION
lpMMI->ptMinTrackSize.x = r.Width();
lpMMI->ptMinTrackSize.y = r.Height();
}
}

void CSCBMiniDockFrameWnd::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
{
if ((GetStyle() & MFS_4THICKFRAME) != 0)
{
CSizingControlBar* pBar = GetSizingControlBar();
if (pBar != NULL)
{
lpwndpos->flags |= SWP_NOSIZE; // don‘t size this time
// prevents flicker
pBar->m_pDockBar->ModifyStyle(0, WS_CLIPCHILDREN);
// enable diagonal resizing
ModifyStyle(MFS_4THICKFRAME, 0);
#ifndef _SCB_MINIFRAME_CAPTION
// remove caption
ModifyStyle(WS_SYSMENU|WS_CAPTION, 0);
#endif
DelayRecalcLayout();
pBar->PostMessage(WM_NCPAINT);
}
}

CMiniFrameWnd::OnWindowPosChanging(lpwndpos);
}

#endif //_SCB_REPLACE_MINIFRAME

窗口浮动4生1模式