Windows2003-3790/sdktools/trace/traceview/dockdialogbar.cpp
2020-09-30 16:53:55 +02:00

1024 lines
26 KiB
C++

//////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2002 Microsoft Corporation. All rights reserved.
// Copyright (c) 2002 OSR Open Systems Resources, Inc.
//
// DockDialogBar.cpp - implementation of the CDockDialogBar class
//////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DockDialogBar.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDockDialogBar
IMPLEMENT_DYNAMIC(CDockDialogBar, CControlBar);
CDockDialogBar::CDockDialogBar() :
m_clrBtnHilight(::GetSysColor(COLOR_BTNHILIGHT)),
m_clrBtnShadow(::GetSysColor(COLOR_BTNSHADOW))
{
m_sizeMin = CSize(32, 32);
m_sizeHorz = CSize(200, 200);
m_sizeVert = CSize(200, 200);
m_sizeFloat = CSize(200, 200);
m_bTracking = FALSE;
m_bInRecalcNC = FALSE;
m_cxEdge = 6;
m_cxBorder = 3;
m_cxGripper = 15;
m_pDialog = NULL;
m_brushBkgd.CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
m_cyBorder = 3;
m_cCaptionSize = GetSystemMetrics(SM_CYSMCAPTION);
m_cMinWidth = GetSystemMetrics(SM_CXMIN);
m_cMinHeight = GetSystemMetrics(SM_CYMIN);
m_bKeepSize = TRUE;
m_bShowTitleInGripper = FALSE;
}
CDockDialogBar::~CDockDialogBar()
{
}
BEGIN_MESSAGE_MAP(CDockDialogBar, CControlBar)
//{{AFX_MSG_MAP(CDockDialogBar)
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_SETCURSOR()
ON_WM_WINDOWPOSCHANGING()
ON_WM_WINDOWPOSCHANGED()
ON_WM_NCPAINT()
ON_WM_NCLBUTTONDOWN()
ON_WM_NCHITTEST()
ON_WM_NCCALCSIZE()
ON_WM_LBUTTONDOWN()
ON_WM_CAPTURECHANGED()
ON_WM_LBUTTONDBLCLK()
ON_WM_NCLBUTTONDBLCLK()
ON_WM_SIZE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDockDialogBar message handlers
void CDockDialogBar::OnUpdateCmdUI(class CFrameWnd *pTarget, int bDisableIfNoHndler)
{
UpdateDialogControls(pTarget, bDisableIfNoHndler);
}
BOOL CDockDialogBar::Create(CWnd *pParentWnd,
CDialog *pDialog,
CString &pTitle,
UINT nID,
DWORD dwStyle,
BOOL bShowTitleInGripper)
{
ASSERT_VALID(pParentWnd); // must have a parent
ASSERT (!((dwStyle & CBRS_SIZE_FIXED) && (dwStyle & CBRS_SIZE_DYNAMIC)));
//
// save the style
//
m_dwStyle = dwStyle & CBRS_ALL;
//
// Determine whether or not to display the title
// in the gripper bar
//
m_bShowTitleInGripper = bShowTitleInGripper;
//
// Adjust the gripper width if necessary
//
if(m_bShowTitleInGripper) {
m_cxGripper = 25;
}
//
// create the base window
//
CString wndclass = AfxRegisterWndClass(CS_DBLCLKS, LoadCursor(NULL, IDC_ARROW),
m_brushBkgd, 0);
if (!CWnd::Create(wndclass, pTitle, dwStyle, CRect(0,0,0,0),
pParentWnd, 0)) {
return FALSE;
}
m_pTitle = (LPCTSTR)pTitle;
//
// create the child dialog
//
m_pDialog = pDialog;
m_pDialog->Create(nID, this);
//
// use the dialog dimensions as default base dimensions
//
CRect rc;
m_pDialog->GetWindowRect(rc);
m_sizeHorz = m_sizeVert = m_sizeFloat = rc.Size();
m_sizeHorz.cy += m_cxEdge + m_cxBorder;
m_sizeVert.cx += m_cxEdge + m_cxBorder;
return TRUE;
}
CSize CDockDialogBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
{
CRect rc;
LONG availableHeight;
LONG actualHeight;
LONG rowHeight;
LONG diff;
LONG oldDiff;
LONG adjustment;
CString str;
LONG ii;
BOOL bFound;
BOOL bIsMinimum;
CDockBar *pDockBar;
CDockDialogBar *pBar;
CPtrArray barArray;
m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_TOP)->GetWindowRect(rc);
int nHorzDockBarWidth = bStretch ? 32767 : rc.Width() + 4;
m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_LEFT)->GetWindowRect(rc);
int nVertDockBarHeight = bStretch ? 32767 : rc.Height() + 4;
if(IsFloating()) {
return m_sizeFloat;
}
CFrameWnd *pFrame = GetParentFrame();
if(pFrame == NULL) {
if (bHorz)
return CSize(nHorzDockBarWidth, m_sizeHorz.cy);
else
return CSize(m_sizeVert.cx, nVertDockBarHeight);
}
//
// Get the available screen height
//
pFrame->GetClientRect(rc);
ScreenToClient(rc);
//
// Client rect height minus the status bar height
//
availableHeight = rc.Height() - 18;
actualHeight = 0;
pDockBar = (CDockBar *)m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_TOP);
if(pDockBar == NULL) {
if (bHorz)
return CSize(nHorzDockBarWidth, m_sizeHorz.cy);
else
return CSize(m_sizeVert.cx, nVertDockBarHeight);
}
bFound = FALSE;
rowHeight = 0;
//
// Walk the top rows
//
for(ii = 0; ii < pDockBar->m_arrBars.GetSize(); ii++) {
pBar = (CDockDialogBar *)pDockBar->m_arrBars[ii];
if(pBar == NULL) {
if(!bFound) {
availableHeight -= rowHeight;
}
rowHeight = 0;
continue;
}
if(pBar->IsKindOf(RUNTIME_CLASS(CDockDialogBar))) {
if(!bFound && pBar != this) {
if (bHorz)
return CSize(nHorzDockBarWidth, m_sizeHorz.cy);
else
return CSize(m_sizeVert.cx, nVertDockBarHeight);
}
bFound = TRUE;
barArray.Add(pBar);
//
// We position these with one border overlapping
// so subtract one part of a border width from the size
//
actualHeight += (pBar->m_sizeHorz.cy - 2);
continue;
}
pBar->GetWindowRect(rc);
rowHeight = max(rowHeight, rc.Height());
}
pDockBar = (CDockBar *)m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_BOTTOM);
if(pDockBar == NULL) {
if (bHorz)
return CSize(nHorzDockBarWidth, m_sizeHorz.cy);
else
return CSize(m_sizeVert.cx, nVertDockBarHeight);
}
bFound = FALSE;
rowHeight = 0;
//
// Walk the bottom rows
//
for(ii = 0; ii < pDockBar->m_arrBars.GetSize(); ii++) {
pBar = (CDockDialogBar *)pDockBar->m_arrBars[ii];
if(pBar == NULL) {
if(!bFound) {
availableHeight -= rowHeight;
}
rowHeight = 0;
continue;
}
if(pBar->IsKindOf(RUNTIME_CLASS(CDockDialogBar))) {
bFound = TRUE;
barArray.Add(pBar);
//
// We position these with one border overlapping
// so subtract one part of a border width from the size
//
actualHeight += (pBar->m_sizeHorz.cy - 2);
continue;
}
pBar->GetWindowRect(rc);
rowHeight = max(rowHeight, rc.Height());
}
diff = availableHeight - actualHeight;
if(diff == 0) {
if (bHorz)
return CSize(nHorzDockBarWidth, m_sizeHorz.cy);
else
return CSize(m_sizeVert.cx, nVertDockBarHeight);
}
adjustment = (diff > 0) ? 1 : -1;
//
// walk through our array and adjust the heights
//
while(diff != 0) {
oldDiff = diff;
for(ii = 0; ii < barArray.GetSize(); ii++) {
pBar = (CDockDialogBar *)barArray[ii];
if(pBar->m_bKeepSize) {
continue;
}
if((pBar->m_sizeHorz.cy + adjustment) >= pBar->m_sizeMin.cy) {
pBar->m_sizeHorz.cy += adjustment;
diff -= adjustment;
if(diff == 0) {
break;
}
}
}
if(oldDiff == diff) {
bIsMinimum = TRUE;
for(ii = 0; ii < barArray.GetSize(); ii++) {
pBar = (CDockDialogBar *)barArray[ii];
if(pBar->m_bKeepSize == TRUE) {
bIsMinimum = FALSE;
}
pBar->m_bKeepSize = FALSE;
}
if(bIsMinimum) {
break;
}
}
}
for(ii = 0; ii < barArray.GetSize(); ii++) {
pBar = (CDockDialogBar *)barArray[ii];
pBar->m_bKeepSize = FALSE;
}
if (bHorz)
return CSize(nHorzDockBarWidth, m_sizeHorz.cy);
else
return CSize(m_sizeVert.cx, nVertDockBarHeight);
}
CSize CDockDialogBar::CalcDynamicLayout(int nLength, DWORD dwMode)
{
if (IsFloating())
{
//
// Get the frame window for this dock dialog bar
// It better not be the main window
//
CFrameWnd* pFrameWnd = GetParentFrame();
if ( pFrameWnd != AfxGetMainWnd() )
{
//
// Disable the SC_CLOSE Control for floating window
//
EnableMenuItem(::GetSystemMenu(pFrameWnd->m_hWnd, FALSE),
SC_CLOSE,
MF_BYCOMMAND | MF_GRAYED);
}
//
// Enable diagonal arrow cursor for resizing
//
GetParent()->GetParent()->ModifyStyle(0, MFS_4THICKFRAME);
}
if (dwMode & (LM_HORZDOCK | LM_VERTDOCK))
{
SetWindowPos(NULL, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER |
SWP_NOACTIVATE | SWP_FRAMECHANGED);
m_pDockSite->RecalcLayout();
return CControlBar::CalcDynamicLayout(nLength,dwMode);
}
if (dwMode & LM_MRUWIDTH)
return m_sizeFloat;
if (dwMode & LM_COMMIT)
{
m_sizeFloat.cx = nLength;
return m_sizeFloat;
}
if (IsFloating())
{
RECT window_rect;
POINT cursor_pt;
GetCursorPos(&cursor_pt);
GetParent()->GetParent()->GetWindowRect(&window_rect);
switch (m_pDockContext->m_nHitTest)
{
case HTTOPLEFT:
m_sizeFloat.cx = max(window_rect.right - cursor_pt.x,
m_cMinWidth) - m_cxBorder;
m_sizeFloat.cy = max(window_rect.bottom - m_cCaptionSize -
cursor_pt.y,m_cMinHeight) - 1;
m_pDockContext->m_rectFrameDragHorz.top = min(cursor_pt.y,
window_rect.bottom - m_cCaptionSize - m_cMinHeight) -
m_cyBorder;
m_pDockContext->m_rectFrameDragHorz.left = min(cursor_pt.x,
window_rect.right - m_cMinWidth) - 1;
return m_sizeFloat;
case HTTOPRIGHT:
m_sizeFloat.cx = max(cursor_pt.x - window_rect.left,
m_cMinWidth);
m_sizeFloat.cy = max(window_rect.bottom - m_cCaptionSize -
cursor_pt.y,m_cMinHeight) - 1;
m_pDockContext->m_rectFrameDragHorz.top = min(cursor_pt.y,
window_rect.bottom - m_cCaptionSize - m_cMinHeight) -
m_cyBorder;
return m_sizeFloat;
case HTBOTTOMLEFT:
m_sizeFloat.cx = max(window_rect.right - cursor_pt.x,
m_cMinWidth) - m_cxBorder;
m_sizeFloat.cy = max(cursor_pt.y - window_rect.top -
m_cCaptionSize,m_cMinHeight);
m_pDockContext->m_rectFrameDragHorz.left = min(cursor_pt.x,
window_rect.right - m_cMinWidth) - 1;
return m_sizeFloat;
case HTBOTTOMRIGHT:
m_sizeFloat.cx = max(cursor_pt.x - window_rect.left,
m_cMinWidth);
m_sizeFloat.cy = max(cursor_pt.y - window_rect.top -
m_cCaptionSize,m_cMinHeight);
return m_sizeFloat;
}
}
if (dwMode & LM_LENGTHY)
return CSize(m_sizeFloat.cx,
m_sizeFloat.cy = max(m_sizeMin.cy, nLength));
else
return CSize(max(m_sizeMin.cx, nLength), m_sizeFloat.cy);
}
void CDockDialogBar::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
{
CControlBar::OnWindowPosChanging(lpwndpos);
}
void CDockDialogBar::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos)
{
CControlBar::OnWindowPosChanged(lpwndpos);
if(!::IsWindow(m_hWnd) || m_pDialog==NULL)
return;
if(!::IsWindow(m_pDialog->m_hWnd))
return;
if (m_bInRecalcNC)
{
CRect rc;
GetClientRect(rc);
m_pDialog->MoveWindow(rc);
return;
}
//
// Find on which side are we docked
//
UINT nDockBarID = GetParent()->GetDlgCtrlID();
//
// Return if dropped at same location
//
if (nDockBarID == m_nDockBarID // no docking side change
&& (lpwndpos->flags & SWP_NOSIZE) // no size change
&& ((m_dwStyle & CBRS_BORDER_ANY) != CBRS_BORDER_ANY))
return;
m_nDockBarID = nDockBarID;
//
// Force recalc the non-client area
//
m_bInRecalcNC = TRUE;
SetWindowPos(NULL, 0,0,0,0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
m_bInRecalcNC = FALSE;
}
BOOL CDockDialogBar::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if ((nHitTest != HTSIZE) || m_bTracking)
return CControlBar::OnSetCursor(pWnd, nHitTest, message);
if (IsHorz())
SetCursor(LoadCursor(NULL, IDC_SIZENS));
else
SetCursor(LoadCursor(NULL, IDC_SIZEWE));
return TRUE;
}
/////////////////////////////////////////////////////////////////////////
// Mouse Handling
//
void CDockDialogBar::OnLButtonUp(UINT nFlags, CPoint point)
{
if (!m_bTracking)
CControlBar::OnLButtonUp(nFlags, point);
else
{
ClientToWnd(point);
StopTracking(TRUE);
}
}
void CDockDialogBar::OnMouseMove(UINT nFlags, CPoint point)
{
if (IsFloating() || !m_bTracking)
{
CControlBar::OnMouseMove(nFlags, point);
return;
}
CPoint cpt = m_rectTracker.CenterPoint();
ClientToWnd(point);
if (IsHorz())
{
if (cpt.y != point.y)
{
OnInvertTracker(m_rectTracker);
m_rectTracker.OffsetRect(0, point.y - cpt.y);
OnInvertTracker(m_rectTracker);
}
}
else
{
if (cpt.x != point.x)
{
OnInvertTracker(m_rectTracker);
m_rectTracker.OffsetRect(point.x - cpt.x, 0);
OnInvertTracker(m_rectTracker);
}
}
}
void CDockDialogBar::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)
{
//
// Compute the rectangle of the mobile edge
//
GetWindowRect(m_rectBorder);
m_rectBorder = CRect(0, 0, m_rectBorder.Width(), m_rectBorder.Height());
DWORD dwBorderStyle = m_dwStyle | CBRS_BORDER_ANY;
switch(m_nDockBarID)
{
case AFX_IDW_DOCKBAR_TOP:
dwBorderStyle &= ~CBRS_BORDER_BOTTOM;
lpncsp->rgrc[0].left += m_cxGripper;
lpncsp->rgrc[0].bottom += -m_cxEdge;
lpncsp->rgrc[0].top += m_cxBorder;
lpncsp->rgrc[0].right += -m_cxBorder;
m_rectBorder.top = m_rectBorder.bottom - m_cxEdge;
break;
case AFX_IDW_DOCKBAR_BOTTOM:
dwBorderStyle &= ~CBRS_BORDER_TOP;
lpncsp->rgrc[0].left += m_cxGripper;
lpncsp->rgrc[0].top += m_cxEdge;
lpncsp->rgrc[0].bottom += -m_cxBorder;
lpncsp->rgrc[0].right += -m_cxBorder;
m_rectBorder.bottom = m_rectBorder.top + m_cxEdge;
break;
case AFX_IDW_DOCKBAR_LEFT:
dwBorderStyle &= ~CBRS_BORDER_RIGHT;
lpncsp->rgrc[0].right += -m_cxEdge;
lpncsp->rgrc[0].left += m_cxBorder;
lpncsp->rgrc[0].bottom += -m_cxBorder;
lpncsp->rgrc[0].top += m_cxGripper;
m_rectBorder.left = m_rectBorder.right - m_cxEdge;
break;
case AFX_IDW_DOCKBAR_RIGHT:
dwBorderStyle &= ~CBRS_BORDER_LEFT;
lpncsp->rgrc[0].left += m_cxEdge;
lpncsp->rgrc[0].right += -m_cxBorder;
lpncsp->rgrc[0].bottom += -m_cxBorder;
lpncsp->rgrc[0].top += m_cxGripper;
m_rectBorder.right = m_rectBorder.left + m_cxEdge;
break;
default:
m_rectBorder.SetRectEmpty();
break;
}
SetBarStyle(dwBorderStyle);
}
void CDockDialogBar::OnNcPaint()
{
EraseNonClient();
CWindowDC dc(this);
dc.Draw3dRect(m_rectBorder, GetSysColor(COLOR_BTNHIGHLIGHT),
GetSysColor(COLOR_BTNSHADOW));
DrawGripper(dc);
CRect pRect;
GetClientRect( &pRect );
InvalidateRect( &pRect, TRUE );
}
void CDockDialogBar::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
if (m_bTracking) return;
if((nHitTest == HTSYSMENU) && !IsFloating())
GetDockingFrame()->ShowControlBar(this, FALSE, FALSE);
else if ((nHitTest == HTMINBUTTON) && !IsFloating())
m_pDockContext->ToggleDocking();
else if ((nHitTest == HTCAPTION) && !IsFloating() && (m_pDockBar != NULL))
{
// start the drag
ASSERT(m_pDockContext != NULL);
m_pDockContext->StartDrag(point);
}
else if ((nHitTest == HTSIZE) && !IsFloating()) {
m_bKeepSize = TRUE;
StartTracking();
} else {
CControlBar::OnNcLButtonDown(nHitTest, point);
}
}
UINT CDockDialogBar::OnNcHitTest(CPoint point)
{
if (IsFloating())
return CControlBar::OnNcHitTest(point);
CRect rc;
GetWindowRect(rc);
point.Offset(-rc.left, -rc.top);
if(m_rectClose.PtInRect(point))
return HTSYSMENU;
else if (m_rectUndock.PtInRect(point))
return HTMINBUTTON;
else if (m_rectGripper.PtInRect(point))
return HTCAPTION;
else if (m_rectBorder.PtInRect(point))
return HTSIZE;
else
return CControlBar::OnNcHitTest(point);
}
void CDockDialogBar::OnLButtonDown(UINT nFlags, CPoint point)
{
//
// only start dragging if clicked in "void" space
//
if (m_pDockBar != NULL)
{
//
// start the drag
//
ASSERT(m_pDockContext != NULL);
ClientToScreen(&point);
m_pDockContext->StartDrag(point);
}
else
{
CWnd::OnLButtonDown(nFlags, point);
}
}
void CDockDialogBar::OnLButtonDblClk(UINT nFlags, CPoint point)
{
//
// only toggle docking if clicked in "void" space
//
if (m_pDockBar != NULL)
{
//
// toggle docking
//
ASSERT(m_pDockContext != NULL);
m_pDockContext->ToggleDocking();
}
else
{
CWnd::OnLButtonDblClk(nFlags, point);
}
}
void CDockDialogBar::StartTracking()
{
SetCapture();
//
// make sure no updates are pending
//
RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW);
m_pDockSite->LockWindowUpdate();
m_ptOld = m_rectBorder.CenterPoint();
m_bTracking = TRUE;
m_rectTracker = m_rectBorder;
if (!IsHorz()) m_rectTracker.bottom -= 4;
OnInvertTracker(m_rectTracker);
}
void CDockDialogBar::OnCaptureChanged(CWnd *pWnd)
{
if (m_bTracking && pWnd != this)
//
// cancel tracking
//
StopTracking(FALSE);
CControlBar::OnCaptureChanged(pWnd);
}
void CDockDialogBar::StopTracking(BOOL bAccept)
{
CDockDialogBar *pBar;
CDockBar *pDockBar;
LONG beforeIndex;
LONG afterIndex;
LONG ii;
BOOL bFound = FALSE;
OnInvertTracker(m_rectTracker);
m_pDockSite->UnlockWindowUpdate();
m_bTracking = FALSE;
ReleaseCapture();
if (!bAccept) return;
int maxsize, minsize, newsize;
CRect rcc;
m_pDockSite->GetWindowRect(rcc);
newsize = IsHorz() ? m_sizeHorz.cy : m_sizeVert.cx;
maxsize = newsize + (IsHorz() ? rcc.Height() : rcc.Width());
minsize = IsHorz() ? m_sizeMin.cy : m_sizeMin.cx;
CPoint point = m_rectTracker.CenterPoint();
switch (m_nDockBarID)
{
case AFX_IDW_DOCKBAR_TOP:
newsize += point.y - m_ptOld.y; break;
case AFX_IDW_DOCKBAR_BOTTOM:
newsize += -point.y + m_ptOld.y; break;
case AFX_IDW_DOCKBAR_LEFT:
newsize += point.x - m_ptOld.x; break;
case AFX_IDW_DOCKBAR_RIGHT:
newsize += -point.x + m_ptOld.x; break;
}
pDockBar = (CDockBar *)m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_TOP);
//
// Mark all bars to keep their size
//
for(ii = 0; ii < pDockBar->m_arrBars.GetSize(); ii++) {
pBar = (CDockDialogBar *)pDockBar->m_arrBars[ii];
if(pBar == NULL) {
continue;
}
if(pBar->IsKindOf(RUNTIME_CLASS(CDockDialogBar))) {
//
// Mark all bars to keep their size for now
//
pBar->m_bKeepSize = TRUE;
}
}
//
// Have all windows keep there size except those directly next
// to the window changing size if possible. Normally only the
// window below, or after, the window changing size will need
// to change size as well, unless the user attempted to resize
// the window to smaller than its minimum. Then both the window
// above and below will need to change size.
//
for(ii = 0; ii < pDockBar->m_arrBars.GetSize(); ii++) {
pBar = (CDockDialogBar *)pDockBar->m_arrBars[ii];
if(pBar == NULL) {
continue;
}
if(pBar->IsKindOf(RUNTIME_CLASS(CDockDialogBar))) {
//
// Mark all bars to keep their size for now
//
pBar->m_bKeepSize = TRUE;
if(pBar == this) {
bFound = TRUE;
continue;
}
if(bFound) {
afterIndex = ii;
break;
}
if(!bFound) {
beforeIndex = ii;
}
}
}
//
// The window below, or after the one being modified will
// alway need to change size
//
pBar = (CDockDialogBar *)pDockBar->m_arrBars[afterIndex];
pBar->m_bKeepSize = FALSE;
//
// If the modified window is being shrunk past its minimum
// then the window above, or before this one needs to change
// as well
//
if(newsize < minsize) {
pBar = (CDockDialogBar *)pDockBar->m_arrBars[beforeIndex];
pBar->m_bKeepSize = FALSE;
}
newsize = max(minsize, min(maxsize, newsize));
if (IsHorz())
m_sizeHorz.cy = newsize;
else
m_sizeVert.cx = newsize;
m_pDockSite->RecalcLayout();
}
void CDockDialogBar::OnInvertTracker(const CRect& rect)
{
ASSERT_VALID(this);
ASSERT(!rect.IsRectEmpty());
ASSERT(m_bTracking);
CRect rct = rect, rcc, rcf;
GetWindowRect(rcc);
m_pDockSite->GetWindowRect(rcf);
rct.OffsetRect(rcc.left - rcf.left, rcc.top - rcf.top);
rct.DeflateRect(1, 1);
CDC *pDC = m_pDockSite->GetDCEx(NULL,
DCX_WINDOW|DCX_CACHE|DCX_LOCKWINDOWUPDATE);
CBrush* pBrush = CDC::GetHalftoneBrush();
HBRUSH hOldBrush = NULL;
if (pBrush != NULL)
hOldBrush = (HBRUSH)SelectObject(pDC->m_hDC, pBrush->m_hObject);
pDC->PatBlt(rct.left, rct.top, rct.Width(), rct.Height(), PATINVERT);
if (hOldBrush != NULL)
SelectObject(pDC->m_hDC, hOldBrush);
m_pDockSite->ReleaseDC(pDC);
}
BOOL CDockDialogBar::IsHorz() const
{
return (m_nDockBarID == AFX_IDW_DOCKBAR_TOP ||
m_nDockBarID == AFX_IDW_DOCKBAR_BOTTOM);
}
CPoint& CDockDialogBar::ClientToWnd(CPoint& point)
{
if (m_nDockBarID == AFX_IDW_DOCKBAR_BOTTOM)
point.y += m_cxEdge;
else if (m_nDockBarID == AFX_IDW_DOCKBAR_RIGHT)
point.x += m_cxEdge;
return point;
}
void CDockDialogBar::DrawGripper(CDC & dc)
{
CString groupNumber;
//
// no gripper if floating
//
if( m_dwStyle & CBRS_FLOATING ) {
return;
}
m_pDockSite->RecalcLayout();
CRect gripper;
GetWindowRect( gripper );
ScreenToClient( gripper );
gripper.OffsetRect( -gripper.left, -gripper.top );
if( m_dwStyle & CBRS_ORIENT_HORZ ) {
//
// gripper at left
//
m_rectGripper.top = gripper.top;
m_rectGripper.bottom = gripper.bottom;
m_rectGripper.left = gripper.left;
m_rectGripper.right = gripper.left + 15;
gripper.top += 10;
gripper.bottom -= 10;
gripper.left += 5;
gripper.right = gripper.left + 3;
//
// Draw first bar
//
dc.Draw3dRect(gripper, m_clrBtnHilight, m_clrBtnShadow);
gripper.OffsetRect(4, 0);
//
// Draw second bar
//
dc.Draw3dRect(gripper, m_clrBtnHilight, m_clrBtnShadow);
//
// Display title if requested
//
if(m_bShowTitleInGripper) {
gripper.OffsetRect(8, 0);
gripper.DeflateRect(-4, 0);
dc.SelectStockObject(SYSTEM_FONT);
dc.SetBkColor(GetSysColor(COLOR_BTNFACE));
dc.SetTextColor(GetSysColor(COLOR_3DSHADOW));
//
// Gripper title format -- ID #
//
dc.DrawText('I', gripper, DT_CENTER);
gripper.OffsetRect(0, 8);
gripper.DeflateRect(0, 8);
dc.DrawText('D', gripper, DT_CENTER);
gripper.OffsetRect(0, 8);
gripper.DeflateRect(0, 8);
dc.DrawText(' ', gripper, DT_CENTER);
gripper.OffsetRect(0, 4);
gripper.DeflateRect(0, 4);
groupNumber = m_pTitle.Right(m_pTitle.GetLength() - m_pTitle.ReverseFind(' ') - 1);
for(int ii = 0; ii < groupNumber.GetLength(); ii++) {
dc.DrawText(groupNumber[ii], gripper, DT_CENTER);
gripper.OffsetRect(0, 8);
gripper.DeflateRect(0, 8);
}
}
}
else {
//
// gripper at top
//
m_rectGripper.top = gripper.top;
m_rectGripper.bottom = gripper.top + 20;
m_rectGripper.left = gripper.left;
m_rectGripper.right = gripper.right - 10;
gripper.right -= 38;
gripper.left += 5;
gripper.top += 10;
gripper.bottom = gripper.top + 3;
dc.Draw3dRect( gripper, RGB(0, 255, 0), RGB(0, 255, 255));
gripper.OffsetRect(0, 4);
dc.Draw3dRect( gripper, RGB(255, 255, 0), RGB(255, 0, 0));
}
}
void CDockDialogBar::OnNcLButtonDblClk(UINT nHitTest, CPoint point)
{
if ((m_pDockBar != NULL) && (nHitTest == HTCAPTION))
{
//
// toggle docking
//
ASSERT(m_pDockContext != NULL);
m_pDockContext->ToggleDocking();
}
else
{
CWnd::OnNcLButtonDblClk(nHitTest, point);
}
}