Develop and Download Open Source Software

Browse CVS Repository

Contents of /satellite/neuromanager/sizecbar.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.4 - (show annotations) (download) (as text)
Sat Feb 4 13:38:16 2006 UTC (18 years, 2 months ago) by orrisroot
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +0 -0 lines
File MIME type: text/x-c++src
FILE REMOVED
moved main application sources to neuromanager directory.

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

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26