📄 resizectrl.cpp
字号:
if( m_array->GetAt( current ).handle == hWndCtl )
{
m_array->RemoveAt( current );
return TRUE;
}
}
return FALSE;
}
BOOL CResizeCtrl::GetWindowRect( RECT * rect )
{
if( rect )
{
*rect = m_windowRect;
return TRUE;
}
else
return FALSE;
}
BOOL CResizeCtrl::CalcValue(int delta, int part, int & pending, long &position, BOOL isSize)
{
if( part > 0 )
{
int toAdd = ( delta * part ) + pending;
if( toAdd != 0 )
{
position += ( toAdd / m_maxPart );
pending = toAdd % m_maxPart ;
// avoid negative width or height
if( TRUE == isSize && position < 0 )
{
pending += ( position * m_maxPart );
position = 0;
}
return TRUE;
}
}
return FALSE;
}
void CResizeCtrl::Resize(int cx, int cy)
{
ASSERT ( m_array );
if( FALSE == m_inResize )
{
m_inResize = TRUE;
int upperBound = m_array->GetUpperBound();
if( upperBound >= 0 )
{
int deltaX = cx - m_size.cx;
int deltaY = cy - m_size.cy;
if( deltaX != 0 || deltaY != 0 )
{
CRPItemState * items = m_array->GetData();
HDWP hdwp = ::BeginDeferWindowPos( 0 );
for( int current = 0; current <= upperBound; current++, items++ )
{
RECT rcItem;
::GetWindowRect( items->handle, & rcItem );
::MapWindowPoints( HWND_DESKTOP, m_hWndParent, (LPPOINT)(RECT*)&rcItem, 2 );
rcItem.right -= rcItem.left;
rcItem.bottom -= rcItem.top;
BOOL changed = FALSE;
changed |= CalcValue( deltaX, items->part.left, items->pending.left, rcItem.left, FALSE );
changed |= CalcValue( deltaX, items->part.width, items->pending.width, rcItem.right, TRUE );
changed |= CalcValue( deltaY, items->part.top, items->pending.top, rcItem.top, FALSE );
changed |= CalcValue( deltaY, items->part.height, items->pending.height, rcItem.bottom, TRUE );
if( changed )
{
hdwp = ::DeferWindowPos( hdwp, items->handle, NULL,
rcItem.left, rcItem.top,
rcItem.right, rcItem.bottom, SWP_NOZORDER );
}
}
::EndDeferWindowPos( hdwp );
m_size.cx = cx;
m_size.cy = cy;
}
}
m_inResize = FALSE;
}
}
LRESULT CALLBACK CResizeCtrl::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
LRESULT result = 0;
CResizeCtrl * This = reinterpret_cast<CResizeCtrl *>(::GetProp( hWnd, m_szResizeProperty ));
if( This )
{
WNDPROC prevWndProc = This->m_prevWndProc;
if( FALSE == This->ProcessMessage( msg, wParam, lParam, result ) )
result = ::CallWindowProc( prevWndProc, hWnd, msg, wParam, lParam );
}
return result;
}
void CResizeCtrl::ChangeStyle(BOOL enable)
{
ASSERT( m_hWndParent );
ASSERT( m_hasResizingBorder == FALSE );
CRect rect;
BOOL hasMenu = ::GetMenu( m_hWndParent ) != NULL;
long style = ::GetWindowLong( m_hWndParent, GWL_STYLE );
::GetWindowRect( m_hWndParent, &rect );
// retrieve client Rectangle
RECT oldClientRect;
::GetClientRect( m_hWndParent, &oldClientRect );
RECT newClientRect = oldClientRect;
// adjust rect with current style
::AdjustWindowRect( &oldClientRect, style, hasMenu );
if( enable )
{
style |= WS_THICKFRAME;
}
else
{
style &= ~WS_THICKFRAME;
}
// adjust rect with new style
::AdjustWindowRect( &newClientRect, style, hasMenu );
// and adjust the windowrect, so that the clientrect remains equal
rect.left += ( newClientRect.left - oldClientRect.left );
rect.right += ( newClientRect.right - oldClientRect.right );
rect.top += ( newClientRect.top - oldClientRect.top );
rect.bottom += ( newClientRect.bottom - oldClientRect.bottom );
::SetWindowLong( m_hWndParent, GWL_STYLE, style );
::SetWindowPos ( m_hWndParent, HWND_DESKTOP, rect.left, rect.top, rect.Width(), rect.Height(),
SWP_NOZORDER | SWP_NOACTIVATE );
}
BOOL CResizeCtrl::ProcessMessage(UINT message, WPARAM wParam, LPARAM lParam, LRESULT & result)
{
BOOL handled = FALSE;
if( m_gripEnabled && WM_NCHITTEST == message )
{
POINT pt = { (int)LOWORD(lParam), (int)HIWORD(lParam) };
::ScreenToClient( m_hWndParent, &pt);
if( ::PtInRect ( m_gripRect, pt ) )
{
result = HTBOTTOMRIGHT;
handled = TRUE;
}
}
else if( m_gripEnabled && WM_PAINT == message )
{
// First let the previous windowproc handle the WM_SIZE message
result = ::CallWindowProc( m_prevWndProc, m_hWndParent, message, wParam, lParam );
HDC hDC = ::GetDC( m_hWndParent );
DrawFrameControl(hDC, &m_gripRect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
::ReleaseDC( m_hWndParent, hDC );
// flag message handled
handled = TRUE;
}
else if( WM_DESTROY == message )
{
// Remove subclassing
SetEnabled( FALSE );
}
else if( WM_SIZE == message )
{
// First let the previous windowproc handle the WM_SIZE message
result = ::CallWindowProc( m_prevWndProc, m_hWndParent, message, wParam, lParam );
// resize all registered controls
Resize( (int)LOWORD(lParam) , (int)HIWORD(lParam) );
if( m_gripEnabled )
{
::InvalidateRect( m_hWndParent, m_gripRect, TRUE );
GetGripRect( m_gripRect, TRUE );
}
// flag message handled
handled = TRUE;
}
else if( WM_GETMINMAXINFO == message )
{
// First let the previous windowproc handle the WM_GETMINMAXINFO message
result = ::CallWindowProc( m_prevWndProc, m_hWndParent, message, wParam, lParam );
MINMAXINFO * lpMMI = (MINMAXINFO * )lParam;
if( m_minTracking.cx == -1 )
m_minTracking.cx = lpMMI->ptMinTrackSize.x;
if( m_minTracking.cy == -1 )
m_minTracking.cy = lpMMI->ptMinTrackSize.y;
if( m_maxTracking.cx == -1 )
m_maxTracking.cx = lpMMI->ptMaxTrackSize.x;
if( m_maxTracking.cy == -1 )
m_maxTracking.cy = lpMMI->ptMaxTrackSize.y;
lpMMI->ptMinTrackSize.x = m_minTracking.cx;
lpMMI->ptMinTrackSize.y = m_minTracking.cy;
lpMMI->ptMaxTrackSize.x = m_maxTracking.cx;
lpMMI->ptMaxTrackSize.y = m_maxTracking.cy;
// flag message handled
handled = TRUE;
}
else
{
// if the original window had no resizing border
// we must serve WM_MOUSE, WM_NCLBUTTONDOWN and
// WM_LBUTTONUP to enable resizing
if( !m_hasResizingBorder )
{
POINT mousePostion;
RECT currentRect;
if( WM_MOUSEMOVE == message )
{
if (m_hitCode && !m_inMouseMove )
{
m_inMouseMove = TRUE;
::GetCursorPos( &mousePostion );
mousePostion.x += m_delta.cx;
mousePostion.y += m_delta.cy;
RECT m_previsionRect;
::GetWindowRect( m_hWndParent, ¤tRect );
m_previsionRect = currentRect;
switch( m_hitCode )
{
case HTTOPLEFT : currentRect.left = mousePostion.x; // fall through
case HTTOP : currentRect.top = mousePostion.y; break;
case HTBOTTOMRIGHT : currentRect.right = mousePostion.x; // fall through
case HTBOTTOM : currentRect.bottom = mousePostion.y; break;
case HTBOTTOMLEFT : currentRect.bottom = mousePostion.y; // fall through
case HTLEFT : currentRect.left = mousePostion.x; break;
case HTTOPRIGHT : currentRect.top = mousePostion.y; // fall through
case HTRIGHT : currentRect.right = mousePostion.x; break;
}
if (!::EqualRect( ¤tRect, &m_previsionRect ))
{
int width = currentRect.right - currentRect.left;
int height = currentRect.bottom - currentRect.top;
::SetWindowPos( m_hWndParent, HWND_DESKTOP, currentRect.left, currentRect.top,
width, height, SWP_NOZORDER | SWP_NOACTIVATE );
}
m_inMouseMove = FALSE;
}
}
else if( WM_NCLBUTTONDOWN == message )
{
::GetCursorPos( &mousePostion );
::GetWindowRect( m_hWndParent, ¤tRect );
m_hitCode = wParam;
m_delta.cx =
m_delta.cy = 0;
switch( m_hitCode )
{
case HTTOPLEFT : m_delta.cx = currentRect.left - mousePostion.x; // fall through
case HTTOP : m_delta.cy = currentRect.top - mousePostion.y; break;
case HTBOTTOMRIGHT : m_delta.cx = currentRect.right - mousePostion.x; // fall through
case HTBOTTOM : m_delta.cy = currentRect.bottom - mousePostion.y; break;
case HTBOTTOMLEFT : m_delta.cy = currentRect.bottom - mousePostion.y; // fall through
case HTLEFT : m_delta.cx = currentRect.left - mousePostion.x; break;
case HTTOPRIGHT : m_delta.cy = currentRect.top - mousePostion.y; // fall through
case HTRIGHT : m_delta.cx = currentRect.right - mousePostion.x; break;
default : m_hitCode = 0; break;
}
if (m_hitCode)
{
::SetCapture( m_hWndParent );
}
}
else if( WM_LBUTTONUP == message )
{
if (m_hitCode != 0)
{
::ReleaseCapture();
m_hitCode = 0;
}
}
}
}
return handled;
}
///////////////////////////////////////////////////////////////////////
// MinMaxInfo Support
BOOL CResizeCtrl::SetMinimumTrackingSize( const CSize & size )
{
m_minTracking = size;
return TRUE;
}
BOOL CResizeCtrl::SetMinimumTrackingSize()
{
RECT rect;
::GetWindowRect( m_hWndParent, &rect );
return SetMinimumTrackingSize( CSize( rect.right - rect.left, rect.bottom - rect.top ) );
}
CSize CResizeCtrl::GetMinimumTrackingSize( )
{
return m_minTracking;
}
BOOL CResizeCtrl::SetMaximumTrackingSize( const CSize & size )
{
m_maxTracking = size;
return TRUE;
}
CSize CResizeCtrl::GetMaximumTrackingSize( )
{
return m_maxTracking;
}
void CResizeCtrl::GetGripRect(RECT & rect, BOOL redraw)
{
GetClientRect( m_hWndParent, &rect );
rect.left = rect.right - ::GetSystemMetrics(SM_CXVSCROLL) ;
rect.top = rect.bottom - ::GetSystemMetrics(SM_CYHSCROLL) ;
if( redraw )
::InvalidateRect( m_hWndParent, &rect, TRUE );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -