// LayoutSplit.cpp: implementation of the CLayoutSplit class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "LayoutSplit.h" #include "LayoutPanel.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// namespace DynamicLayout { CLayoutSplit::CLayoutSplit( CWnd* pWnd, COLORREF dwColor/*=1*/ ) :m_pPanelSizing(NULL) ,m_pPanelAdhere(NULL) ,m_pOwnerWnd(pWnd) ,m_dwColor(dwColor) ,m_nWidth(4) ,m_pDC(NULL) ,m_pPen(NULL) ,m_nPosLast(0xFFFFFFFF) { } BOOL CLayoutSplit::IsPointOn( int x, int y ) { CRect rect; m_pPanelAdhere->GetRect(rect); switch( m_nBorder ) { case BORDER_TOP: rect.bottom = rect.top; rect.top -= m_nWidth; rect.left++; rect.right--; break; case BORDER_BOTTOM: rect.top = rect.bottom; rect.bottom += m_nWidth; rect.left++; rect.right--; break; case BORDER_LEFT: rect.right = rect.left; rect.left -= m_nWidth; rect.top++; rect.bottom--; break; case BORDER_RIGHT: rect.left = rect.right; rect.right += m_nWidth; rect.top++; rect.bottom--; break; default: break; } return rect.PtInRect( CPoint(x,y) ); } BOOL CLayoutSplit::OnMouseMove( int x, int y ) { if( m_pDC != NULL && IsPosValid(x,y) ) { EraseLast();//清除上次 DrawSplit(x,y);//绘制本次 return TRUE; } else if( IsPointOn(x,y) ) { SetCursor(); return TRUE; } return FALSE; } BOOL CLayoutSplit::OnLButtonDown( int x, int y ) { if( m_pDC != NULL || !IsPointOn(x,y) ) return FALSE; m_pOwnerWnd->SetCapture(); SetCursor(); m_pDC = m_pOwnerWnd->GetDC(); COLORREF dwColor = ( m_dwColor == 1 )?RGB(128,128,128):m_dwColor; m_pPen = new CPen(PS_SOLID,1,dwColor); m_pPen = m_pDC->SelectObject( m_pPen ); m_pDC->SetROP2( R2_NOTXORPEN ); CRect rectAdhere; CRect rectSizing; m_pPanelAdhere->GetRect( rectAdhere ); m_pPanelSizing->GetRect( rectSizing ); //1.记录分割线的位置 //2.计算本地分割条能移动的区间 switch( m_nBorder ) { case BORDER_TOP: m_nPosBegin = y; //鼠标落下时的位置 m_ptSplit.x = rectAdhere.left; //分割条的有效点 m_ptSplit.y = rectAdhere.top-1; m_nSplitLen = rectAdhere.Width(); //分割条的高度 m_nPosMin = y-rectSizing.Height()+2;//分割条可移动范围的最小位置 m_nPosMax = y+rectAdhere.Height()-2;//分割条可移动范围的最大位置 break; case BORDER_BOTTOM: m_nPosBegin = y; m_ptSplit.x = rectAdhere.left; m_ptSplit.y = rectAdhere.bottom+1; m_nSplitLen = rectAdhere.Width(); m_nPosMin = y-rectAdhere.Height()+2; m_nPosMax = y+rectSizing.Height()-2; break; case BORDER_LEFT: m_nPosBegin = x; m_ptSplit.x = rectAdhere.left-1; m_ptSplit.y = rectAdhere.top; m_nSplitLen = rectAdhere.Height(); m_nPosMin = x-rectSizing.Width()+2; m_nPosMax = x+rectAdhere.Width()-2; break; case BORDER_RIGHT: m_nPosBegin = x; m_ptSplit.x = rectAdhere.right+1; m_ptSplit.y = rectAdhere.top; m_nSplitLen = rectAdhere.Height(); m_nPosMin = x-rectAdhere.Width()+2; m_nPosMax = x+rectSizing.Width()-2; break; default: break; } return TRUE; } BOOL CLayoutSplit::OnLButtonUp( int x, int y ) { if( m_pDC == NULL ) return FALSE; //清除最后一次分割条绘制 EraseLast(); //释放绘图设备;还原光标 m_pPen = m_pDC->SelectObject( m_pPen ); delete m_pPen; m_pPen = NULL; m_pOwnerWnd->ReleaseDC( m_pDC ); m_pDC = NULL; RestoreCursor(); ::ReleaseCapture(); //依照风格条位置,改变布局 CRect rectAdhere; CRect rectSizing; m_pPanelAdhere->GetRect( rectAdhere ); m_pPanelSizing->GetRect( rectSizing ); switch(m_nBorder) { case BORDER_TOP: if( y > m_nPosMax ) y = m_nPosMax; else if( y < m_nPosMin ) y = m_nPosMin; rectAdhere.top += (y - m_nPosBegin); rectSizing.bottom += (y - m_nPosBegin); break; case BORDER_BOTTOM: if( y > m_nPosMax ) y = m_nPosMax; else if( y < m_nPosMin ) y = m_nPosMin; rectAdhere.bottom += (y - m_nPosBegin); rectSizing.top += (y - m_nPosBegin); break; case BORDER_LEFT: if( x > m_nPosMax ) x = m_nPosMax; else if( x < m_nPosMin ) x = m_nPosMin; rectAdhere.left += (x - m_nPosBegin); rectSizing.right += (x - m_nPosBegin); break; case BORDER_RIGHT: if( x > m_nPosMax ) x = m_nPosMax; else if( x < m_nPosMin ) x = m_nPosMin; rectAdhere.right += (x - m_nPosBegin); rectSizing.left += (x - m_nPosBegin); break; default: break; } m_pPanelAdhere->SetRect( rectAdhere ); m_pPanelSizing->SetRect( rectSizing ); return TRUE; } void CLayoutSplit::SetCursor() { m_hCursor = ::GetCursor(); if( m_nBorder == BORDER_RIGHT || m_nBorder == BORDER_LEFT ) ::SetCursor( ::LoadCursor( NULL,IDC_SIZEWE ) ); else ::SetCursor( ::LoadCursor( NULL,IDC_SIZENS ) ); } void CLayoutSplit::RestoreCursor() { ::SetCursor( m_hCursor ); } BOOL CLayoutSplit::IsPosValid( int x, int y ) { if( m_nBorder == BORDER_TOP || m_nBorder == BORDER_BOTTOM ) { return ( y<=m_nPosMax && y>=m_nPosMin ); } else { return ( x<=m_nPosMax && x>=m_nPosMin ); } } void CLayoutSplit::DrawSplit(int x, int y) { int i; switch(m_nBorder) { case BORDER_TOP: m_nPosLast = m_ptSplit.y + (y-m_nPosBegin); for(i=0;iMoveTo( m_ptSplit.x, m_nPosLast-i ); m_pDC->LineTo( m_ptSplit.x+m_nSplitLen, m_nPosLast-i ); } break; case BORDER_BOTTOM: m_nPosLast = m_ptSplit.y + (y-m_nPosBegin); for(i=0;iMoveTo( m_ptSplit.x, m_nPosLast+i ); m_pDC->LineTo( m_ptSplit.x+m_nSplitLen, m_nPosLast+i ); } break; case BORDER_RIGHT: m_nPosLast = m_ptSplit.x + (x-m_nPosBegin); for(i=0;iMoveTo( m_nPosLast+i, m_ptSplit.y ); m_pDC->LineTo( m_nPosLast+i,m_ptSplit.y+m_nSplitLen); } break; case BORDER_LEFT: m_nPosLast = m_ptSplit.x + (x-m_nPosBegin); for(i=0;iMoveTo( m_nPosLast-i, m_ptSplit.y ); m_pDC->LineTo( m_nPosLast-i, m_ptSplit.y+m_nSplitLen ); } break; default: break; } } void CLayoutSplit::EraseLast() { if( m_nPosLast != 0xFFFFFFFF ) { int i; switch(m_nBorder) { case BORDER_TOP: for(i=0;iMoveTo( m_ptSplit.x, m_nPosLast-i ); m_pDC->LineTo( m_ptSplit.x+m_nSplitLen, m_nPosLast-i ); } break; case BORDER_BOTTOM: for(i=0;iMoveTo( m_ptSplit.x, m_nPosLast+i ); m_pDC->LineTo( m_ptSplit.x+m_nSplitLen, m_nPosLast+i ); } break; case BORDER_RIGHT: for(i=0;iMoveTo( m_nPosLast+i, m_ptSplit.y ); m_pDC->LineTo( m_nPosLast+i,m_ptSplit.y+m_nSplitLen); } break; case BORDER_LEFT: for(i=0;iMoveTo( m_nPosLast-i, m_ptSplit.y ); m_pDC->LineTo( m_nPosLast-i, m_ptSplit.y+m_nSplitLen ); } break; default: break; } m_nPosLast = 0xFFFFFFFF; }//if }//function }//namespace