📄 sizecbar.cpp
字号:
/////////////////////////////////////////////////////////////////////////// Copyright (C) 1998, 1999 by Cristi Posea// All rights reserved//// Use and distribute freely, except: don't remove my name from the// source or documentation (don't take credit for my work), mark your// changes (don't get me blamed for your possible bugs), don't alter// or remove this notice.// No warrantee of any kind, express or implied, is included with this// software; use at your own risk, responsibility for damages (if any) to// anyone resulting from the use of this software rests entirely with the// user.//// This class is intended to be used as a base class. Do not simply add// your code to this file - instead create a new class derived from// CSizingControlBar and put there what you need.// Modify this file only to fix bugs, and don't forget to send me a copy.//// Send bug reports, bug fixes, enhancements, requests, flames, etc.,// and I'll try to keep a version up to date. I can be reached at:// cristip@dundas.com//// More details at MFC Programmer's SourceBook// http://www.codeguru.com/docking/docking_window.shtml or search// www.codeguru.com for my name if the article was moved./////////////////////////////////////////////////////////////////////////////// Acknowledgements:// o Thanks to Harlan R. Seymour (harlans@dundas.com) for his continuous// support during development of this code.// o Thanks to Dundas Software for the opportunity to test this code// on real-life applications.// If you don't know who they are, visit them at www.dundas.com .// Their award winning components and development suites are// a pile of gold.// o Thanks to Chris Maunder (chrism@dundas.com) who came with the// simplest way to query "Show window content while dragging" system// setting.// o Thanks to Zafir Anjum (zafir@codeguru.com) for publishing this// code on his cool site (www.codeguru.com).// o Some ideas for the gripper came from the CToolBarEx flat toolbar// by Joerg Koenig (Joerg.Koenig@rhein-neckar.de). Also he inspired// me on writing this notice:) . Thanks, Joerg!// o Thanks to Jakawan Ratiwanich (jack@alpha.fsec.ucf.edu) and to// Udo Schaefer (Udo.Schaefer@vcase.de) for the dwStyle bug fix under// VC++ 6.0.// o And, of course, many thanks to all of you who used this code,// for the invaluable feedback I received.// /////////////////////////////////////////////////////////////////////////// sizecbar.cpp : implementation file//#include "stdafx.h"#include "sizecbar.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////// CSizingControlBarCSCBArray CSizingControlBar::m_arrBars; // static memberIMPLEMENT_DYNAMIC(CSizingControlBar, baseCSizingControlBar);CSizingControlBar::CSizingControlBar(){ m_szMin = CSize(33, 32); m_szHorz = CSize(200, 200); m_szVert = CSize(200, 200); m_szFloat = CSize(200, 200); m_bTracking = FALSE; m_bKeepSize = FALSE; m_bParentSizing = FALSE; m_cxEdge = 5; m_bDragShowContent = FALSE; m_nDockBarID = 0; m_dwSCBStyle = 0;}CSizingControlBar::~CSizingControlBar(){}BEGIN_MESSAGE_MAP(CSizingControlBar, baseCSizingControlBar) //{{AFX_MSG_MAP(CSizingControlBar) ON_WM_CREATE() ON_WM_PAINT() ON_WM_NCPAINT() ON_WM_NCCALCSIZE() ON_WM_WINDOWPOSCHANGING() ON_WM_CAPTURECHANGED() ON_WM_SETTINGCHANGE() ON_WM_LBUTTONUP() ON_WM_MOUSEMOVE() ON_WM_NCLBUTTONDOWN() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONDBLCLK() ON_WM_RBUTTONDOWN() ON_WM_NCLBUTTONUP() ON_WM_NCMOUSEMOVE() ON_WM_NCHITTEST() //}}AFX_MSG_MAPEND_MESSAGE_MAP()BOOL CSizingControlBar::Create(LPCTSTR lpszWindowName, CWnd* pParentWnd, CSize sizeDefault, BOOL bHasGripper, UINT nID, DWORD dwStyle){ // must have a parent ASSERT_VALID(pParentWnd); // cannot be both fixed and dynamic // (CBRS_SIZE_DYNAMIC is used for resizng when floating) ASSERT (!((dwStyle & CBRS_SIZE_FIXED) && (dwStyle & CBRS_SIZE_DYNAMIC))); m_dwStyle = dwStyle & CBRS_ALL; // save the control bar styles m_szHorz = sizeDefault; // set the size members m_szVert = sizeDefault; m_szFloat = sizeDefault; m_cyGripper = bHasGripper ? 12 : 0; // set the gripper width // register and create the window - skip CControlBar::Create() CString wndclass = ::AfxRegisterWndClass(CS_DBLCLKS, ::LoadCursor(NULL, IDC_ARROW), ::GetSysColorBrush(COLOR_BTNFACE), 0); dwStyle &= ~CBRS_ALL; // keep only the generic window styles dwStyle |= WS_CLIPCHILDREN; // prevents flashing if (!CWnd::Create(wndclass, lpszWindowName, dwStyle, CRect(0, 0, 0, 0), pParentWnd, nID)) return FALSE; return TRUE;}/////////////////////////////////////////////////////////////////////////// CSizingControlBar message handlersint CSizingControlBar::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (baseCSizingControlBar::OnCreate(lpCreateStruct) == -1) return -1; // querry SPI_GETDRAGFULLWINDOWS system parameter // OnSettingChange() will update m_bDragShowContent m_bDragShowContent = FALSE; ::SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &m_bDragShowContent, 0); m_arrBars.Add(this); // register // m_dwSCBStyle |= SCBS_SHOWEDGES; return 0;}BOOL CSizingControlBar::DestroyWindow() { int nPos = FindSizingBar(this); ASSERT(nPos >= 0); m_arrBars.RemoveAt(nPos); // unregister return baseCSizingControlBar::DestroyWindow();}const BOOL CSizingControlBar::IsFloating() const{ return !IsHorzDocked() && !IsVertDocked();}const BOOL CSizingControlBar::IsHorzDocked() const{ return (m_nDockBarID == AFX_IDW_DOCKBAR_TOP || m_nDockBarID == AFX_IDW_DOCKBAR_BOTTOM);}const BOOL CSizingControlBar::IsVertDocked() const{ return (m_nDockBarID == AFX_IDW_DOCKBAR_LEFT || m_nDockBarID == AFX_IDW_DOCKBAR_RIGHT);}const BOOL CSizingControlBar::IsSideTracking() const{ // don't call this when not tracking ASSERT(m_bTracking && !IsFloating()); return (m_htEdge == HTLEFT || m_htEdge == HTRIGHT) ? IsHorzDocked() : IsVertDocked();}CSize CSizingControlBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz){ if (bStretch) // the bar is stretched (is not the child of a dockbar) if (bHorz) return CSize(32767, m_szHorz.cy); else return CSize(m_szVert.cx, 32767); // dirty cast - using CSCBDockBar to access protected CDockBar members CSCBDockBar* pDockBar = (CSCBDockBar*) m_pDockBar; // force imediate RecalcDelayShow() for all sizing bars on the row // with delayShow/delayHide flags set to avoid IsVisible() problems CSCBArray arrSCBars; GetRowSizingBars(arrSCBars); AFX_SIZEPARENTPARAMS layout; layout.hDWP = pDockBar->m_bLayoutQuery ? NULL : ::BeginDeferWindowPos(arrSCBars.GetSize()); for (int i = 0; i < arrSCBars.GetSize(); i++) arrSCBars[i]->RecalcDelayShow(&layout); if (layout.hDWP != NULL) ::EndDeferWindowPos(layout.hDWP); // get available length CRect rc = pDockBar->m_rectLayout; if (rc.IsRectEmpty()) m_pDockSite->GetClientRect(&rc); int nLengthAvail = bHorz ? rc.Width() + 2 : rc.Height() - 2; if (IsVisible() && !IsFloating() && m_bParentSizing && arrSCBars[0] == this) if (NegociateSpace(nLengthAvail, (bHorz != FALSE))) AlignControlBars(); m_bParentSizing = FALSE; CSize szRet = bHorz ? m_szHorz : m_szVert; szRet.cx = max(m_szMin.cx, szRet.cx); szRet.cy = max(m_szMin.cy, szRet.cy); return szRet;}CSize CSizingControlBar::CalcDynamicLayout(int nLength, DWORD dwMode){ if (dwMode & (LM_HORZDOCK | LM_VERTDOCK)) // docked ? { if (nLength == -1) m_bParentSizing = TRUE; return baseCSizingControlBar::CalcDynamicLayout(nLength, dwMode); } if (dwMode & LM_MRUWIDTH) return m_szFloat; if (dwMode & LM_COMMIT) return m_szFloat; // already committed ((dwMode & LM_LENGTHY) ? m_szFloat.cy : m_szFloat.cx) = nLength; m_szFloat.cx = max(m_szFloat.cx, m_szMin.cx); m_szFloat.cy = max(m_szFloat.cy, m_szMin.cy); return m_szFloat;}void CSizingControlBar::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos){ // force non-client recalc if moved or resized lpwndpos->flags |= SWP_FRAMECHANGED; baseCSizingControlBar::OnWindowPosChanging(lpwndpos); // find on which side are we docked UINT nOldDockBarID = m_nDockBarID; m_nDockBarID = GetParent()->GetDlgCtrlID(); if (!IsFloating()) if (lpwndpos->flags & SWP_SHOWWINDOW) m_bKeepSize = TRUE;}/////////////////////////////////////////////////////////////////////////// Mouse Handling//void CSizingControlBar::OnLButtonDown(UINT nFlags, CPoint point) { if (m_pDockBar != NULL) { // start the drag ASSERT(m_pDockContext != NULL); ClientToScreen(&point); m_pDockContext->StartDrag(point); } else CWnd::OnLButtonDown(nFlags, point);}void CSizingControlBar::OnLButtonDblClk(UINT nFlags, CPoint point) { if (m_pDockBar != NULL) { // toggle docking ASSERT(m_pDockContext != NULL); m_pDockContext->ToggleDocking(); } else CWnd::OnLButtonDblClk(nFlags, point);}void CSizingControlBar::OnNcLButtonDown(UINT nHitTest, CPoint point) { if (IsFloating()) { baseCSizingControlBar::OnNcLButtonDown(nHitTest, point); return; } if (m_bTracking) return; if ((nHitTest >= HTSIZEFIRST) && (nHitTest <= HTSIZELAST)) StartTracking(nHitTest); // sizing edge hit}void CSizingControlBar::OnNcLButtonUp(UINT nHitTest, CPoint point) { if (nHitTest == HTCLOSE) m_pDockSite->ShowControlBar(this, FALSE, FALSE); // hide baseCSizingControlBar::OnNcLButtonUp(nHitTest, point);}void CSizingControlBar::OnLButtonUp(UINT nFlags, CPoint point) { if (m_bTracking) StopTracking(); baseCSizingControlBar::OnLButtonUp(nFlags, point);}void CSizingControlBar::OnRButtonDown(UINT nFlags, CPoint point) { if (m_bTracking) StopTracking(); baseCSizingControlBar::OnRButtonDown(nFlags, point);}void CSizingControlBar::OnMouseMove(UINT nFlags, CPoint point) { if (m_bTracking) OnTrackUpdateSize(point); baseCSizingControlBar::OnMouseMove(nFlags, point);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -