Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(128)

Side by Side Diff: third_party/wtl/include/atlsplit.h

Issue 703753005: More Windows build fixes. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: remove generated files Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/wtl/include/atlscrl.h ('k') | third_party/wtl/include/atltheme.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Windows Template Library - WTL version 8.0
2 // Copyright (C) Microsoft Corporation. All rights reserved.
3 //
4 // This file is a part of the Windows Template Library.
5 // The use and distribution terms for this software are covered by the
6 // Microsoft Permissive License (Ms-PL) which can be found in the file
7 // Ms-PL.txt at the root of this distribution.
8
9 #ifndef __ATLSPLIT_H__
10 #define __ATLSPLIT_H__
11
12 #pragma once
13
14 #ifndef __cplusplus
15 #error ATL requires C++ compilation (use a .cpp suffix)
16 #endif
17
18 #ifndef __ATLAPP_H__
19 #error atlsplit.h requires atlapp.h to be included first
20 #endif
21
22 #ifndef __ATLWIN_H__
23 #error atlsplit.h requires atlwin.h to be included first
24 #endif
25
26
27 ///////////////////////////////////////////////////////////////////////////////
28 // Classes in this file:
29 //
30 // CSplitterImpl<T, t_bVertical>
31 // CSplitterWindowImpl<T, t_bVertical, TBase, TWinTraits>
32 // CSplitterWindowT<t_bVertical>
33
34
35 namespace WTL
36 {
37
38 ///////////////////////////////////////////////////////////////////////////////
39 // CSplitterImpl - Provides splitter support to any window
40
41 // Splitter panes constants
42 #define SPLIT_PANE_LEFT 0
43 #define SPLIT_PANE_RIGHT 1
44 #define SPLIT_PANE_TOP SPLIT_PANE_LEFT
45 #define SPLIT_PANE_BOTTOM SPLIT_PANE_RIGHT
46 #define SPLIT_PANE_NONE -1
47
48 // Splitter extended styles
49 #define SPLIT_PROPORTIONAL 0x00000001
50 #define SPLIT_NONINTERACTIVE 0x00000002
51 #define SPLIT_RIGHTALIGNED 0x00000004
52 #define SPLIT_BOTTOMALIGNED SPLIT_RIGHTALIGNED
53
54 // Note: SPLIT_PROPORTIONAL and SPLIT_RIGHTALIGNED/SPLIT_BOTTOMALIGNED are
55 // mutually exclusive. If both are set, splitter defaults to SPLIT_PROPORTIONAL
56
57
58 template <class T, bool t_bVertical = true>
59 class CSplitterImpl
60 {
61 public:
62 enum { m_nPanesCount = 2, m_nPropMax = 10000 };
63
64 HWND m_hWndPane[m_nPanesCount];
65 RECT m_rcSplitter;
66 int m_xySplitterPos;
67 int m_nDefActivePane;
68 int m_cxySplitBar; // splitter bar width/height
69 static HCURSOR m_hCursor;
70 int m_cxyMin; // minimum pane size
71 int m_cxyBarEdge; // splitter bar edge
72 bool m_bFullDrag;
73 int m_cxyDragOffset;
74 int m_nProportionalPos;
75 bool m_bUpdateProportionalPos;
76 DWORD m_dwExtendedStyle; // splitter specific extended styles
77 int m_nSinglePane; // single pane mode
78
79 // Constructor
80 CSplitterImpl() :
81 m_xySplitterPos(-1), m_nDefActivePane(SPLIT_PANE_NONE),
82 m_cxySplitBar(0), m_cxyMin(0), m_cxyBarEdge(0), m_bFullD rag(true),
83 m_cxyDragOffset(0), m_nProportionalPos(0), m_bUpdateProp ortionalPos(true),
84 m_dwExtendedStyle(SPLIT_PROPORTIONAL),
85 m_nSinglePane(SPLIT_PANE_NONE)
86 {
87 m_hWndPane[SPLIT_PANE_LEFT] = NULL;
88 m_hWndPane[SPLIT_PANE_RIGHT] = NULL;
89
90 ::SetRectEmpty(&m_rcSplitter);
91
92 if(m_hCursor == NULL)
93 {
94 CStaticDataInitCriticalSectionLock lock;
95 if(FAILED(lock.Lock()))
96 {
97 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to l ock critical section in CSplitterImpl::CSplitterImpl.\n"));
98 ATLASSERT(FALSE);
99 return;
100 }
101
102 if(m_hCursor == NULL)
103 m_hCursor = ::LoadCursor(NULL, t_bVertical ? IDC _SIZEWE : IDC_SIZENS);
104
105 lock.Unlock();
106 }
107 }
108
109 // Attributes
110 void SetSplitterRect(LPRECT lpRect = NULL, bool bUpdate = true)
111 {
112 if(lpRect == NULL)
113 {
114 T* pT = static_cast<T*>(this);
115 pT->GetClientRect(&m_rcSplitter);
116 }
117 else
118 {
119 m_rcSplitter = *lpRect;
120 }
121
122 if(IsProportional())
123 UpdateProportionalPos();
124 else if(IsRightAligned())
125 UpdateRightAlignPos();
126
127 if(bUpdate)
128 UpdateSplitterLayout();
129 }
130
131 void GetSplitterRect(LPRECT lpRect) const
132 {
133 ATLASSERT(lpRect != NULL);
134 *lpRect = m_rcSplitter;
135 }
136
137 bool SetSplitterPos(int xyPos = -1, bool bUpdate = true)
138 {
139 if(xyPos == -1) // -1 == middle
140 {
141 if(t_bVertical)
142 xyPos = (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) / 2;
143 else
144 xyPos = (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge) / 2;
145 }
146
147 // Adjust if out of valid range
148 int cxyMax = 0;
149 if(t_bVertical)
150 cxyMax = m_rcSplitter.right - m_rcSplitter.left;
151 else
152 cxyMax = m_rcSplitter.bottom - m_rcSplitter.top;
153
154 if(xyPos < m_cxyMin + m_cxyBarEdge)
155 xyPos = m_cxyMin;
156 else if(xyPos > (cxyMax - m_cxySplitBar - m_cxyBarEdge - m_cxyMi n))
157 xyPos = cxyMax - m_cxySplitBar - m_cxyBarEdge - m_cxyMin ;
158
159 // Set new position and update if requested
160 bool bRet = (m_xySplitterPos != xyPos);
161 m_xySplitterPos = xyPos;
162
163 if(m_bUpdateProportionalPos)
164 {
165 if(IsProportional())
166 StoreProportionalPos();
167 else if(IsRightAligned())
168 StoreRightAlignPos();
169 }
170 else
171 {
172 m_bUpdateProportionalPos = true;
173 }
174
175 if(bUpdate && bRet)
176 UpdateSplitterLayout();
177
178 return bRet;
179 }
180
181 void SetSplitterPosPct(int nPct, bool bUpdate = true)
182 {
183 ATLASSERT(nPct >= 0 && nPct <= 100);
184
185 m_nProportionalPos = ::MulDiv(nPct, m_nPropMax, 100);
186 UpdateProportionalPos();
187
188 if(bUpdate)
189 UpdateSplitterLayout();
190 }
191
192 int GetSplitterPos() const
193 {
194 return m_xySplitterPos;
195 }
196
197 bool SetSinglePaneMode(int nPane = SPLIT_PANE_NONE)
198 {
199 ATLASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT || nPane == SPLIT_PANE_NONE);
200 if(!(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT || nP ane == SPLIT_PANE_NONE))
201 return false;
202
203 if(nPane != SPLIT_PANE_NONE)
204 {
205 if(!::IsWindowVisible(m_hWndPane[nPane]))
206 ::ShowWindow(m_hWndPane[nPane], SW_SHOW);
207 int nOtherPane = (nPane == SPLIT_PANE_LEFT) ? SPLIT_PANE _RIGHT : SPLIT_PANE_LEFT;
208 ::ShowWindow(m_hWndPane[nOtherPane], SW_HIDE);
209 if(m_nDefActivePane != nPane)
210 m_nDefActivePane = nPane;
211 }
212 else if(m_nSinglePane != SPLIT_PANE_NONE)
213 {
214 int nOtherPane = (m_nSinglePane == SPLIT_PANE_LEFT) ? SP LIT_PANE_RIGHT : SPLIT_PANE_LEFT;
215 ::ShowWindow(m_hWndPane[nOtherPane], SW_SHOW);
216 }
217
218 m_nSinglePane = nPane;
219 UpdateSplitterLayout();
220 return true;
221 }
222
223 int GetSinglePaneMode() const
224 {
225 return m_nSinglePane;
226 }
227
228 DWORD GetSplitterExtendedStyle() const
229 {
230 return m_dwExtendedStyle;
231 }
232
233 DWORD SetSplitterExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0)
234 {
235 DWORD dwPrevStyle = m_dwExtendedStyle;
236 if(dwMask == 0)
237 m_dwExtendedStyle = dwExtendedStyle;
238 else
239 m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwE xtendedStyle & dwMask);
240 #ifdef _DEBUG
241 if(IsProportional() && IsRightAligned())
242 ATLTRACE2(atlTraceUI, 0, _T("CSplitterImpl::SetSplitterE xtendedStyle - SPLIT_PROPORTIONAL and SPLIT_RIGHTALIGNED are mutually exclusive, defaulting to SPLIT_PROPORTIONAL.\n"));
243 #endif // _DEBUG
244 return dwPrevStyle;
245 }
246
247 // Splitter operations
248 void SetSplitterPanes(HWND hWndLeftTop, HWND hWndRightBottom, bool bUpda te = true)
249 {
250 m_hWndPane[SPLIT_PANE_LEFT] = hWndLeftTop;
251 m_hWndPane[SPLIT_PANE_RIGHT] = hWndRightBottom;
252 ATLASSERT(m_hWndPane[SPLIT_PANE_LEFT] == NULL || m_hWndPane[SPLI T_PANE_RIGHT] == NULL || m_hWndPane[SPLIT_PANE_LEFT] != m_hWndPane[SPLIT_PANE_RI GHT]);
253 if(bUpdate)
254 UpdateSplitterLayout();
255 }
256
257 bool SetSplitterPane(int nPane, HWND hWnd, bool bUpdate = true)
258 {
259 ATLASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT) ;
260
261 if(nPane != SPLIT_PANE_LEFT && nPane != SPLIT_PANE_RIGHT)
262 return false;
263 m_hWndPane[nPane] = hWnd;
264 ATLASSERT(m_hWndPane[SPLIT_PANE_LEFT] == NULL || m_hWndPane[SPLI T_PANE_RIGHT] == NULL || m_hWndPane[SPLIT_PANE_LEFT] != m_hWndPane[SPLIT_PANE_RI GHT]);
265 if(bUpdate)
266 UpdateSplitterLayout();
267 return true;
268 }
269
270 HWND GetSplitterPane(int nPane) const
271 {
272 ATLASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT) ;
273
274 if(nPane != SPLIT_PANE_LEFT && nPane != SPLIT_PANE_RIGHT)
275 return false;
276 return m_hWndPane[nPane];
277 }
278
279 bool SetActivePane(int nPane)
280 {
281 ATLASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT) ;
282
283 if(nPane != SPLIT_PANE_LEFT && nPane != SPLIT_PANE_RIGHT)
284 return false;
285 if(m_nSinglePane != SPLIT_PANE_NONE && nPane != m_nSinglePane)
286 return false;
287 ::SetFocus(m_hWndPane[nPane]);
288 m_nDefActivePane = nPane;
289 return true;
290 }
291
292 int GetActivePane() const
293 {
294 int nRet = SPLIT_PANE_NONE;
295 HWND hWndFocus = ::GetFocus();
296 if(hWndFocus != NULL)
297 {
298 for(int nPane = 0; nPane < m_nPanesCount; nPane++)
299 {
300 if(hWndFocus == m_hWndPane[nPane] || ::IsChild(m _hWndPane[nPane], hWndFocus))
301 {
302 nRet = nPane;
303 break;
304 }
305 }
306 }
307 return nRet;
308 }
309
310 bool ActivateNextPane(bool bNext = true)
311 {
312 int nPane = m_nSinglePane;
313 if(nPane == SPLIT_PANE_NONE)
314 {
315 switch(GetActivePane())
316 {
317 case SPLIT_PANE_LEFT:
318 nPane = SPLIT_PANE_RIGHT;
319 break;
320 case SPLIT_PANE_RIGHT:
321 nPane = SPLIT_PANE_LEFT;
322 break;
323 default:
324 nPane = bNext ? SPLIT_PANE_LEFT : SPLIT_PANE_RIG HT;
325 break;
326 }
327 }
328 return SetActivePane(nPane);
329 }
330
331 bool SetDefaultActivePane(int nPane)
332 {
333 ATLASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT) ;
334
335 if(nPane != SPLIT_PANE_LEFT && nPane != SPLIT_PANE_RIGHT)
336 return false;
337 m_nDefActivePane = nPane;
338 return true;
339 }
340
341 bool SetDefaultActivePane(HWND hWnd)
342 {
343 for(int nPane = 0; nPane < m_nPanesCount; nPane++)
344 {
345 if(hWnd == m_hWndPane[nPane])
346 {
347 m_nDefActivePane = nPane;
348 return true;
349 }
350 }
351 return false; // not found
352 }
353
354 int GetDefaultActivePane() const
355 {
356 return m_nDefActivePane;
357 }
358
359 void DrawSplitter(CDCHandle dc)
360 {
361 ATLASSERT(dc.m_hDC != NULL);
362 if(m_nSinglePane == SPLIT_PANE_NONE && m_xySplitterPos == -1)
363 return;
364
365 T* pT = static_cast<T*>(this);
366 if(m_nSinglePane == SPLIT_PANE_NONE)
367 {
368 pT->DrawSplitterBar(dc);
369
370 for(int nPane = 0; nPane < m_nPanesCount; nPane++)
371 {
372 if(m_hWndPane[nPane] == NULL)
373 pT->DrawSplitterPane(dc, nPane);
374 }
375 }
376 else
377 {
378 if(m_hWndPane[m_nSinglePane] == NULL)
379 pT->DrawSplitterPane(dc, m_nSinglePane);
380 }
381 }
382
383 // Overrideables
384 void DrawSplitterBar(CDCHandle dc)
385 {
386 RECT rect;
387 if(GetSplitterBarRect(&rect))
388 {
389 dc.FillRect(&rect, COLOR_3DFACE);
390 // draw 3D edge if needed
391 T* pT = static_cast<T*>(this);
392 if((pT->GetExStyle() & WS_EX_CLIENTEDGE) != 0)
393 dc.DrawEdge(&rect, EDGE_RAISED, t_bVertical ? (B F_LEFT | BF_RIGHT) : (BF_TOP | BF_BOTTOM));
394 }
395 }
396
397 // called only if pane is empty
398 void DrawSplitterPane(CDCHandle dc, int nPane)
399 {
400 RECT rect;
401 if(GetSplitterPaneRect(nPane, &rect))
402 {
403 T* pT = static_cast<T*>(this);
404 if((pT->GetExStyle() & WS_EX_CLIENTEDGE) == 0)
405 dc.DrawEdge(&rect, EDGE_SUNKEN, BF_RECT | BF_ADJ UST);
406 dc.FillRect(&rect, COLOR_APPWORKSPACE);
407 }
408 }
409
410 // Message map and handlers
411 BEGIN_MSG_MAP(CSplitterImpl)
412 MESSAGE_HANDLER(WM_CREATE, OnCreate)
413 MESSAGE_HANDLER(WM_PAINT, OnPaint)
414 #ifndef _WIN32_WCE
415 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
416 #endif // !_WIN32_WCE
417 if(IsInteractive())
418 {
419 MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor)
420 MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
421 MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
422 MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
423 MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDoubleClick)
424 MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged)
425 }
426 MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
427 #ifndef _WIN32_WCE
428 MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate)
429 #endif // !_WIN32_WCE
430 MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
431 END_MSG_MAP()
432
433 LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BO OL& bHandled)
434 {
435 GetSystemSettings(false);
436 bHandled = FALSE;
437 return 1;
438 }
439
440 LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOO L& /*bHandled*/)
441 {
442 T* pT = static_cast<T*>(this);
443 // try setting position if not set
444 if(m_nSinglePane == SPLIT_PANE_NONE && m_xySplitterPos == -1)
445 pT->SetSplitterPos();
446 // do painting
447 CPaintDC dc(pT->m_hWnd);
448 pT->DrawSplitter(dc.m_hDC);
449 return 0;
450 }
451
452 LRESULT OnSetCursor(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& b Handled)
453 {
454 T* pT = static_cast<T*>(this);
455 if((HWND)wParam == pT->m_hWnd && LOWORD(lParam) == HTCLIENT)
456 {
457 DWORD dwPos = ::GetMessagePos();
458 POINT ptPos = { GET_X_LPARAM(dwPos), GET_Y_LPARAM(dwPos) };
459 pT->ScreenToClient(&ptPos);
460 if(IsOverSplitterBar(ptPos.x, ptPos.y))
461 return 1;
462 }
463
464 bHandled = FALSE;
465 return 0;
466 }
467
468 LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& b Handled)
469 {
470 T* pT = static_cast<T*>(this);
471 int xPos = GET_X_LPARAM(lParam);
472 int yPos = GET_Y_LPARAM(lParam);
473 if((wParam & MK_LBUTTON) && ::GetCapture() == pT->m_hWnd)
474 {
475 int xyNewSplitPos = 0;
476 if(t_bVertical)
477 xyNewSplitPos = xPos - m_rcSplitter.left - m_cxy DragOffset;
478 else
479 xyNewSplitPos = yPos - m_rcSplitter.top - m_cxyD ragOffset;
480
481 if(xyNewSplitPos == -1) // avoid -1, that means middle
482 xyNewSplitPos = -2;
483
484 if(m_xySplitterPos != xyNewSplitPos)
485 {
486 if(m_bFullDrag)
487 {
488 if(pT->SetSplitterPos(xyNewSplitPos, tru e))
489 pT->UpdateWindow();
490 }
491 else
492 {
493 DrawGhostBar();
494 pT->SetSplitterPos(xyNewSplitPos, false) ;
495 DrawGhostBar();
496 }
497 }
498 }
499 else // not dragging, just set cursor
500 {
501 if(IsOverSplitterBar(xPos, yPos))
502 ::SetCursor(m_hCursor);
503 bHandled = FALSE;
504 }
505
506 return 0;
507 }
508
509 LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, B OOL& bHandled)
510 {
511 int xPos = GET_X_LPARAM(lParam);
512 int yPos = GET_Y_LPARAM(lParam);
513 if(IsOverSplitterBar(xPos, yPos))
514 {
515 T* pT = static_cast<T*>(this);
516 pT->SetCapture();
517 ::SetCursor(m_hCursor);
518 if(!m_bFullDrag)
519 DrawGhostBar();
520 if(t_bVertical)
521 m_cxyDragOffset = xPos - m_rcSplitter.left - m_x ySplitterPos;
522 else
523 m_cxyDragOffset = yPos - m_rcSplitter.top - m_xy SplitterPos;
524 }
525 bHandled = FALSE;
526 return 1;
527 }
528
529 LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
530 {
531 ::ReleaseCapture();
532 bHandled = FALSE;
533 return 1;
534 }
535
536 LRESULT OnLButtonDoubleClick(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /* lParam*/, BOOL& /*bHandled*/)
537 {
538 T* pT = static_cast<T*>(this);
539 pT->SetSplitterPos(); // middle
540 return 0;
541 }
542
543 LRESULT OnCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lPar am*/, BOOL& /*bHandled*/)
544 {
545 if(!m_bFullDrag)
546 {
547 DrawGhostBar();
548 UpdateSplitterLayout();
549 T* pT = static_cast<T*>(this);
550 pT->UpdateWindow();
551 }
552 return 0;
553 }
554
555 LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM, BOOL& bHand led)
556 {
557 if(m_nSinglePane == SPLIT_PANE_NONE)
558 {
559 if(m_nDefActivePane == SPLIT_PANE_LEFT || m_nDefActivePa ne == SPLIT_PANE_RIGHT)
560 ::SetFocus(m_hWndPane[m_nDefActivePane]);
561 }
562 else
563 {
564 ::SetFocus(m_hWndPane[m_nSinglePane]);
565 }
566 bHandled = FALSE;
567 return 1;
568 }
569
570 #ifndef _WIN32_WCE
571 LRESULT OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& / *bHandled*/)
572 {
573 T* pT = static_cast<T*>(this);
574 LRESULT lRet = pT->DefWindowProc(uMsg, wParam, lParam);
575 if(lRet == MA_ACTIVATE || lRet == MA_ACTIVATEANDEAT)
576 {
577 DWORD dwPos = ::GetMessagePos();
578 POINT pt = { GET_X_LPARAM(dwPos), GET_Y_LPARAM(dwPos) };
579 pT->ScreenToClient(&pt);
580 RECT rcPane;
581 for(int nPane = 0; nPane < m_nPanesCount; nPane++)
582 {
583 if(GetSplitterPaneRect(nPane, &rcPane) && ::PtIn Rect(&rcPane, pt))
584 {
585 m_nDefActivePane = nPane;
586 break;
587 }
588 }
589 }
590 return lRet;
591 }
592 #endif // !_WIN32_WCE
593
594 LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lPara m*/, BOOL& /*bHandled*/)
595 {
596 GetSystemSettings(true);
597 return 0;
598 }
599
600 // Implementation - internal helpers
601 void UpdateSplitterLayout()
602 {
603 if(m_nSinglePane == SPLIT_PANE_NONE && m_xySplitterPos == -1)
604 return;
605
606 T* pT = static_cast<T*>(this);
607 RECT rect = { 0, 0, 0, 0 };
608 if(m_nSinglePane == SPLIT_PANE_NONE)
609 {
610 if(GetSplitterBarRect(&rect))
611 pT->InvalidateRect(&rect);
612
613 for(int nPane = 0; nPane < m_nPanesCount; nPane++)
614 {
615 if(GetSplitterPaneRect(nPane, &rect))
616 {
617 if(m_hWndPane[nPane] != NULL)
618 ::SetWindowPos(m_hWndPane[nPane] , NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP _NOZORDER);
619 else
620 pT->InvalidateRect(&rect);
621 }
622 }
623 }
624 else
625 {
626 if(GetSplitterPaneRect(m_nSinglePane, &rect))
627 {
628 if(m_hWndPane[m_nSinglePane] != NULL)
629 ::SetWindowPos(m_hWndPane[m_nSinglePane] , NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP _NOZORDER);
630 else
631 pT->InvalidateRect(&rect);
632 }
633 }
634 }
635
636 bool GetSplitterBarRect(LPRECT lpRect) const
637 {
638 ATLASSERT(lpRect != NULL);
639 if(m_nSinglePane != SPLIT_PANE_NONE || m_xySplitterPos == -1)
640 return false;
641
642 if(t_bVertical)
643 {
644 lpRect->left = m_rcSplitter.left + m_xySplitterPos;
645 lpRect->top = m_rcSplitter.top;
646 lpRect->right = m_rcSplitter.left + m_xySplitterPos + m_ cxySplitBar + m_cxyBarEdge;
647 lpRect->bottom = m_rcSplitter.bottom;
648 }
649 else
650 {
651 lpRect->left = m_rcSplitter.left;
652 lpRect->top = m_rcSplitter.top + m_xySplitterPos;
653 lpRect->right = m_rcSplitter.right;
654 lpRect->bottom = m_rcSplitter.top + m_xySplitterPos + m_ cxySplitBar + m_cxyBarEdge;
655 }
656
657 return true;
658 }
659
660 bool GetSplitterPaneRect(int nPane, LPRECT lpRect) const
661 {
662 ATLASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT) ;
663 ATLASSERT(lpRect != NULL);
664 bool bRet = true;
665 if(m_nSinglePane != SPLIT_PANE_NONE)
666 {
667 if(nPane == m_nSinglePane)
668 *lpRect = m_rcSplitter;
669 else
670 bRet = false;
671 }
672 else if(nPane == SPLIT_PANE_LEFT)
673 {
674 if(t_bVertical)
675 {
676 lpRect->left = m_rcSplitter.left;
677 lpRect->top = m_rcSplitter.top;
678 lpRect->right = m_rcSplitter.left + m_xySplitter Pos;
679 lpRect->bottom = m_rcSplitter.bottom;
680 }
681 else
682 {
683 lpRect->left = m_rcSplitter.left;
684 lpRect->top = m_rcSplitter.top;
685 lpRect->right = m_rcSplitter.right;
686 lpRect->bottom = m_rcSplitter.top + m_xySplitter Pos;
687 }
688 }
689 else if(nPane == SPLIT_PANE_RIGHT)
690 {
691 if(t_bVertical)
692 {
693 lpRect->left = m_rcSplitter.left + m_xySplitterP os + m_cxySplitBar + m_cxyBarEdge;
694 lpRect->top = m_rcSplitter.top;
695 lpRect->right = m_rcSplitter.right;
696 lpRect->bottom = m_rcSplitter.bottom;
697 }
698 else
699 {
700 lpRect->left = m_rcSplitter.left;
701 lpRect->top = m_rcSplitter.top + m_xySplitterPos + m_cxySplitBar + m_cxyBarEdge;
702 lpRect->right = m_rcSplitter.right;
703 lpRect->bottom = m_rcSplitter.bottom;
704 }
705 }
706 else
707 {
708 bRet = false;
709 }
710 return bRet;
711 }
712
713 bool IsOverSplitterRect(int x, int y) const
714 {
715 // -1 == don't check
716 return ((x == -1 || (x >= m_rcSplitter.left && x <= m_rcSplitter .right)) &&
717 (y == -1 || (y >= m_rcSplitter.top && y <= m_rcSplitter. bottom)));
718 }
719
720 bool IsOverSplitterBar(int x, int y) const
721 {
722 if(m_nSinglePane != SPLIT_PANE_NONE)
723 return false;
724 if(m_xySplitterPos == -1 || !IsOverSplitterRect(x, y))
725 return false;
726 int xy = t_bVertical ? x : y;
727 int xyOff = t_bVertical ? m_rcSplitter.left : m_rcSplitter.top;
728 return ((xy >= (xyOff + m_xySplitterPos)) && (xy < xyOff + m_xyS plitterPos + m_cxySplitBar + m_cxyBarEdge));
729 }
730
731 void DrawGhostBar()
732 {
733 RECT rect = { 0, 0, 0, 0 };
734 if(GetSplitterBarRect(&rect))
735 {
736 // invert the brush pattern (looks just like frame windo w sizing)
737 T* pT = static_cast<T*>(this);
738 CWindowDC dc(pT->m_hWnd);
739 CBrush brush = CDCHandle::GetHalftoneBrush();
740 if(brush.m_hBrush != NULL)
741 {
742 CBrushHandle brushOld = dc.SelectBrush(brush);
743 dc.PatBlt(rect.left, rect.top, rect.right - rect .left, rect.bottom - rect.top, PATINVERT);
744 dc.SelectBrush(brushOld);
745 }
746 }
747 }
748
749 void GetSystemSettings(bool bUpdate)
750 {
751 #ifndef _WIN32_WCE
752 m_cxySplitBar = ::GetSystemMetrics(t_bVertical ? SM_CXSIZEFRAME : SM_CYSIZEFRAME);
753 #else // CE specific
754 m_cxySplitBar = 2 * ::GetSystemMetrics(t_bVertical ? SM_CXEDGE : SM_CYEDGE);
755 #endif // _WIN32_WCE
756
757 T* pT = static_cast<T*>(this);
758 if((pT->GetExStyle() & WS_EX_CLIENTEDGE))
759 {
760 m_cxyBarEdge = 2 * ::GetSystemMetrics(t_bVertical ? SM_C XEDGE : SM_CYEDGE);
761 m_cxyMin = 0;
762 }
763 else
764 {
765 m_cxyBarEdge = 0;
766 m_cxyMin = 2 * ::GetSystemMetrics(t_bVertical ? SM_CXEDG E : SM_CYEDGE);
767 }
768
769 #ifndef _WIN32_WCE
770 ::SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &m_bFullDrag, 0);
771 #endif // !_WIN32_WCE
772
773 if(bUpdate)
774 UpdateSplitterLayout();
775 }
776
777 bool IsProportional() const
778 {
779 return ((m_dwExtendedStyle & SPLIT_PROPORTIONAL) != 0);
780 }
781
782 void StoreProportionalPos()
783 {
784 int cxyTotal = t_bVertical ? (m_rcSplitter.right - m_rcSplitter. left - m_cxySplitBar - m_cxyBarEdge) : (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge);
785 if(cxyTotal > 0)
786 m_nProportionalPos = ::MulDiv(m_xySplitterPos, m_nPropMa x, cxyTotal);
787 else
788 m_nProportionalPos = 0;
789 ATLTRACE2(atlTraceUI, 0, _T("CSplitterImpl::StoreProportionalPos - %i\n"), m_nProportionalPos);
790 }
791
792 void UpdateProportionalPos()
793 {
794 int cxyTotal = t_bVertical ? (m_rcSplitter.right - m_rcSplitter. left - m_cxySplitBar - m_cxyBarEdge) : (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge);
795 if(cxyTotal > 0)
796 {
797 int xyNewPos = ::MulDiv(m_nProportionalPos, cxyTotal, m_ nPropMax);
798 m_bUpdateProportionalPos = false;
799 T* pT = static_cast<T*>(this);
800 pT->SetSplitterPos(xyNewPos, false);
801 }
802 }
803
804 bool IsRightAligned() const
805 {
806 return ((m_dwExtendedStyle & SPLIT_RIGHTALIGNED) != 0);
807 }
808
809 void StoreRightAlignPos()
810 {
811 int cxyTotal = t_bVertical ? (m_rcSplitter.right - m_rcSplitter. left - m_cxySplitBar - m_cxyBarEdge) : (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge);
812 if(cxyTotal > 0)
813 m_nProportionalPos = cxyTotal - m_xySplitterPos;
814 else
815 m_nProportionalPos = 0;
816 ATLTRACE2(atlTraceUI, 0, _T("CSplitterImpl::StoreRightAlignPos - %i\n"), m_nProportionalPos);
817 }
818
819 void UpdateRightAlignPos()
820 {
821 int cxyTotal = t_bVertical ? (m_rcSplitter.right - m_rcSplitter. left - m_cxySplitBar - m_cxyBarEdge) : (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge);
822 if(cxyTotal > 0)
823 {
824 m_bUpdateProportionalPos = false;
825 T* pT = static_cast<T*>(this);
826 pT->SetSplitterPos(cxyTotal - m_nProportionalPos, false) ;
827 }
828 }
829
830 bool IsInteractive() const
831 {
832 return ((m_dwExtendedStyle & SPLIT_NONINTERACTIVE) == 0);
833 }
834 };
835
836 template <class T, bool t_bVertical> HCURSOR CSplitterImpl< T, t_bVertical>::m_h Cursor = NULL;
837
838
839 ///////////////////////////////////////////////////////////////////////////////
840 // CSplitterWindowImpl - Implements a splitter window
841
842 template <class T, bool t_bVertical = true, class TBase = ATL::CWindow, class TW inTraits = ATL::CControlWinTraits>
843 class ATL_NO_VTABLE CSplitterWindowImpl : public ATL::CWindowImpl< T, TBase, TWi nTraits >, public CSplitterImpl< T , t_bVertical >
844 {
845 public:
846 DECLARE_WND_CLASS_EX(NULL, CS_DBLCLKS, COLOR_WINDOW)
847
848 typedef CSplitterImpl< T , t_bVertical > _baseClass;
849
850 BEGIN_MSG_MAP(CSplitterWindowImpl)
851 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
852 MESSAGE_HANDLER(WM_SIZE, OnSize)
853 CHAIN_MSG_MAP(_baseClass)
854 FORWARD_NOTIFICATIONS()
855 END_MSG_MAP()
856
857 LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lPa ram*/, BOOL& /*bHandled*/)
858 {
859 // handled, no background painting needed
860 return 1;
861 }
862
863 LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bH andled)
864 {
865 if(wParam != SIZE_MINIMIZED)
866 SetSplitterRect();
867
868 bHandled = FALSE;
869 return 1;
870 }
871 };
872
873
874 ///////////////////////////////////////////////////////////////////////////////
875 // CSplitterWindow - Implements a splitter window to be used as is
876
877 template <bool t_bVertical = true>
878 class CSplitterWindowT : public CSplitterWindowImpl<CSplitterWindowT<t_bVertical >, t_bVertical>
879 {
880 public:
881 DECLARE_WND_CLASS_EX(_T("WTL_SplitterWindow"), CS_DBLCLKS, COLOR_WINDOW)
882 };
883
884 typedef CSplitterWindowT<true> CSplitterWindow;
885 typedef CSplitterWindowT<false> CHorSplitterWindow;
886
887 }; // namespace WTL
888
889 #endif // __ATLSPLIT_H__
OLDNEW
« no previous file with comments | « third_party/wtl/include/atlscrl.h ('k') | third_party/wtl/include/atltheme.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698