| 1 |
///////////////////////////////////////////////////////////////////////// |
| 2 |
// |
| 3 |
// CSizingControlBar Version 2.44 |
| 4 |
// |
| 5 |
// Created: Jan 24, 1998 Last Modified: March 31, 2002 |
| 6 |
// |
| 7 |
// See the official site at www.datamekanix.com for documentation and |
| 8 |
// the latest news. |
| 9 |
// |
| 10 |
///////////////////////////////////////////////////////////////////////// |
| 11 |
// Copyright (C) 1998-2002 by Cristi Posea. All rights reserved. |
| 12 |
// |
| 13 |
// This code is free for personal and commercial use, providing this |
| 14 |
// notice remains intact in the source files and all eventual changes are |
| 15 |
// clearly marked with comments. |
| 16 |
// |
| 17 |
// You must obtain the author's consent before you can include this code |
| 18 |
// in a software library. |
| 19 |
// |
| 20 |
// No warrantee of any kind, express or implied, is included with this |
| 21 |
// software; use at your own risk, responsibility for damages (if any) to |
| 22 |
// anyone resulting from the use of this software rests entirely with the |
| 23 |
// user. |
| 24 |
// |
| 25 |
// Send bug reports, bug fixes, enhancements, requests, flames, etc. to |
| 26 |
// cristi@datamekanix.com or post them at the message board at the site. |
| 27 |
// |
| 28 |
// The sources and a short version of the docs are also available at |
| 29 |
// www.codeproject.com . Look for a "Docking Windows" section and check |
| 30 |
// the version to be sure you get the latest one ;) |
| 31 |
// |
| 32 |
// Hint: These classes are intended to be used as base classes. Do not |
| 33 |
// simply add your code to these files - instead create a new class |
| 34 |
// derived from one of CSizingControlBarXX classes and put there what |
| 35 |
// you need. See CMyBar classes in the demo projects for examples. |
| 36 |
// Modify this file only to fix bugs, and don't forget to send me a copy. |
| 37 |
///////////////////////////////////////////////////////////////////////// |
| 38 |
// Acknowledgements: |
| 39 |
// o Thanks to Harlan R. Seymour for his continuous support during |
| 40 |
// development of this code. |
| 41 |
// o Thanks to Dundas Software for the opportunity |
| 42 |
// to test this code on real-life applications. |
| 43 |
// o Some ideas for the gripper came from the CToolBarEx flat toolbar |
| 44 |
// by Joerg Koenig. Thanks, Joerg! |
| 45 |
// o Thanks to Robert Wolpow for the code on which CDockContext based |
| 46 |
// dialgonal resizing is based. |
| 47 |
// o Thanks to the following people for various bug fixes and/or |
| 48 |
// enhancements: Chris Maunder, Jakawan Ratiwanich, Udo Schaefer, |
| 49 |
// Anatoly Ivasyuk, Peter Hauptmann, DJ(?), Pat Kusbel, Aleksey |
| 50 |
// Malyshev. |
| 51 |
// o And, of course, many thanks to all of you who used this code, |
| 52 |
// for the invaluable feedback I received. |
| 53 |
///////////////////////////////////////////////////////////////////////// |
| 54 |
|
| 55 |
// sizecbar.cpp : implementation file |
| 56 |
// |
| 57 |
|
| 58 |
#include "stdafx.h" |
| 59 |
#include "sizecbar.h" |
| 60 |
|
| 61 |
#ifdef _DEBUG |
| 62 |
#define new DEBUG_NEW |
| 63 |
#undef THIS_FILE |
| 64 |
static char THIS_FILE[] = __FILE__; |
| 65 |
#endif |
| 66 |
|
| 67 |
///////////////////////////////////////////////////////////////////////// |
| 68 |
// CSizingControlBar |
| 69 |
|
| 70 |
IMPLEMENT_DYNAMIC( CSizingControlBar, baseCSizingControlBar ); |
| 71 |
|
| 72 |
CSizingControlBar::CSizingControlBar() |
| 73 |
{ |
| 74 |
m_szMinHorz = CSize( 33, 32 ); |
| 75 |
m_szMinVert = CSize( 33, 32 ); |
| 76 |
m_szMinFloat = CSize( 37, 32 ); |
| 77 |
m_szHorz = CSize( 200, 200 ); |
| 78 |
m_szVert = CSize( 200, 200 ); |
| 79 |
m_szFloat = CSize( 200, 200 ); |
| 80 |
m_bTracking = FALSE; |
| 81 |
m_bKeepSize = FALSE; |
| 82 |
m_bParentSizing = FALSE; |
| 83 |
m_cxEdge = 5; |
| 84 |
m_bDragShowContent = FALSE; |
| 85 |
m_nDockBarID = 0; |
| 86 |
m_dwSCBStyle = 0; |
| 87 |
} |
| 88 |
|
| 89 |
CSizingControlBar::~CSizingControlBar() |
| 90 |
{} |
| 91 |
|
| 92 |
BEGIN_MESSAGE_MAP( CSizingControlBar, baseCSizingControlBar ) |
| 93 |
//{{AFX_MSG_MAP(CSizingControlBar) |
| 94 |
ON_WM_CREATE() |
| 95 |
ON_WM_PAINT() |
| 96 |
ON_WM_NCPAINT() |
| 97 |
ON_WM_NCCALCSIZE() |
| 98 |
ON_WM_WINDOWPOSCHANGING() |
| 99 |
ON_WM_CAPTURECHANGED() |
| 100 |
ON_WM_SETTINGCHANGE() |
| 101 |
ON_WM_LBUTTONUP() |
| 102 |
ON_WM_MOUSEMOVE() |
| 103 |
ON_WM_NCLBUTTONDOWN() |
| 104 |
ON_WM_LBUTTONDOWN() |
| 105 |
ON_WM_LBUTTONDBLCLK() |
| 106 |
ON_WM_RBUTTONDOWN() |
| 107 |
ON_WM_NCMOUSEMOVE() |
| 108 |
ON_WM_NCHITTEST() |
| 109 |
ON_WM_CLOSE() |
| 110 |
ON_WM_SIZE() |
| 111 |
//}}AFX_MSG_MAP |
| 112 |
ON_MESSAGE( WM_SETTEXT, OnSetText ) |
| 113 |
END_MESSAGE_MAP() |
| 114 |
|
| 115 |
// old creation method, still here for compatibility reasons |
| 116 |
BOOL CSizingControlBar::Create( LPCTSTR lpszWindowName, CWnd* pParentWnd, |
| 117 |
CSize sizeDefault, BOOL bHasGripper, |
| 118 |
UINT nID, DWORD dwStyle ) |
| 119 |
{ |
| 120 |
UNUSED_ALWAYS( bHasGripper ); |
| 121 |
|
| 122 |
m_szHorz = m_szVert = m_szFloat = sizeDefault; |
| 123 |
return Create( lpszWindowName, pParentWnd, nID, dwStyle ); |
| 124 |
} |
| 125 |
|
| 126 |
// preffered creation method |
| 127 |
BOOL CSizingControlBar::Create( LPCTSTR lpszWindowName, |
| 128 |
CWnd* pParentWnd, UINT nID, |
| 129 |
DWORD dwStyle ) |
| 130 |
{ |
| 131 |
// must have a parent |
| 132 |
ASSERT_VALID( pParentWnd ); |
| 133 |
// cannot be both fixed and dynamic |
| 134 |
// (CBRS_SIZE_DYNAMIC is used for resizng when floating) |
| 135 |
ASSERT ( !( ( dwStyle & CBRS_SIZE_FIXED ) && |
| 136 |
( dwStyle & CBRS_SIZE_DYNAMIC ) ) ); |
| 137 |
|
| 138 |
m_dwStyle = dwStyle & CBRS_ALL; // save the control bar styles |
| 139 |
|
| 140 |
// register and create the window - skip CControlBar::Create() |
| 141 |
CString wndclass = ::AfxRegisterWndClass( CS_DBLCLKS, |
| 142 |
::LoadCursor( NULL, IDC_ARROW ), |
| 143 |
::GetSysColorBrush( COLOR_BTNFACE ), 0 ); |
| 144 |
|
| 145 |
dwStyle &= ~CBRS_ALL; // keep only the generic window styles |
| 146 |
dwStyle |= WS_CLIPCHILDREN; // prevents flashing |
| 147 |
if ( !CWnd::Create( wndclass, lpszWindowName, dwStyle, |
| 148 |
CRect( 0, 0, 0, 0 ), pParentWnd, nID ) ) |
| 149 |
return FALSE; |
| 150 |
|
| 151 |
return TRUE; |
| 152 |
} |
| 153 |
|
| 154 |
///////////////////////////////////////////////////////////////////////// |
| 155 |
// CSizingControlBar operations |
| 156 |
#if defined(_SCB_REPLACE_MINIFRAME) && !defined(_SCB_MINIFRAME_CAPTION) |
| 157 |
void CSizingControlBar::EnableDocking( DWORD dwDockStyle ) |
| 158 |
{ |
| 159 |
// must be CBRS_ALIGN_XXX or CBRS_FLOAT_MULTI only |
| 160 |
ASSERT( ( dwDockStyle & ~( CBRS_ALIGN_ANY | CBRS_FLOAT_MULTI ) ) == 0 ); |
| 161 |
// cannot have the CBRS_FLOAT_MULTI style |
| 162 |
ASSERT( ( dwDockStyle & CBRS_FLOAT_MULTI ) == 0 ); |
| 163 |
// the bar must have CBRS_SIZE_DYNAMIC style |
| 164 |
ASSERT( ( m_dwStyle & CBRS_SIZE_DYNAMIC ) != 0 ); |
| 165 |
|
| 166 |
m_dwDockStyle = dwDockStyle; |
| 167 |
if ( m_pDockContext == NULL ) |
| 168 |
m_pDockContext = new CSCBDockContext( this ); |
| 169 |
|
| 170 |
// permanently wire the bar's owner to its current parent |
| 171 |
if ( m_hWndOwner == NULL ) |
| 172 |
m_hWndOwner = ::GetParent( m_hWnd ); |
| 173 |
} |
| 174 |
#endif |
| 175 |
|
| 176 |
///////////////////////////////////////////////////////////////////////// |
| 177 |
// CSizingControlBar message handlers |
| 178 |
|
| 179 |
int CSizingControlBar::OnCreate( LPCREATESTRUCT lpCreateStruct ) |
| 180 |
{ |
| 181 |
if ( baseCSizingControlBar::OnCreate( lpCreateStruct ) == -1 ) |
| 182 |
return -1; |
| 183 |
|
| 184 |
// query SPI_GETDRAGFULLWINDOWS system parameter |
| 185 |
// OnSettingChange() will update m_bDragShowContent |
| 186 |
m_bDragShowContent = FALSE; |
| 187 |
::SystemParametersInfo( SPI_GETDRAGFULLWINDOWS, 0, |
| 188 |
&m_bDragShowContent, 0 ); |
| 189 |
|
| 190 |
// uncomment this line if you want raised borders |
| 191 |
// m_dwSCBStyle |= SCBS_SHOWEDGES; |
| 192 |
|
| 193 |
return 0; |
| 194 |
} |
| 195 |
|
| 196 |
|
| 197 |
LRESULT CSizingControlBar::OnSetText( WPARAM wParam, LPARAM lParam ) |
| 198 |
{ |
| 199 |
UNUSED_ALWAYS( wParam ); |
| 200 |
|
| 201 |
LRESULT lResult = CWnd::Default(); |
| 202 |
|
| 203 |
if ( IsFloating() && |
| 204 |
GetParentFrame() ->IsKindOf( RUNTIME_CLASS( CMiniDockFrameWnd ) ) ) |
| 205 |
{ |
| 206 |
m_pDockBar->SetWindowText( ( LPCTSTR ) lParam ); // update dockbar |
| 207 |
GetParentFrame() ->DelayRecalcLayout(); // refresh miniframe |
| 208 |
} |
| 209 |
|
| 210 |
return lResult; |
| 211 |
} |
| 212 |
|
| 213 |
const BOOL CSizingControlBar::IsFloating() const |
| 214 |
{ |
| 215 |
return !IsHorzDocked() && !IsVertDocked(); |
| 216 |
} |
| 217 |
|
| 218 |
const BOOL CSizingControlBar::IsHorzDocked() const |
| 219 |
{ |
| 220 |
return ( m_nDockBarID == AFX_IDW_DOCKBAR_TOP || |
| 221 |
m_nDockBarID == AFX_IDW_DOCKBAR_BOTTOM ); |
| 222 |
} |
| 223 |
|
| 224 |
const BOOL CSizingControlBar::IsVertDocked() const |
| 225 |
{ |
| 226 |
return ( m_nDockBarID == AFX_IDW_DOCKBAR_LEFT || |
| 227 |
m_nDockBarID == AFX_IDW_DOCKBAR_RIGHT ); |
| 228 |
} |
| 229 |
|
| 230 |
const BOOL CSizingControlBar::IsSideTracking() const |
| 231 |
{ |
| 232 |
// don't call this when not tracking |
| 233 |
ASSERT( m_bTracking && !IsFloating() ); |
| 234 |
|
| 235 |
return ( m_htEdge == HTLEFT || m_htEdge == HTRIGHT ) ? |
| 236 |
IsHorzDocked() : IsVertDocked(); |
| 237 |
} |
| 238 |
|
| 239 |
CSize CSizingControlBar::CalcFixedLayout( BOOL bStretch, BOOL bHorz ) |
| 240 |
{ |
| 241 |
if ( bStretch ) |
| 242 |
// the bar is stretched (is not the child of a dockbar) |
| 243 |
if ( bHorz ) |
| 244 |
return CSize( 32767, m_szHorz.cy ); |
| 245 |
else |
| 246 |
return CSize( m_szVert.cx, 32767 ); |
| 247 |
|
| 248 |
// dirty cast - we need access to protected CDockBar members |
| 249 |
CSCBDockBar* pDockBar = ( CSCBDockBar* ) m_pDockBar; |
| 250 |
|
| 251 |
// force imediate RecalcDelayShow() for all sizing bars on the row |
| 252 |
// with delayShow/delayHide flags set to avoid IsVisible() problems |
| 253 |
CSCBArray arrSCBars; |
| 254 |
GetRowSizingBars( arrSCBars ); |
| 255 |
AFX_SIZEPARENTPARAMS layout; |
| 256 |
layout.hDWP = pDockBar->m_bLayoutQuery ? |
| 257 |
NULL : ::BeginDeferWindowPos( arrSCBars.GetSize() ); |
| 258 |
for ( int i = 0; i < arrSCBars.GetSize(); i++ ) |
| 259 |
if ( arrSCBars[ i ] ->m_nStateFlags & ( delayHide | delayShow ) ) |
| 260 |
arrSCBars[ i ] ->RecalcDelayShow( &layout ); |
| 261 |
if ( layout.hDWP != NULL ) |
| 262 |
::EndDeferWindowPos( layout.hDWP ); |
| 263 |
|
| 264 |
// get available length |
| 265 |
CRect rc = pDockBar->m_rectLayout; |
| 266 |
if ( rc.IsRectEmpty() ) |
| 267 |
m_pDockSite->GetClientRect( &rc ); |
| 268 |
int nLengthTotal = bHorz ? rc.Width() + 2 : rc.Height() - 2; |
| 269 |
|
| 270 |
if ( IsVisible() && !IsFloating() && |
| 271 |
m_bParentSizing && arrSCBars[ 0 ] == this ) |
| 272 |
if ( NegotiateSpace( nLengthTotal, ( bHorz != FALSE ) ) ) |
| 273 |
AlignControlBars(); |
| 274 |
|
| 275 |
m_bParentSizing = FALSE; |
| 276 |
|
| 277 |
if ( bHorz ) |
| 278 |
return CSize( max( m_szMinHorz.cx, m_szHorz.cx ), |
| 279 |
max( m_szMinHorz.cy, m_szHorz.cy ) ); |
| 280 |
|
| 281 |
return CSize( max( m_szMinVert.cx, m_szVert.cx ), |
| 282 |
max( m_szMinVert.cy, m_szVert.cy ) ); |
| 283 |
} |
| 284 |
|
| 285 |
CSize CSizingControlBar::CalcDynamicLayout( int nLength, DWORD dwMode ) |
| 286 |
{ |
| 287 |
// docked ? |
| 288 |
if ( dwMode & ( LM_HORZDOCK | LM_VERTDOCK ) ) |
| 289 |
{ |
| 290 |
if ( nLength == -1 ) |
| 291 |
m_bParentSizing = TRUE; |
| 292 |
|
| 293 |
return baseCSizingControlBar::CalcDynamicLayout( nLength, dwMode ); |
| 294 |
} |
| 295 |
|
| 296 |
if ( dwMode & LM_MRUWIDTH ) |
| 297 |
return m_szFloat; |
| 298 |
if ( dwMode & LM_COMMIT ) |
| 299 |
return m_szFloat; // already committed |
| 300 |
|
| 301 |
#ifndef _SCB_REPLACE_MINIFRAME |
| 302 |
// check for dialgonal resizing hit test |
| 303 |
int nHitTest = m_pDockContext->m_nHitTest; |
| 304 |
if ( IsFloating() && |
| 305 |
( nHitTest == HTTOPLEFT || nHitTest == HTBOTTOMLEFT || |
| 306 |
nHitTest == HTTOPRIGHT || nHitTest == HTBOTTOMRIGHT ) ) |
| 307 |
{ |
| 308 |
CPoint ptCursor; |
| 309 |
::GetCursorPos( &ptCursor ); |
| 310 |
|
| 311 |
CRect rFrame, rBar; |
| 312 |
GetParentFrame() ->GetWindowRect( &rFrame ); |
| 313 |
GetWindowRect( &rBar ); |
| 314 |
|
| 315 |
if ( nHitTest == HTTOPLEFT || nHitTest == HTBOTTOMLEFT ) |
| 316 |
{ |
| 317 |
m_szFloat.cx = rFrame.left + rBar.Width() - ptCursor.x; |
| 318 |
m_pDockContext->m_rectFrameDragHorz.left = |
| 319 |
min( ptCursor.x, rFrame.left + rBar.Width() - m_szMinFloat.cx ); |
| 320 |
} |
| 321 |
|
| 322 |
if ( nHitTest == HTTOPLEFT || nHitTest == HTTOPRIGHT ) |
| 323 |
{ |
| 324 |
m_szFloat.cy = rFrame.top + rBar.Height() - ptCursor.y; |
| 325 |
m_pDockContext->m_rectFrameDragHorz.top = |
| 326 |
min( ptCursor.y, rFrame.top + rBar.Height() - m_szMinFloat.cy ); |
| 327 |
} |
| 328 |
|
| 329 |
if ( nHitTest == HTTOPRIGHT || nHitTest == HTBOTTOMRIGHT ) |
| 330 |
m_szFloat.cx = rBar.Width() + ptCursor.x - rFrame.right; |
| 331 |
|
| 332 |
if ( nHitTest == HTBOTTOMLEFT || nHitTest == HTBOTTOMRIGHT ) |
| 333 |
m_szFloat.cy = rBar.Height() + ptCursor.y - rFrame.bottom; |
| 334 |
} |
| 335 |
else |
| 336 |
#endif //_SCB_REPLACE_MINIFRAME |
| 337 |
|
| 338 |
( ( dwMode & LM_LENGTHY ) ? m_szFloat.cy : m_szFloat.cx ) = nLength; |
| 339 |
|
| 340 |
m_szFloat.cx = max( m_szFloat.cx, m_szMinFloat.cx ); |
| 341 |
m_szFloat.cy = max( m_szFloat.cy, m_szMinFloat.cy ); |
| 342 |
|
| 343 |
return m_szFloat; |
| 344 |
} |
| 345 |
|
| 346 |
void CSizingControlBar::OnWindowPosChanging( WINDOWPOS FAR* lpwndpos ) |
| 347 |
{ |
| 348 |
// force non-client recalc if moved or resized |
| 349 |
lpwndpos->flags |= SWP_FRAMECHANGED; |
| 350 |
|
| 351 |
baseCSizingControlBar::OnWindowPosChanging( lpwndpos ); |
| 352 |
|
| 353 |
// find on which side are we docked |
| 354 |
m_nDockBarID = GetParent() ->GetDlgCtrlID(); |
| 355 |
|
| 356 |
if ( !IsFloating() ) |
| 357 |
if ( lpwndpos->flags & SWP_SHOWWINDOW ) |
| 358 |
m_bKeepSize = TRUE; |
| 359 |
} |
| 360 |
|
| 361 |
///////////////////////////////////////////////////////////////////////// |
| 362 |
// Mouse Handling |
| 363 |
// |
| 364 |
void CSizingControlBar::OnLButtonDown( UINT nFlags, CPoint point ) |
| 365 |
{ |
| 366 |
if ( m_pDockBar != NULL ) |
| 367 |
{ |
| 368 |
// start the drag |
| 369 |
ASSERT( m_pDockContext != NULL ); |
| 370 |
ClientToScreen( &point ); |
| 371 |
m_pDockContext->StartDrag( point ); |
| 372 |
} |
| 373 |
else |
| 374 |
CWnd::OnLButtonDown( nFlags, point ); |
| 375 |
} |
| 376 |
|
| 377 |
void CSizingControlBar::OnLButtonDblClk( UINT nFlags, CPoint point ) |
| 378 |
{ |
| 379 |
if ( m_pDockBar != NULL ) |
| 380 |
{ |
| 381 |
// toggle docking |
| 382 |
ASSERT( m_pDockContext != NULL ); |
| 383 |
m_pDockContext->ToggleDocking(); |
| 384 |
} |
| 385 |
else |
| 386 |
CWnd::OnLButtonDblClk( nFlags, point ); |
| 387 |
} |
| 388 |
|
| 389 |
void CSizingControlBar::OnNcLButtonDown( UINT nHitTest, CPoint point ) |
| 390 |
{ |
| 391 |
UNUSED_ALWAYS( point ); |
| 392 |
|
| 393 |
if ( m_bTracking || IsFloating() ) |
| 394 |
return ; |
| 395 |
|
| 396 |
if ( ( nHitTest >= HTSIZEFIRST ) && ( nHitTest <= HTSIZELAST ) ) |
| 397 |
StartTracking( nHitTest, point ); // sizing edge hit |
| 398 |
} |
| 399 |
|
| 400 |
void CSizingControlBar::OnLButtonUp( UINT nFlags, CPoint point ) |
| 401 |
{ |
| 402 |
if ( m_bTracking ) |
| 403 |
StopTracking(); |
| 404 |
|
| 405 |
baseCSizingControlBar::OnLButtonUp( nFlags, point ); |
| 406 |
} |
| 407 |
|
| 408 |
void CSizingControlBar::OnRButtonDown( UINT nFlags, CPoint point ) |
| 409 |
{ |
| 410 |
if ( m_bTracking ) |
| 411 |
StopTracking(); |
| 412 |
|
| 413 |
baseCSizingControlBar::OnRButtonDown( nFlags, point ); |
| 414 |
} |
| 415 |
|
| 416 |
void CSizingControlBar::OnMouseMove( UINT nFlags, CPoint point ) |
| 417 |
{ |
| 418 |
if ( m_bTracking ) |
| 419 |
{ |
| 420 |
CPoint ptScreen = point; |
| 421 |
ClientToScreen( &ptScreen ); |
| 422 |
|
| 423 |
OnTrackUpdateSize( ptScreen ); |
| 424 |
} |
| 425 |
|
| 426 |
baseCSizingControlBar::OnMouseMove( nFlags, point ); |
| 427 |
} |
| 428 |
|
| 429 |
void CSizingControlBar::OnCaptureChanged( CWnd *pWnd ) |
| 430 |
{ |
| 431 |
if ( m_bTracking && ( pWnd != this ) ) |
| 432 |
StopTracking(); |
| 433 |
|
| 434 |
baseCSizingControlBar::OnCaptureChanged( pWnd ); |
| 435 |
} |
| 436 |
|
| 437 |
void CSizingControlBar::OnNcCalcSize( BOOL bCalcValidRects, |
| 438 |
NCCALCSIZE_PARAMS FAR* lpncsp ) |
| 439 |
{ |
| 440 |
UNUSED_ALWAYS( bCalcValidRects ); |
| 441 |
|
| 442 |
#ifndef _SCB_REPLACE_MINIFRAME |
| 443 |
// Enable diagonal resizing for floating miniframe |
| 444 |
if ( IsFloating() ) |
| 445 |
{ |
| 446 |
CFrameWnd * pFrame = GetParentFrame(); |
| 447 |
if ( pFrame != NULL && |
| 448 |
pFrame->IsKindOf( RUNTIME_CLASS( CMiniFrameWnd ) ) ) |
| 449 |
{ |
| 450 |
DWORD dwStyle = ::GetWindowLong( pFrame->m_hWnd, GWL_STYLE ); |
| 451 |
if ( ( dwStyle & MFS_4THICKFRAME ) != 0 ) |
| 452 |
{ |
| 453 |
pFrame->ModifyStyle( MFS_4THICKFRAME, 0 ); // clear |
| 454 |
GetParent() ->ModifyStyle( 0, WS_CLIPCHILDREN ); |
| 455 |
} |
| 456 |
} |
| 457 |
} |
| 458 |
#endif _SCB_REPLACE_MINIFRAME |
| 459 |
|
| 460 |
// compute the the client area |
| 461 |
m_dwSCBStyle &= ~SCBS_EDGEALL; |
| 462 |
|
| 463 |
// add resizing edges between bars on the same row |
| 464 |
if ( !IsFloating() && m_pDockBar != NULL ) |
| 465 |
{ |
| 466 |
CSCBArray arrSCBars; |
| 467 |
int nThis; |
| 468 |
GetRowSizingBars( arrSCBars, nThis ); |
| 469 |
|
| 470 |
BOOL bHorz = IsHorzDocked(); |
| 471 |
if ( nThis > 0 ) |
| 472 |
m_dwSCBStyle |= bHorz ? SCBS_EDGELEFT : SCBS_EDGETOP; |
| 473 |
|
| 474 |
if ( nThis < arrSCBars.GetUpperBound() ) |
| 475 |
m_dwSCBStyle |= bHorz ? SCBS_EDGERIGHT : SCBS_EDGEBOTTOM; |
| 476 |
} |
| 477 |
|
| 478 |
NcCalcClient( &lpncsp->rgrc[ 0 ], m_nDockBarID ); |
| 479 |
} |
| 480 |
|
| 481 |
void CSizingControlBar::NcCalcClient( LPRECT pRc, UINT nDockBarID ) |
| 482 |
{ |
| 483 |
CRect rc( pRc ); |
| 484 |
|
| 485 |
rc.DeflateRect( 3, 5, 3, 3 ); |
| 486 |
if ( nDockBarID != AFX_IDW_DOCKBAR_FLOAT ) |
| 487 |
rc.DeflateRect( 2, 0, 2, 2 ); |
| 488 |
|
| 489 |
switch ( nDockBarID ) |
| 490 |
{ |
| 491 |
case AFX_IDW_DOCKBAR_TOP: |
| 492 |
m_dwSCBStyle |= SCBS_EDGEBOTTOM; |
| 493 |
break; |
| 494 |
case AFX_IDW_DOCKBAR_BOTTOM: |
| 495 |
m_dwSCBStyle |= SCBS_EDGETOP; |
| 496 |
break; |
| 497 |
case AFX_IDW_DOCKBAR_LEFT: |
| 498 |
m_dwSCBStyle |= SCBS_EDGERIGHT; |
| 499 |
break; |
| 500 |
case AFX_IDW_DOCKBAR_RIGHT: |
| 501 |
m_dwSCBStyle |= SCBS_EDGELEFT; |
| 502 |
break; |
| 503 |
} |
| 504 |
|
| 505 |
// make room for edges only if they will be painted |
| 506 |
if ( m_dwSCBStyle & SCBS_SHOWEDGES ) |
| 507 |
rc.DeflateRect( |
| 508 |
( m_dwSCBStyle & SCBS_EDGELEFT ) ? m_cxEdge : 0, |
| 509 |
( m_dwSCBStyle & SCBS_EDGETOP ) ? m_cxEdge : 0, |
| 510 |
( m_dwSCBStyle & SCBS_EDGERIGHT ) ? m_cxEdge : 0, |
| 511 |
( m_dwSCBStyle & SCBS_EDGEBOTTOM ) ? m_cxEdge : 0 ); |
| 512 |
|
| 513 |
*pRc = rc; |
| 514 |
} |
| 515 |
|
| 516 |
void CSizingControlBar::OnNcPaint() |
| 517 |
{ |
| 518 |
// get window DC that is clipped to the non-client area |
| 519 |
CWindowDC dc( this ); // the HDC will be released by the destructor |
| 520 |
|
| 521 |
CRect rcClient, rcBar; |
| 522 |
GetClientRect( rcClient ); |
| 523 |
ClientToScreen( rcClient ); |
| 524 |
GetWindowRect( rcBar ); |
| 525 |
rcClient.OffsetRect( -rcBar.TopLeft() ); |
| 526 |
rcBar.OffsetRect( -rcBar.TopLeft() ); |
| 527 |
|
| 528 |
CDC mdc; |
| 529 |
mdc.CreateCompatibleDC( &dc ); |
| 530 |
|
| 531 |
CBitmap bm; |
| 532 |
bm.CreateCompatibleBitmap( &dc, rcBar.Width(), rcBar.Height() ); |
| 533 |
CBitmap* pOldBm = mdc.SelectObject( &bm ); |
| 534 |
|
| 535 |
// draw borders in non-client area |
| 536 |
CRect rcDraw = rcBar; |
| 537 |
DrawBorders( &mdc, rcDraw ); |
| 538 |
|
| 539 |
// erase the NC background |
| 540 |
mdc.FillRect( rcDraw, CBrush::FromHandle( |
| 541 |
( HBRUSH ) GetClassLong( m_hWnd, GCL_HBRBACKGROUND ) ) ); |
| 542 |
|
| 543 |
if ( m_dwSCBStyle & SCBS_SHOWEDGES ) |
| 544 |
{ |
| 545 |
CRect rcEdge; // paint the sizing edges |
| 546 |
for ( int i = 0; i < 4; i++ ) |
| 547 |
if ( GetEdgeRect( rcBar, GetEdgeHTCode( i ), rcEdge ) ) |
| 548 |
mdc.Draw3dRect( rcEdge, ::GetSysColor( COLOR_BTNHIGHLIGHT ), |
| 549 |
::GetSysColor( COLOR_BTNSHADOW ) ); |
| 550 |
} |
| 551 |
|
| 552 |
NcPaintGripper( &mdc, rcClient ); |
| 553 |
|
| 554 |
// client area is not our bussiness :) |
| 555 |
dc.IntersectClipRect( rcBar ); |
| 556 |
dc.ExcludeClipRect( rcClient ); |
| 557 |
|
| 558 |
dc.BitBlt( 0, 0, rcBar.Width(), rcBar.Height(), &mdc, 0, 0, SRCCOPY ); |
| 559 |
|
| 560 |
mdc.SelectObject( pOldBm ); |
| 561 |
bm.DeleteObject(); |
| 562 |
mdc.DeleteDC(); |
| 563 |
} |
| 564 |
|
| 565 |
void CSizingControlBar::NcPaintGripper( CDC* pDC, CRect rcClient ) |
| 566 |
{ |
| 567 |
UNUSED_ALWAYS( pDC ); |
| 568 |
UNUSED_ALWAYS( rcClient ); |
| 569 |
} |
| 570 |
|
| 571 |
void CSizingControlBar::OnPaint() |
| 572 |
{ |
| 573 |
// overridden to skip border painting based on clientrect |
| 574 |
CPaintDC dc( this ); |
| 575 |
} |
| 576 |
|
| 577 |
UINT CSizingControlBar::OnNcHitTest( CPoint point ) |
| 578 |
{ |
| 579 |
CRect rcBar, rcEdge; |
| 580 |
GetWindowRect( rcBar ); |
| 581 |
|
| 582 |
if ( !IsFloating() ) |
| 583 |
for ( int i = 0; i < 4; i++ ) |
| 584 |
if ( GetEdgeRect( rcBar, GetEdgeHTCode( i ), rcEdge ) ) |
| 585 |
if ( rcEdge.PtInRect( point ) ) |
| 586 |
return GetEdgeHTCode( i ); |
| 587 |
|
| 588 |
return HTCLIENT; |
| 589 |
} |
| 590 |
|
| 591 |
void CSizingControlBar::OnSettingChange( UINT uFlags, LPCTSTR lpszSection ) |
| 592 |
{ |
| 593 |
baseCSizingControlBar::OnSettingChange( uFlags, lpszSection ); |
| 594 |
|
| 595 |
m_bDragShowContent = FALSE; |
| 596 |
::SystemParametersInfo( SPI_GETDRAGFULLWINDOWS, 0, |
| 597 |
&m_bDragShowContent, 0 ); // update |
| 598 |
} |
| 599 |
|
| 600 |
void CSizingControlBar::OnSize( UINT nType, int cx, int cy ) |
| 601 |
{ |
| 602 |
UNUSED_ALWAYS( nType ); |
| 603 |
|
| 604 |
if ( ( m_dwSCBStyle & SCBS_SIZECHILD ) != 0 ) |
| 605 |
{ |
| 606 |
// automatic child resizing - only one child is allowed |
| 607 |
CWnd * pWnd = GetWindow( GW_CHILD ); |
| 608 |
if ( pWnd != NULL ) |
| 609 |
{ |
| 610 |
pWnd->MoveWindow( 0, 0, cx, cy ); |
| 611 |
ASSERT( pWnd->GetWindow( GW_HWNDNEXT ) == NULL ); |
| 612 |
} |
| 613 |
} |
| 614 |
} |
| 615 |
|
| 616 |
void CSizingControlBar::OnClose() |
| 617 |
{ |
| 618 |
// do nothing: protection against accidentally destruction by the |
| 619 |
// child control (i.e. if user hits Esc in a child editctrl) |
| 620 |
} |
| 621 |
|
| 622 |
///////////////////////////////////////////////////////////////////////// |
| 623 |
// CSizingControlBar implementation helpers |
| 624 |
|
| 625 |
void CSizingControlBar::StartTracking( UINT nHitTest, CPoint point ) |
| 626 |
{ |
| 627 |
SetCapture(); |
| 628 |
|
| 629 |
// make sure no updates are pending |
| 630 |
if ( !m_bDragShowContent ) |
| 631 |
RedrawWindow( NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW ); |
| 632 |
|
| 633 |
m_htEdge = nHitTest; |
| 634 |
m_bTracking = TRUE; |
| 635 |
|
| 636 |
BOOL bHorz = IsHorzDocked(); |
| 637 |
BOOL bHorzTracking = m_htEdge == HTLEFT || m_htEdge == HTRIGHT; |
| 638 |
|
| 639 |
m_nTrackPosOld = bHorzTracking ? point.x : point.y; |
| 640 |
|
| 641 |
CRect rcBar, rcEdge; |
| 642 |
GetWindowRect( rcBar ); |
| 643 |
GetEdgeRect( rcBar, m_htEdge, rcEdge ); |
| 644 |
m_nTrackEdgeOfs = m_nTrackPosOld - |
| 645 |
( bHorzTracking ? rcEdge.CenterPoint().x : rcEdge.CenterPoint().y ); |
| 646 |
|
| 647 |
CSCBArray arrSCBars; |
| 648 |
int nThis; |
| 649 |
GetRowSizingBars( arrSCBars, nThis ); |
| 650 |
|
| 651 |
m_nTrackPosMin = m_nTrackPosMax = m_nTrackPosOld; |
| 652 |
if ( !IsSideTracking() ) |
| 653 |
{ |
| 654 |
// calc minwidth as the max minwidth of the sizing bars on row |
| 655 |
int nMinWidth = bHorz ? m_szMinHorz.cy : m_szMinVert.cx; |
| 656 |
for ( int i = 0; i < arrSCBars.GetSize(); i++ ) |
| 657 |
nMinWidth = max( nMinWidth, bHorz ? |
| 658 |
arrSCBars[ i ] ->m_szMinHorz.cy : |
| 659 |
arrSCBars[ i ] ->m_szMinVert.cx ); |
| 660 |
int nExcessWidth = ( bHorz ? m_szHorz.cy : m_szVert.cx ) - nMinWidth; |
| 661 |
|
| 662 |
// the control bar cannot grow with more than the width of |
| 663 |
// remaining client area of the mainframe |
| 664 |
CRect rcT; |
| 665 |
m_pDockSite->RepositionBars( 0, 0xFFFF, AFX_IDW_PANE_FIRST, |
| 666 |
reposQuery, &rcT, NULL, TRUE ); |
| 667 |
int nMaxWidth = bHorz ? rcT.Height() - 2 : rcT.Width() - 2; |
| 668 |
|
| 669 |
BOOL bTopOrLeft = m_htEdge == HTTOP || m_htEdge == HTLEFT; |
| 670 |
|
| 671 |
m_nTrackPosMin -= bTopOrLeft ? nMaxWidth : nExcessWidth; |
| 672 |
m_nTrackPosMax += bTopOrLeft ? nExcessWidth : nMaxWidth; |
| 673 |
} |
| 674 |
else |
| 675 |
{ |
| 676 |
// side tracking: |
| 677 |
// max size is the actual size plus the amount the other |
| 678 |
// sizing bars can be decreased until they reach their minsize |
| 679 |
if ( m_htEdge == HTBOTTOM || m_htEdge == HTRIGHT ) |
| 680 |
nThis++; |
| 681 |
|
| 682 |
for ( int i = 0; i < arrSCBars.GetSize(); i++ ) |
| 683 |
{ |
| 684 |
CSizingControlBar* pBar = arrSCBars[ i ]; |
| 685 |
|
| 686 |
int nExcessWidth = bHorz ? |
| 687 |
pBar->m_szHorz.cx - pBar->m_szMinHorz.cx : |
| 688 |
pBar->m_szVert.cy - pBar->m_szMinVert.cy; |
| 689 |
|
| 690 |
if ( i < nThis ) |
| 691 |
m_nTrackPosMin -= nExcessWidth; |
| 692 |
else |
| 693 |
m_nTrackPosMax += nExcessWidth; |
| 694 |
} |
| 695 |
} |
| 696 |
|
| 697 |
OnTrackInvertTracker(); // draw tracker |
| 698 |
} |
| 699 |
|
| 700 |
void CSizingControlBar::StopTracking() |
| 701 |
{ |
| 702 |
OnTrackInvertTracker(); // erase tracker |
| 703 |
|
| 704 |
m_bTracking = FALSE; |
| 705 |
ReleaseCapture(); |
| 706 |
|
| 707 |
m_pDockSite->DelayRecalcLayout(); |
| 708 |
} |
| 709 |
|
| 710 |
void CSizingControlBar::OnTrackUpdateSize( CPoint& point ) |
| 711 |
{ |
| 712 |
ASSERT( !IsFloating() ); |
| 713 |
|
| 714 |
BOOL bHorzTrack = m_htEdge == HTLEFT || m_htEdge == HTRIGHT; |
| 715 |
|
| 716 |
int nTrackPos = bHorzTrack ? point.x : point.y; |
| 717 |
nTrackPos = max( m_nTrackPosMin, min( m_nTrackPosMax, nTrackPos ) ); |
| 718 |
|
| 719 |
int nDelta = nTrackPos - m_nTrackPosOld; |
| 720 |
|
| 721 |
if ( nDelta == 0 ) |
| 722 |
return ; // no pos change |
| 723 |
|
| 724 |
OnTrackInvertTracker(); // erase tracker |
| 725 |
|
| 726 |
m_nTrackPosOld = nTrackPos; |
| 727 |
|
| 728 |
BOOL bHorz = IsHorzDocked(); |
| 729 |
|
| 730 |
CSize sizeNew = bHorz ? m_szHorz : m_szVert; |
| 731 |
switch ( m_htEdge ) |
| 732 |
{ |
| 733 |
case HTLEFT: |
| 734 |
sizeNew -= CSize( nDelta, 0 ); |
| 735 |
break; |
| 736 |
case HTTOP: |
| 737 |
sizeNew -= CSize( 0, nDelta ); |
| 738 |
break; |
| 739 |
case HTRIGHT: |
| 740 |
sizeNew += CSize( nDelta, 0 ); |
| 741 |
break; |
| 742 |
case HTBOTTOM: |
| 743 |
sizeNew += CSize( 0, nDelta ); |
| 744 |
break; |
| 745 |
} |
| 746 |
|
| 747 |
CSCBArray arrSCBars; |
| 748 |
int nThis; |
| 749 |
GetRowSizingBars( arrSCBars, nThis ); |
| 750 |
|
| 751 |
if ( !IsSideTracking() ) |
| 752 |
for ( int i = 0; i < arrSCBars.GetSize(); i++ ) |
| 753 |
{ |
| 754 |
CSizingControlBar* pBar = arrSCBars[ i ]; |
| 755 |
// make same width (or height) |
| 756 |
( bHorz ? pBar->m_szHorz.cy : pBar->m_szVert.cx ) = |
| 757 |
bHorz ? sizeNew.cy : sizeNew.cx; |
| 758 |
} |
| 759 |
else |
| 760 |
{ |
| 761 |
int nGrowingBar = nThis; |
| 762 |
BOOL bBefore = m_htEdge == HTTOP || m_htEdge == HTLEFT; |
| 763 |
if ( bBefore && nDelta > 0 ) |
| 764 |
nGrowingBar--; |
| 765 |
if ( !bBefore && nDelta < 0 ) |
| 766 |
nGrowingBar++; |
| 767 |
if ( nGrowingBar != nThis ) |
| 768 |
bBefore = !bBefore; |
| 769 |
|
| 770 |
// nGrowing is growing |
| 771 |
nDelta = abs( nDelta ); |
| 772 |
CSizingControlBar* pBar = arrSCBars[ nGrowingBar ]; |
| 773 |
( bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy ) += nDelta; |
| 774 |
|
| 775 |
// the others are shrinking |
| 776 |
int nFirst = bBefore ? nGrowingBar - 1 : nGrowingBar + 1; |
| 777 |
int nLimit = bBefore ? -1 : arrSCBars.GetSize(); |
| 778 |
|
| 779 |
for ( int i = nFirst; nDelta != 0 && i != nLimit; i += ( bBefore ? -1 : 1 ) ) |
| 780 |
{ |
| 781 |
CSizingControlBar * pBar = arrSCBars[ i ]; |
| 782 |
|
| 783 |
int nDeltaT = min( nDelta, |
| 784 |
( bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy ) - |
| 785 |
( bHorz ? pBar->m_szMinHorz.cx : pBar->m_szMinVert.cy ) ); |
| 786 |
|
| 787 |
( bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy ) -= nDeltaT; |
| 788 |
nDelta -= nDeltaT; |
| 789 |
} |
| 790 |
} |
| 791 |
|
| 792 |
OnTrackInvertTracker(); // redraw tracker at new pos |
| 793 |
|
| 794 |
if ( m_bDragShowContent ) |
| 795 |
m_pDockSite->DelayRecalcLayout(); |
| 796 |
} |
| 797 |
|
| 798 |
void CSizingControlBar::OnTrackInvertTracker() |
| 799 |
{ |
| 800 |
ASSERT( m_bTracking ); |
| 801 |
|
| 802 |
if ( m_bDragShowContent ) |
| 803 |
return ; // don't show tracker if DragFullWindows is on |
| 804 |
|
| 805 |
BOOL bHorz = IsHorzDocked(); |
| 806 |
CRect rc, rcBar, rcDock, rcFrame; |
| 807 |
GetWindowRect( rcBar ); |
| 808 |
m_pDockBar->GetWindowRect( rcDock ); |
| 809 |
m_pDockSite->GetWindowRect( rcFrame ); |
| 810 |
VERIFY( GetEdgeRect( rcBar, m_htEdge, rc ) ); |
| 811 |
if ( !IsSideTracking() ) |
| 812 |
rc = bHorz ? |
| 813 |
CRect( rcDock.left + 1, rc.top, rcDock.right - 1, rc.bottom ) : |
| 814 |
CRect( rc.left, rcDock.top + 1, rc.right, rcDock.bottom - 1 ); |
| 815 |
|
| 816 |
BOOL bHorzTracking = m_htEdge == HTLEFT || m_htEdge == HTRIGHT; |
| 817 |
int nOfs = m_nTrackPosOld - m_nTrackEdgeOfs; |
| 818 |
nOfs -= bHorzTracking ? rc.CenterPoint().x : rc.CenterPoint().y; |
| 819 |
rc.OffsetRect( bHorzTracking ? nOfs : 0, bHorzTracking ? 0 : nOfs ); |
| 820 |
rc.OffsetRect( -rcFrame.TopLeft() ); |
| 821 |
|
| 822 |
CDC *pDC = m_pDockSite->GetDCEx( NULL, |
| 823 |
DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE ); |
| 824 |
CBrush* pBrush = CDC::GetHalftoneBrush(); |
| 825 |
CBrush* pBrushOld = pDC->SelectObject( pBrush ); |
| 826 |
|
| 827 |
pDC->PatBlt( rc.left, rc.top, rc.Width(), rc.Height(), PATINVERT ); |
| 828 |
|
| 829 |
pDC->SelectObject( pBrushOld ); |
| 830 |
m_pDockSite->ReleaseDC( pDC ); |
| 831 |
} |
| 832 |
|
| 833 |
BOOL CSizingControlBar::GetEdgeRect( CRect rcWnd, UINT nHitTest, |
| 834 |
CRect& rcEdge ) |
| 835 |
{ |
| 836 |
rcEdge = rcWnd; |
| 837 |
if ( m_dwSCBStyle & SCBS_SHOWEDGES ) |
| 838 |
rcEdge.DeflateRect( 1, 1 ); |
| 839 |
BOOL bHorz = IsHorzDocked(); |
| 840 |
|
| 841 |
switch ( nHitTest ) |
| 842 |
{ |
| 843 |
case HTLEFT: |
| 844 |
if ( !( m_dwSCBStyle & SCBS_EDGELEFT ) ) |
| 845 |
return FALSE; |
| 846 |
rcEdge.right = rcEdge.left + m_cxEdge; |
| 847 |
rcEdge.DeflateRect( 0, bHorz ? m_cxEdge : 0 ); |
| 848 |
break; |
| 849 |
case HTTOP: |
| 850 |
if ( !( m_dwSCBStyle & SCBS_EDGETOP ) ) |
| 851 |
return FALSE; |
| 852 |
rcEdge.bottom = rcEdge.top + m_cxEdge; |
| 853 |
rcEdge.DeflateRect( bHorz ? 0 : m_cxEdge, 0 ); |
| 854 |
break; |
| 855 |
case HTRIGHT: |
| 856 |
if ( !( m_dwSCBStyle & SCBS_EDGERIGHT ) ) |
| 857 |
return FALSE; |
| 858 |
rcEdge.left = rcEdge.right - m_cxEdge; |
| 859 |
rcEdge.DeflateRect( 0, bHorz ? m_cxEdge : 0 ); |
| 860 |
break; |
| 861 |
case HTBOTTOM: |
| 862 |
if ( !( m_dwSCBStyle & SCBS_EDGEBOTTOM ) ) |
| 863 |
return FALSE; |
| 864 |
rcEdge.top = rcEdge.bottom - m_cxEdge; |
| 865 |
rcEdge.DeflateRect( bHorz ? 0 : m_cxEdge, 0 ); |
| 866 |
break; |
| 867 |
default: |
| 868 |
ASSERT( FALSE ); // invalid hit test code |
| 869 |
} |
| 870 |
return TRUE; |
| 871 |
} |
| 872 |
|
| 873 |
UINT CSizingControlBar::GetEdgeHTCode( int nEdge ) |
| 874 |
{ |
| 875 |
if ( nEdge == 0 ) |
| 876 |
return HTLEFT; |
| 877 |
if ( nEdge == 1 ) |
| 878 |
return HTTOP; |
| 879 |
if ( nEdge == 2 ) |
| 880 |
return HTRIGHT; |
| 881 |
if ( nEdge == 3 ) |
| 882 |
return HTBOTTOM; |
| 883 |
ASSERT( FALSE ); // invalid edge code |
| 884 |
return HTNOWHERE; |
| 885 |
} |
| 886 |
|
| 887 |
void CSizingControlBar::GetRowInfo( int& nFirst, int& nLast, int& nThis ) |
| 888 |
{ |
| 889 |
ASSERT_VALID( m_pDockBar ); // verify bounds |
| 890 |
|
| 891 |
nThis = m_pDockBar->FindBar( this ); |
| 892 |
ASSERT( nThis != -1 ); |
| 893 |
|
| 894 |
int i, nBars = m_pDockBar->m_arrBars.GetSize(); |
| 895 |
|
| 896 |
// find the first and the last bar in row |
| 897 |
for ( nFirst = -1, i = nThis - 1; i >= 0 && nFirst == -1; i-- ) |
| 898 |
if ( m_pDockBar->m_arrBars[ i ] == NULL ) |
| 899 |
nFirst = i + 1; |
| 900 |
for ( nLast = -1, i = nThis + 1; i < nBars && nLast == -1; i++ ) |
| 901 |
if ( m_pDockBar->m_arrBars[ i ] == NULL ) |
| 902 |
nLast = i - 1; |
| 903 |
|
| 904 |
ASSERT( ( nLast != -1 ) && ( nFirst != -1 ) ); |
| 905 |
} |
| 906 |
|
| 907 |
void CSizingControlBar::GetRowSizingBars( CSCBArray& arrSCBars ) |
| 908 |
{ |
| 909 |
int nThis; // dummy |
| 910 |
GetRowSizingBars( arrSCBars, nThis ); |
| 911 |
} |
| 912 |
|
| 913 |
void CSizingControlBar::GetRowSizingBars( CSCBArray& arrSCBars, int& nThis ) |
| 914 |
{ |
| 915 |
arrSCBars.RemoveAll(); |
| 916 |
|
| 917 |
int nFirstT, nLastT, nThisT; |
| 918 |
GetRowInfo( nFirstT, nLastT, nThisT ); |
| 919 |
|
| 920 |
nThis = -1; |
| 921 |
for ( int i = nFirstT; i <= nLastT; i++ ) |
| 922 |
{ |
| 923 |
CSizingControlBar* pBar = |
| 924 |
( CSizingControlBar* ) m_pDockBar->m_arrBars[ i ]; |
| 925 |
if ( HIWORD( pBar ) == 0 ) |
| 926 |
continue; // placeholder |
| 927 |
if ( !pBar->IsVisible() ) |
| 928 |
continue; |
| 929 |
if ( pBar->IsKindOf( RUNTIME_CLASS( CSizingControlBar ) ) ) |
| 930 |
{ |
| 931 |
if ( pBar == this ) |
| 932 |
nThis = arrSCBars.GetSize(); |
| 933 |
|
| 934 |
arrSCBars.Add( pBar ); |
| 935 |
} |
| 936 |
} |
| 937 |
} |
| 938 |
|
| 939 |
BOOL CSizingControlBar::NegotiateSpace( int nLengthTotal, BOOL bHorz ) |
| 940 |
{ |
| 941 |
ASSERT( bHorz == IsHorzDocked() ); |
| 942 |
|
| 943 |
int nFirst, nLast, nThis; |
| 944 |
GetRowInfo( nFirst, nLast, nThis ); |
| 945 |
|
| 946 |
int nLengthAvail = nLengthTotal; |
| 947 |
int nLengthActual = 0; |
| 948 |
int nLengthMin = 2; |
| 949 |
int nWidthMax = 0; |
| 950 |
CSizingControlBar* pBar; |
| 951 |
|
| 952 |
for ( int i = nFirst; i <= nLast; i++ ) |
| 953 |
{ |
| 954 |
pBar = ( CSizingControlBar* ) m_pDockBar->m_arrBars[ i ]; |
| 955 |
if ( HIWORD( pBar ) == 0 ) |
| 956 |
continue; // placeholder |
| 957 |
if ( !pBar->IsVisible() ) |
| 958 |
continue; |
| 959 |
BOOL bIsSizingBar = |
| 960 |
pBar->IsKindOf( RUNTIME_CLASS( CSizingControlBar ) ); |
| 961 |
|
| 962 |
int nLengthBar; // minimum length of the bar |
| 963 |
if ( bIsSizingBar ) |
| 964 |
nLengthBar = bHorz ? pBar->m_szMinHorz.cx - 2 : |
| 965 |
pBar->m_szMinVert.cy - 2; |
| 966 |
else |
| 967 |
{ |
| 968 |
CRect rcBar; |
| 969 |
pBar->GetWindowRect( &rcBar ); |
| 970 |
nLengthBar = bHorz ? rcBar.Width() - 2 : rcBar.Height() - 2; |
| 971 |
} |
| 972 |
|
| 973 |
nLengthMin += nLengthBar; |
| 974 |
if ( nLengthMin > nLengthTotal ) |
| 975 |
{ |
| 976 |
// split the row after fixed bar |
| 977 |
if ( i < nThis ) |
| 978 |
{ |
| 979 |
m_pDockBar->m_arrBars.InsertAt( i + 1, |
| 980 |
( CControlBar* ) NULL ); |
| 981 |
return FALSE; |
| 982 |
} |
| 983 |
|
| 984 |
// only this sizebar remains on the row, adjust it to minsize |
| 985 |
if ( i == nThis ) |
| 986 |
{ |
| 987 |
if ( bHorz ) |
| 988 |
m_szHorz.cx = m_szMinHorz.cx; |
| 989 |
else |
| 990 |
m_szVert.cy = m_szMinVert.cy; |
| 991 |
|
| 992 |
return TRUE; // the dockbar will split the row for us |
| 993 |
} |
| 994 |
|
| 995 |
// we have enough bars - go negotiate with them |
| 996 |
m_pDockBar->m_arrBars.InsertAt( i, ( CControlBar* ) NULL ); |
| 997 |
nLast = i - 1; |
| 998 |
break; |
| 999 |
} |
| 1000 |
|
| 1001 |
if ( bIsSizingBar ) |
| 1002 |
{ |
| 1003 |
nLengthActual += bHorz ? pBar->m_szHorz.cx - 2 : |
| 1004 |
pBar->m_szVert.cy - 2; |
| 1005 |
nWidthMax = max( nWidthMax, bHorz ? pBar->m_szHorz.cy : |
| 1006 |
pBar->m_szVert.cx ); |
| 1007 |
} |
| 1008 |
else |
| 1009 |
nLengthAvail -= nLengthBar; |
| 1010 |
} |
| 1011 |
|
| 1012 |
CSCBArray arrSCBars; |
| 1013 |
GetRowSizingBars( arrSCBars ); |
| 1014 |
int nNumBars = arrSCBars.GetSize(); |
| 1015 |
int nDelta = nLengthAvail - nLengthActual; |
| 1016 |
|
| 1017 |
// return faster when there is only one sizing bar per row (this one) |
| 1018 |
if ( nNumBars == 1 ) |
| 1019 |
{ |
| 1020 |
ASSERT( arrSCBars[ 0 ] == this ); |
| 1021 |
|
| 1022 |
if ( nDelta == 0 ) |
| 1023 |
return TRUE; |
| 1024 |
|
| 1025 |
m_bKeepSize = FALSE; |
| 1026 |
( bHorz ? m_szHorz.cx : m_szVert.cy ) += nDelta; |
| 1027 |
|
| 1028 |
return TRUE; |
| 1029 |
} |
| 1030 |
|
| 1031 |
// make all the bars the same width |
| 1032 |
for ( i = 0; i < nNumBars; i++ ) |
| 1033 |
if ( bHorz ) |
| 1034 |
arrSCBars[ i ] ->m_szHorz.cy = nWidthMax; |
| 1035 |
else |
| 1036 |
arrSCBars[ i ] ->m_szVert.cx = nWidthMax; |
| 1037 |
|
| 1038 |
// distribute the difference between the bars, |
| 1039 |
// but don't shrink them below their minsizes |
| 1040 |
while ( nDelta != 0 ) |
| 1041 |
{ |
| 1042 |
int nDeltaOld = nDelta; |
| 1043 |
for ( i = 0; i < nNumBars; i++ ) |
| 1044 |
{ |
| 1045 |
pBar = arrSCBars[ i ]; |
| 1046 |
int nLMin = bHorz ? |
| 1047 |
pBar->m_szMinHorz.cx : pBar->m_szMinVert.cy; |
| 1048 |
int nL = bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy; |
| 1049 |
|
| 1050 |
if ( ( nL == nLMin ) && ( nDelta < 0 ) || |
| 1051 |
// already at min length |
| 1052 |
pBar->m_bKeepSize ) |
| 1053 |
// or wants to keep its size |
| 1054 |
continue; |
| 1055 |
|
| 1056 |
// sign of nDelta |
| 1057 |
int nDelta2 = ( nDelta == 0 ) ? 0 : ( ( nDelta < 0 ) ? -1 : 1 ); |
| 1058 |
|
| 1059 |
( bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy ) += nDelta2; |
| 1060 |
nDelta -= nDelta2; |
| 1061 |
if ( nDelta == 0 ) |
| 1062 |
break; |
| 1063 |
} |
| 1064 |
// clear m_bKeepSize flags |
| 1065 |
if ( ( nDeltaOld == nDelta ) || ( nDelta == 0 ) ) |
| 1066 |
for ( i = 0; i < nNumBars; i++ ) |
| 1067 |
arrSCBars[ i ] ->m_bKeepSize = FALSE; |
| 1068 |
} |
| 1069 |
|
| 1070 |
return TRUE; |
| 1071 |
} |
| 1072 |
|
| 1073 |
void CSizingControlBar::AlignControlBars() |
| 1074 |
{ |
| 1075 |
int nFirst, nLast, nThis; |
| 1076 |
GetRowInfo( nFirst, nLast, nThis ); |
| 1077 |
|
| 1078 |
BOOL bHorz = IsHorzDocked(); |
| 1079 |
BOOL bNeedRecalc = FALSE; |
| 1080 |
int nAlign = bHorz ? -2 : 0; |
| 1081 |
|
| 1082 |
CRect rc, rcDock; |
| 1083 |
m_pDockBar->GetWindowRect( &rcDock ); |
| 1084 |
|
| 1085 |
for ( int i = nFirst; i <= nLast; i++ ) |
| 1086 |
{ |
| 1087 |
CSizingControlBar* pBar = |
| 1088 |
( CSizingControlBar* ) m_pDockBar->m_arrBars[ i ]; |
| 1089 |
if ( HIWORD( pBar ) == 0 ) |
| 1090 |
continue; // placeholder |
| 1091 |
if ( !pBar->IsVisible() ) |
| 1092 |
continue; |
| 1093 |
|
| 1094 |
pBar->GetWindowRect( &rc ); |
| 1095 |
rc.OffsetRect( -rcDock.TopLeft() ); |
| 1096 |
|
| 1097 |
if ( pBar->IsKindOf( RUNTIME_CLASS( CSizingControlBar ) ) ) |
| 1098 |
rc = CRect( rc.TopLeft(), |
| 1099 |
bHorz ? pBar->m_szHorz : pBar->m_szVert ); |
| 1100 |
|
| 1101 |
if ( ( bHorz ? rc.left : rc.top ) != nAlign ) |
| 1102 |
{ |
| 1103 |
if ( !bHorz ) |
| 1104 |
rc.OffsetRect( 0, nAlign - rc.top - 2 ); |
| 1105 |
else if ( m_nDockBarID == AFX_IDW_DOCKBAR_TOP ) |
| 1106 |
rc.OffsetRect( nAlign - rc.left, -2 ); |
| 1107 |
else |
| 1108 |
rc.OffsetRect( nAlign - rc.left, 0 ); |
| 1109 |
pBar->MoveWindow( rc ); |
| 1110 |
bNeedRecalc = TRUE; |
| 1111 |
} |
| 1112 |
nAlign += ( bHorz ? rc.Width() : rc.Height() ) - 2; |
| 1113 |
} |
| 1114 |
|
| 1115 |
if ( bNeedRecalc ) |
| 1116 |
m_pDockSite->DelayRecalcLayout(); |
| 1117 |
} |
| 1118 |
|
| 1119 |
void CSizingControlBar::OnUpdateCmdUI( CFrameWnd* pTarget, |
| 1120 |
BOOL bDisableIfNoHndler ) |
| 1121 |
{ |
| 1122 |
UNUSED_ALWAYS( bDisableIfNoHndler ); |
| 1123 |
UNUSED_ALWAYS( pTarget ); |
| 1124 |
} |
| 1125 |
|
| 1126 |
void CSizingControlBar::LoadState( LPCTSTR lpszProfileName ) |
| 1127 |
{ |
| 1128 |
ASSERT_VALID( this ); |
| 1129 |
ASSERT( GetSafeHwnd() ); // must be called after Create() |
| 1130 |
|
| 1131 |
#if defined(_SCB_REPLACE_MINIFRAME) && !defined(_SCB_MINIFRAME_CAPTION) |
| 1132 |
// compensate the caption miscalculation in CFrameWnd::SetDockState() |
| 1133 |
CDockState state; |
| 1134 |
state.LoadState( lpszProfileName ); |
| 1135 |
|
| 1136 |
UINT nID = GetDlgCtrlID(); |
| 1137 |
for ( int i = 0; i < state.m_arrBarInfo.GetSize(); i++ ) |
| 1138 |
{ |
| 1139 |
CControlBarInfo* pInfo = ( CControlBarInfo* ) state.m_arrBarInfo[ i ]; |
| 1140 |
ASSERT( pInfo != NULL ); |
| 1141 |
if ( !pInfo->m_bFloating ) |
| 1142 |
continue; |
| 1143 |
|
| 1144 |
// this is a floating dockbar - check the ID array |
| 1145 |
for ( int j = 0; j < pInfo->m_arrBarID.GetSize(); j++ ) |
| 1146 |
if ( ( DWORD ) pInfo->m_arrBarID[ j ] == nID ) |
| 1147 |
{ |
| 1148 |
// found this bar - offset origin and save settings |
| 1149 |
pInfo->m_pointPos.x++; |
| 1150 |
pInfo->m_pointPos.y += |
| 1151 |
::GetSystemMetrics( SM_CYSMCAPTION ) + 1; |
| 1152 |
pInfo->SaveState( lpszProfileName, i ); |
| 1153 |
} |
| 1154 |
} |
| 1155 |
#endif //_SCB_REPLACE_MINIFRAME && !_SCB_MINIFRAME_CAPTION |
| 1156 |
|
| 1157 |
CWinApp* pApp = AfxGetApp(); |
| 1158 |
|
| 1159 |
TCHAR szSection[ 256 ]; |
| 1160 |
wsprintf( szSection, _T( "%s-SCBar-%d" ), lpszProfileName, |
| 1161 |
GetDlgCtrlID() ); |
| 1162 |
|
| 1163 |
m_szHorz.cx = max( m_szMinHorz.cx, ( int ) pApp->GetProfileInt( |
| 1164 |
szSection, _T( "sizeHorzCX" ), m_szHorz.cx ) ); |
| 1165 |
m_szHorz.cy = max( m_szMinHorz.cy, ( int ) pApp->GetProfileInt( |
| 1166 |
szSection, _T( "sizeHorzCY" ), m_szHorz.cy ) ); |
| 1167 |
|
| 1168 |
m_szVert.cx = max( m_szMinVert.cx, ( int ) pApp->GetProfileInt( |
| 1169 |
szSection, _T( "sizeVertCX" ), m_szVert.cx ) ); |
| 1170 |
m_szVert.cy = max( m_szMinVert.cy, ( int ) pApp->GetProfileInt( |
| 1171 |
szSection, _T( "sizeVertCY" ), m_szVert.cy ) ); |
| 1172 |
|
| 1173 |
m_szFloat.cx = max( m_szMinFloat.cx, ( int ) pApp->GetProfileInt( |
| 1174 |
szSection, _T( "sizeFloatCX" ), m_szFloat.cx ) ); |
| 1175 |
m_szFloat.cy = max( m_szMinFloat.cy, ( int ) pApp->GetProfileInt( |
| 1176 |
szSection, _T( "sizeFloatCY" ), m_szFloat.cy ) ); |
| 1177 |
} |
| 1178 |
|
| 1179 |
void CSizingControlBar::SaveState( LPCTSTR lpszProfileName ) |
| 1180 |
{ |
| 1181 |
// place your SaveState or GlobalSaveState call in |
| 1182 |
// CMainFrame's OnClose() or DestroyWindow(), not in OnDestroy() |
| 1183 |
ASSERT_VALID( this ); |
| 1184 |
ASSERT( GetSafeHwnd() ); |
| 1185 |
|
| 1186 |
CWinApp* pApp = AfxGetApp(); |
| 1187 |
|
| 1188 |
TCHAR szSection[ 256 ]; |
| 1189 |
wsprintf( szSection, _T( "%s-SCBar-%d" ), lpszProfileName, |
| 1190 |
GetDlgCtrlID() ); |
| 1191 |
|
| 1192 |
pApp->WriteProfileInt( szSection, _T( "sizeHorzCX" ), m_szHorz.cx ); |
| 1193 |
pApp->WriteProfileInt( szSection, _T( "sizeHorzCY" ), m_szHorz.cy ); |
| 1194 |
|
| 1195 |
pApp->WriteProfileInt( szSection, _T( "sizeVertCX" ), m_szVert.cx ); |
| 1196 |
pApp->WriteProfileInt( szSection, _T( "sizeVertCY" ), m_szVert.cy ); |
| 1197 |
|
| 1198 |
pApp->WriteProfileInt( szSection, _T( "sizeFloatCX" ), m_szFloat.cx ); |
| 1199 |
pApp->WriteProfileInt( szSection, _T( "sizeFloatCY" ), m_szFloat.cy ); |
| 1200 |
} |
| 1201 |
|
| 1202 |
void CSizingControlBar::GlobalLoadState( CFrameWnd* pFrame, |
| 1203 |
LPCTSTR lpszProfileName ) |
| 1204 |
{ |
| 1205 |
POSITION pos = pFrame->m_listControlBars.GetHeadPosition(); |
| 1206 |
while ( pos != NULL ) |
| 1207 |
{ |
| 1208 |
CSizingControlBar * pBar = |
| 1209 |
( CSizingControlBar* ) pFrame->m_listControlBars.GetNext( pos ); |
| 1210 |
ASSERT( pBar != NULL ); |
| 1211 |
if ( pBar->IsKindOf( RUNTIME_CLASS( CSizingControlBar ) ) ) |
| 1212 |
pBar->LoadState( lpszProfileName ); |
| 1213 |
} |
| 1214 |
} |
| 1215 |
|
| 1216 |
void CSizingControlBar::GlobalSaveState( CFrameWnd* pFrame, |
| 1217 |
LPCTSTR lpszProfileName ) |
| 1218 |
{ |
| 1219 |
POSITION pos = pFrame->m_listControlBars.GetHeadPosition(); |
| 1220 |
while ( pos != NULL ) |
| 1221 |
{ |
| 1222 |
CSizingControlBar * pBar = |
| 1223 |
( CSizingControlBar* ) pFrame->m_listControlBars.GetNext( pos ); |
| 1224 |
ASSERT( pBar != NULL ); |
| 1225 |
if ( pBar->IsKindOf( RUNTIME_CLASS( CSizingControlBar ) ) ) |
| 1226 |
pBar->SaveState( lpszProfileName ); |
| 1227 |
} |
| 1228 |
} |
| 1229 |
|
| 1230 |
#ifdef _SCB_REPLACE_MINIFRAME |
| 1231 |
#ifndef _SCB_MINIFRAME_CAPTION |
| 1232 |
///////////////////////////////////////////////////////////////////////////// |
| 1233 |
// CSCBDockContext Drag Operations |
| 1234 |
|
| 1235 |
static void AdjustRectangle( CRect& rect, CPoint pt ) |
| 1236 |
{ |
| 1237 |
int nXOffset = ( pt.x < rect.left ) ? ( pt.x - rect.left ) : |
| 1238 |
( pt.x > rect.right ) ? ( pt.x - rect.right ) : 0; |
| 1239 |
int nYOffset = ( pt.y < rect.top ) ? ( pt.y - rect.top ) : |
| 1240 |
( pt.y > rect.bottom ) ? ( pt.y - rect.bottom ) : 0; |
| 1241 |
rect.OffsetRect( nXOffset, nYOffset ); |
| 1242 |
} |
| 1243 |
|
| 1244 |
void CSCBDockContext::StartDrag( CPoint pt ) |
| 1245 |
{ |
| 1246 |
ASSERT_VALID( m_pBar ); |
| 1247 |
m_bDragging = TRUE; |
| 1248 |
|
| 1249 |
InitLoop(); |
| 1250 |
|
| 1251 |
ASSERT( ( m_pBar->m_dwStyle & CBRS_SIZE_DYNAMIC ) != 0 ); |
| 1252 |
|
| 1253 |
// get true bar size (including borders) |
| 1254 |
CRect rect; |
| 1255 |
m_pBar->GetWindowRect( rect ); |
| 1256 |
m_ptLast = pt; |
| 1257 |
CSize sizeHorz = m_pBar->CalcDynamicLayout( 0, LM_HORZ | LM_HORZDOCK ); |
| 1258 |
CSize sizeVert = m_pBar->CalcDynamicLayout( 0, LM_VERTDOCK ); |
| 1259 |
CSize sizeFloat = m_pBar->CalcDynamicLayout( 0, LM_HORZ | LM_MRUWIDTH ); |
| 1260 |
|
| 1261 |
m_rectDragHorz = CRect( rect.TopLeft(), sizeHorz ); |
| 1262 |
m_rectDragVert = CRect( rect.TopLeft(), sizeVert ); |
| 1263 |
|
| 1264 |
// calculate frame dragging rectangle |
| 1265 |
m_rectFrameDragHorz = CRect( rect.TopLeft(), sizeFloat ); |
| 1266 |
|
| 1267 |
#ifdef _MAC |
| 1268 |
|
| 1269 |
CMiniFrameWnd::CalcBorders( &m_rectFrameDragHorz, |
| 1270 |
WS_THICKFRAME, WS_EX_FORCESIZEBOX ); |
| 1271 |
#else |
| 1272 |
|
| 1273 |
CMiniFrameWnd::CalcBorders( &m_rectFrameDragHorz, WS_THICKFRAME ); |
| 1274 |
#endif |
| 1275 |
|
| 1276 |
m_rectFrameDragHorz.DeflateRect( 2, 2 ); |
| 1277 |
m_rectFrameDragVert = m_rectFrameDragHorz; |
| 1278 |
|
| 1279 |
// adjust rectangles so that point is inside |
| 1280 |
AdjustRectangle( m_rectDragHorz, pt ); |
| 1281 |
AdjustRectangle( m_rectDragVert, pt ); |
| 1282 |
AdjustRectangle( m_rectFrameDragHorz, pt ); |
| 1283 |
AdjustRectangle( m_rectFrameDragVert, pt ); |
| 1284 |
|
| 1285 |
// initialize tracking state and enter tracking loop |
| 1286 |
m_dwOverDockStyle = CanDock(); |
| 1287 |
Move( pt ); // call it here to handle special keys |
| 1288 |
Track(); |
| 1289 |
} |
| 1290 |
#endif //_SCB_MINIFRAME_CAPTION |
| 1291 |
|
| 1292 |
///////////////////////////////////////////////////////////////////////////// |
| 1293 |
// CSCBMiniDockFrameWnd |
| 1294 |
|
| 1295 |
IMPLEMENT_DYNCREATE( CSCBMiniDockFrameWnd, baseCSCBMiniDockFrameWnd ); |
| 1296 |
|
| 1297 |
BEGIN_MESSAGE_MAP( CSCBMiniDockFrameWnd, baseCSCBMiniDockFrameWnd ) |
| 1298 |
//{{AFX_MSG_MAP(CSCBMiniDockFrameWnd) |
| 1299 |
ON_WM_NCLBUTTONDOWN() |
| 1300 |
ON_WM_GETMINMAXINFO() |
| 1301 |
ON_WM_WINDOWPOSCHANGING() |
| 1302 |
ON_WM_SIZE() |
| 1303 |
//}}AFX_MSG_MAP |
| 1304 |
END_MESSAGE_MAP() |
| 1305 |
|
| 1306 |
BOOL CSCBMiniDockFrameWnd::Create( CWnd* pParent, DWORD dwBarStyle ) |
| 1307 |
{ |
| 1308 |
// set m_bInRecalcLayout to avoid flashing during creation |
| 1309 |
// RecalcLayout will be called once something is docked |
| 1310 |
m_bInRecalcLayout = TRUE; |
| 1311 |
|
| 1312 |
DWORD dwStyle = WS_POPUP | WS_CAPTION | WS_SYSMENU | MFS_MOVEFRAME | |
| 1313 |
MFS_4THICKFRAME | MFS_SYNCACTIVE | MFS_BLOCKSYSMENU | |
| 1314 |
FWS_SNAPTOBARS; |
| 1315 |
|
| 1316 |
if ( dwBarStyle & CBRS_SIZE_DYNAMIC ) |
| 1317 |
dwStyle &= ~MFS_MOVEFRAME; |
| 1318 |
|
| 1319 |
DWORD dwExStyle = 0; |
| 1320 |
#ifdef _MAC |
| 1321 |
|
| 1322 |
if ( dwBarStyle & CBRS_SIZE_DYNAMIC ) |
| 1323 |
dwExStyle |= WS_EX_FORCESIZEBOX; |
| 1324 |
else |
| 1325 |
dwStyle &= ~( MFS_MOVEFRAME | MFS_4THICKFRAME ); |
| 1326 |
#endif |
| 1327 |
|
| 1328 |
if ( !CMiniFrameWnd::CreateEx( dwExStyle, |
| 1329 |
NULL, &afxChNil, dwStyle, rectDefault, pParent ) ) |
| 1330 |
{ |
| 1331 |
m_bInRecalcLayout = FALSE; |
| 1332 |
return FALSE; |
| 1333 |
} |
| 1334 |
dwStyle = dwBarStyle & ( CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT ) ? |
| 1335 |
CBRS_ALIGN_LEFT : CBRS_ALIGN_TOP; |
| 1336 |
dwStyle |= dwBarStyle & CBRS_FLOAT_MULTI; |
| 1337 |
CMenu* pSysMenu = GetSystemMenu( FALSE ); |
| 1338 |
//pSysMenu->DeleteMenu(SC_SIZE, MF_BYCOMMAND); |
| 1339 |
CString strHide; |
| 1340 |
if ( strHide.LoadString( AFX_IDS_HIDE ) ) |
| 1341 |
{ |
| 1342 |
pSysMenu->DeleteMenu( SC_CLOSE, MF_BYCOMMAND ); |
| 1343 |
pSysMenu->AppendMenu( MF_STRING | MF_ENABLED, SC_CLOSE, strHide ); |
| 1344 |
} |
| 1345 |
|
| 1346 |
// must initially create with parent frame as parent |
| 1347 |
if ( !m_wndDockBar.Create( pParent, WS_CHILD | WS_VISIBLE | dwStyle, |
| 1348 |
AFX_IDW_DOCKBAR_FLOAT ) ) |
| 1349 |
{ |
| 1350 |
m_bInRecalcLayout = FALSE; |
| 1351 |
return FALSE; |
| 1352 |
} |
| 1353 |
|
| 1354 |
// set parent to CMiniDockFrameWnd |
| 1355 |
m_wndDockBar.SetParent( this ); |
| 1356 |
m_bInRecalcLayout = FALSE; |
| 1357 |
|
| 1358 |
return TRUE; |
| 1359 |
} |
| 1360 |
|
| 1361 |
void CSCBMiniDockFrameWnd::OnNcLButtonDown( UINT nHitTest, CPoint point ) |
| 1362 |
{ |
| 1363 |
if ( nHitTest == HTCAPTION || nHitTest == HTCLOSE ) |
| 1364 |
{ |
| 1365 |
baseCSCBMiniDockFrameWnd::OnNcLButtonDown( nHitTest, point ); |
| 1366 |
return ; |
| 1367 |
} |
| 1368 |
|
| 1369 |
if ( GetSizingControlBar() != NULL ) |
| 1370 |
CMiniFrameWnd::OnNcLButtonDown( nHitTest, point ); |
| 1371 |
else |
| 1372 |
baseCSCBMiniDockFrameWnd::OnNcLButtonDown( nHitTest, point ); |
| 1373 |
} |
| 1374 |
|
| 1375 |
CSizingControlBar* CSCBMiniDockFrameWnd::GetSizingControlBar() |
| 1376 |
{ |
| 1377 |
CWnd * pWnd = GetWindow( GW_CHILD ); // get the dockbar |
| 1378 |
if ( pWnd == NULL ) |
| 1379 |
return NULL; |
| 1380 |
|
| 1381 |
pWnd = pWnd->GetWindow( GW_CHILD ); // get the controlbar |
| 1382 |
if ( pWnd == NULL ) |
| 1383 |
return NULL; |
| 1384 |
|
| 1385 |
if ( !pWnd->IsKindOf( RUNTIME_CLASS( CSizingControlBar ) ) ) |
| 1386 |
return NULL; |
| 1387 |
|
| 1388 |
return ( CSizingControlBar* ) pWnd; |
| 1389 |
} |
| 1390 |
|
| 1391 |
void CSCBMiniDockFrameWnd::OnSize( UINT nType, int cx, int cy ) |
| 1392 |
{ |
| 1393 |
CSizingControlBar * pBar = GetSizingControlBar(); |
| 1394 |
if ( ( pBar != NULL ) && ( GetStyle() & MFS_4THICKFRAME ) == 0 |
| 1395 |
&& pBar->IsVisible() && |
| 1396 |
cx + 4 >= pBar->m_szMinFloat.cx && |
| 1397 |
cy + 4 >= pBar->m_szMinFloat.cy ) |
| 1398 |
pBar->m_szFloat = CSize( cx + 4, cy + 4 ); |
| 1399 |
|
| 1400 |
baseCSCBMiniDockFrameWnd::OnSize( nType, cx, cy ); |
| 1401 |
} |
| 1402 |
|
| 1403 |
void CSCBMiniDockFrameWnd::OnGetMinMaxInfo( MINMAXINFO FAR* lpMMI ) |
| 1404 |
{ |
| 1405 |
baseCSCBMiniDockFrameWnd::OnGetMinMaxInfo( lpMMI ); |
| 1406 |
|
| 1407 |
CSizingControlBar* pBar = GetSizingControlBar(); |
| 1408 |
if ( pBar != NULL ) |
| 1409 |
{ |
| 1410 |
CRect r( CPoint( 0, 0 ), pBar->m_szMinFloat - CSize( 4, 4 ) ); |
| 1411 |
#ifndef _SCB_MINIFRAME_CAPTION |
| 1412 |
|
| 1413 |
CMiniFrameWnd::CalcBorders( &r, WS_THICKFRAME ); |
| 1414 |
#else |
| 1415 |
|
| 1416 |
CMiniFrameWnd::CalcBorders( &r, WS_THICKFRAME | WS_CAPTION ); |
| 1417 |
#endif //_SCB_MINIFRAME_CAPTION |
| 1418 |
|
| 1419 |
lpMMI->ptMinTrackSize.x = r.Width(); |
| 1420 |
lpMMI->ptMinTrackSize.y = r.Height(); |
| 1421 |
} |
| 1422 |
} |
| 1423 |
|
| 1424 |
void CSCBMiniDockFrameWnd::OnWindowPosChanging( WINDOWPOS FAR* lpwndpos ) |
| 1425 |
{ |
| 1426 |
if ( ( GetStyle() & MFS_4THICKFRAME ) != 0 ) |
| 1427 |
{ |
| 1428 |
CSizingControlBar * pBar = GetSizingControlBar(); |
| 1429 |
if ( pBar != NULL ) |
| 1430 |
{ |
| 1431 |
lpwndpos->flags |= SWP_NOSIZE; // don't size this time |
| 1432 |
// prevents flicker |
| 1433 |
pBar->m_pDockBar->ModifyStyle( 0, WS_CLIPCHILDREN ); |
| 1434 |
|
| 1435 |
// enable diagonal resizing |
| 1436 |
DWORD dwStyleRemove = MFS_4THICKFRAME; |
| 1437 |
#ifndef _SCB_MINIFRAME_CAPTION |
| 1438 |
// remove caption |
| 1439 |
dwStyleRemove |= WS_SYSMENU | WS_CAPTION; |
| 1440 |
#endif |
| 1441 |
|
| 1442 |
ModifyStyle( dwStyleRemove, 0 ); |
| 1443 |
|
| 1444 |
DelayRecalcLayout(); |
| 1445 |
pBar->PostMessage( WM_NCPAINT ); |
| 1446 |
} |
| 1447 |
} |
| 1448 |
|
| 1449 |
CMiniFrameWnd::OnWindowPosChanging( lpwndpos ); |
| 1450 |
} |
| 1451 |
|
| 1452 |
#endif //_SCB_REPLACE_MINIFRAME |