⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ngresizectrl.cpp

📁 ResOrg 图形化管理Vc项目的资源ID的工具的源代码。 ResOrg - Manage and Renumber Resource Symbol IDs Introduction The
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ResizeCtrl.cpp: implementation of the CNGResizeCtrl class.
//
//
// Written by Herbert Menke (h.menke@gmx.de)
// Copyright (c) 2000.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is 
// not sold for profit without the authors written consent, and 
// providing that this notice and the authors name is included. If 
// the source code in  this file is used in any commercial application 
// then acknowledgement must be made to the author of this file 
// (in whatever form you wish).
//
// This file is provided "as is" with no expressed or implied warranty.
//
// Expect bugs.
// 
// Please use and enjoy. Please let me know of any bugs/mods/improvements 
// that you have found/implemented and I will fix/incorporate them into this
// file. 
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "NGResizeCtrl.h"


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

// Specification struct
struct RSRect
{
	int left;   // Specifies the percentage change in the position of the left edge 
	// of the object relative to the total change in the parent form抯 width. 
	int top;    // Specifies the percentage change in the position of the top 
	// of the object relative to the total change in the parent form抯 height.
	int width;  // Specifies the percentage change in the width of the object 
	// relative to the total change in the parent form抯 width.
	int height; // Specifies the percentage change in the height of the object 
	// relative to the total change in the parent form抯 height.
};


struct CRPItemState
{
	HWND   handle;    // Handle of Control
	RSRect pending;   // pending Resize pixels
	RSRect part;      // resize specifications
};

class CResizeArray : public CArray<CRPItemState,CRPItemState> { };

static const TCHAR m_szResizeProperty[]	= _T("___CNGResizeCtrl___Class___");
static const UINT m_idGetResizeCtrl		= ::RegisterWindowMessage( _T("WM_GETRESIZECTRL") );

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CNGResizeCtrl::CNGResizeCtrl( )
: m_array       ( NULL  )
, m_hWndParent  ( NULL  )
, m_maxPart     ( 100   )
, m_inResize    ( FALSE )
, m_prevWndProc ( NULL  )
, m_enabled     ( FALSE )
, m_minTracking ( CSize( -1, -1 ) )
, m_maxTracking ( CSize( -1, -1 ) )
, m_hitCode     ( 0 )
, m_inMouseMove ( FALSE )
, m_delta       ( CSize( 0, 0 ) )
, m_windowRect  ( CRect( 0, 0, 0, 0 ) )
, m_gripEnabled ( FALSE )
, m_margins     ( NULL )
{
}

CNGResizeCtrl::CNGResizeCtrl( HWND hWndParent, BOOL enable, int maxPart, BOOL isPropertyPage )
: m_array( NULL )
, m_hWndParent  ( NULL  )
, m_maxPart     ( 100   )
, m_inResize    ( FALSE )
, m_prevWndProc ( NULL  )
, m_enabled     ( FALSE )
, m_minTracking ( CSize( -1, -1 ) )
, m_maxTracking ( CSize( -1, -1 ) )
, m_hitCode     ( 0 )
, m_inMouseMove ( FALSE )
, m_delta       ( CSize( 0, 0 ) )
, m_gripEnabled ( FALSE )
, m_margins     ( NULL )
{
	Create( hWndParent, enable, maxPart, isPropertyPage );
	
}

CNGResizeCtrl::CNGResizeCtrl( CWnd * wndParent, BOOL enable, int maxPart )
: m_array       ( NULL  )
, m_hWndParent  ( NULL  )
, m_maxPart     ( 100   )
, m_inResize    ( FALSE )
, m_prevWndProc ( NULL  )
, m_enabled     ( FALSE )
, m_minTracking ( CSize( -1, -1 ) )
, m_maxTracking ( CSize( -1, -1 ) )
, m_hitCode     ( 0 )
, m_inMouseMove ( FALSE )
, m_delta       ( CSize( 0, 0 ) )
, m_gripEnabled ( FALSE )
, m_margins     ( NULL )
{
	Create( wndParent, enable, maxPart );
}

CNGResizeCtrl::~CNGResizeCtrl()
{
	if( m_array )
	{
		SetEnabled( FALSE );
		m_array->RemoveAll();
		delete m_array;
	}
	if( m_margins )
		delete m_margins;
}

BOOL CNGResizeCtrl::Create( CWnd * wndParent, BOOL enable, int maxPart )
{
	ASSERT( wndParent );
	if( wndParent )
	{
		return Create( wndParent->GetSafeHwnd(), enable, maxPart,
			wndParent->IsKindOf( RUNTIME_CLASS( CPropertyPage ) ));
	}
	return FALSE;
}

BOOL CNGResizeCtrl::Create( HWND hWndParent, BOOL enable, int maxPart, BOOL isPropertyPage )
{
	ASSERT( !m_array );
	if( m_array )
		return FALSE;
	
	m_array = new CResizeArray;
	ASSERT( m_array );
	ASSERT( hWndParent );
	ASSERT( maxPart > 0 );
	m_hWndParent  = hWndParent;
	m_maxPart     = maxPart;
	m_inResize    = FALSE;
	m_prevWndProc = NULL;
	m_enabled     = FALSE;
	m_minTracking.cx  =
		m_minTracking.cy  =
		m_maxTracking.cx  =
		m_maxTracking.cy  = -1;
	if( isPropertyPage )
		m_hasResizingBorder = TRUE;
	else    
		m_hasResizingBorder = (::GetWindowLong( hWndParent, GWL_STYLE ) & WS_THICKFRAME ) == WS_THICKFRAME;
	if( enable )
		SetEnabled( TRUE );
	else
		::GetWindowRect( hWndParent , &m_windowRect );
	return TRUE;
}



//
// Enabled Property
//

BOOL CNGResizeCtrl::SetEnabled( BOOL enable )
{
	if( !m_array )
		return FALSE;
	ASSERT ( m_array );
	
	if( m_enabled != enable )
	{
		ASSERT( m_hWndParent  );
		::GetWindowRect( m_hWndParent, &m_windowRect );
		// remove subclassing
		if( FALSE == enable )
		{
			ASSERT( m_prevWndProc );
			::SetWindowLong( m_hWndParent, GWL_WNDPROC, reinterpret_cast<LONG>( m_prevWndProc ) );
			m_prevWndProc = NULL;
			::RemoveProp( m_hWndParent, m_szResizeProperty );
			if( m_hasResizingBorder == FALSE )
				ChangeStyle( enable );  
		}
		else
		{
			m_hitCode       = 0;
			m_delta.cx      =
				m_delta.cy      = 0;
			m_inResize      = 
				m_inMouseMove   = FALSE;
			//m_hWndFocus     = NULL;
			
			WNDPROC wndProc = CNGResizeCtrl::WndProc;
			if( m_hasResizingBorder == FALSE )
			{
				ChangeStyle( enable );  
			}
			CRect   rect;
			::GetClientRect( m_hWndParent, &rect );
			m_size.cx = rect.Width();
			m_size.cy = rect.Height();
			
			::SetProp( m_hWndParent, m_szResizeProperty, reinterpret_cast<HANDLE>(this) );
			m_prevWndProc = reinterpret_cast<WNDPROC>( ::GetWindowLong( m_hWndParent, GWL_WNDPROC ) );
			::SetWindowLong( m_hWndParent, GWL_WNDPROC, reinterpret_cast<LONG>( wndProc ) );
		}
		m_enabled = enable;
		if( m_gripEnabled )
		{
			GetGripRect( m_gripRect, TRUE );
		}
		return TRUE;
	}
	return FALSE;
}
BOOL CNGResizeCtrl::GetEnabled() const
{
	return m_enabled;
}

//
// GripEnabled Property
//

BOOL CNGResizeCtrl::SetGripEnabled( BOOL showGrip )
{
	if( m_gripEnabled != showGrip )
	{
		m_gripEnabled = showGrip;
		if( m_enabled )
			GetGripRect( m_gripRect, TRUE );
	}
	return FALSE;
}
BOOL CNGResizeCtrl::GetGripEnabled() const
{
	return m_gripEnabled;
}

// resizeInfo is a null terminated array of CResizeInfo

BOOL CNGResizeCtrl::Add( const CResizeInfo * resizeInfo )
{
	ASSERT ( m_array );
	
	BOOL result = TRUE;
	while( result == TRUE && resizeInfo->ctlID > 0 )
	{
		result &= Add( resizeInfo->ctlID,
			resizeInfo->left,
			resizeInfo->top,
			resizeInfo->width,
			resizeInfo->height );
		resizeInfo++;               
	}
	return result;
}

BOOL CNGResizeCtrl::Add( int ctlID,  int left, int top, int width, int height )
{
	ASSERT ( m_array );
	
	return Add( ::GetDlgItem( m_hWndParent, ctlID), left, top, width, height );
}

BOOL CNGResizeCtrl::Add( CWnd * wndCtl, int left, int top, int width, int height )
{
	ASSERT ( m_array );
	
	if( wndCtl )
		return Add( wndCtl->GetSafeHwnd(), left, top, width, height );
	return FALSE;
	
}

BOOL CNGResizeCtrl::Add(HWND hWndCtl, int left, int top, int width, int height)
{
	ASSERT ( m_array );
	
	if( left < 0 || left > m_maxPart )
	{
		return FALSE;
	}
	if( top < 0 || top > m_maxPart )
	{
		return FALSE;
	}
	if( width < 0 || width > m_maxPart )
	{
		return FALSE;
	}
	if( height < 0 || height > m_maxPart )
	{
		return FALSE;
	}
	
	if( ( left + width ) > m_maxPart )
	{
		return FALSE;
	}
	if( ( top + height) > m_maxPart )
	{
		return FALSE;
	}
	
	if( !::IsWindow( hWndCtl))
		return FALSE;
	
	CRPItemState item;
	
	item.part.left   = left;
	item.part.top    = top;
	item.part.width  = width;
	item.part.height = height;
	item.pending.left   =
		item.pending.top    =
		item.pending.width  =
		item.pending.height = 0;
	item.handle         = hWndCtl;
	
	return m_array->Add( item ) >= 0 ;
}

BOOL CNGResizeCtrl::Remove( int ctlID )
{
	ASSERT ( m_array );
	
	return Remove( ::GetDlgItem( m_hWndParent, ctlID ) );
}

BOOL CNGResizeCtrl::Remove( CWnd * wndCtl )
{
	ASSERT ( m_array );
	
	if( wndCtl )
		return Remove( wndCtl->GetSafeHwnd () );
	return FALSE;  
}

BOOL CNGResizeCtrl::Remove(HWND hWndCtl)
{
	ASSERT ( m_array );
	
	if( !::IsWindow( hWndCtl))
		return FALSE;
	
	int upperBound = m_array->GetUpperBound ();
	for( int current = 0; current <= upperBound; current++ )
	{
		if( m_array->GetAt( current ).handle == hWndCtl )
		{
			m_array->RemoveAt( current );
			return TRUE;
		}
	}
	return FALSE;
}

BOOL CNGResizeCtrl::GetWindowRect( RECT * rect )
{
	if( rect )
	{
		*rect = m_windowRect;
		return TRUE;
	}
	else
		return FALSE;
}
#if 0
BOOL CNGResizeCtrl::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;
}
#endif
BOOL CNGResizeCtrl::CalcValue(int delta, int part, int & pending, long &position, BOOL isSize)
{
	if( part > 0 )
	{
		int toAdd = delta * part;
		if( toAdd != 0 )
		{
			pending   +=   toAdd % m_maxPart ;
			
			if( pending >= m_maxPart )
			{
				pending -= m_maxPart;
				position++;
			}
			else if( pending <= -m_maxPart )
			{
				pending += m_maxPart;
				position--;
			}
			
			position  += ( toAdd / m_maxPart );
			
			// avoid negative width or height
			if( TRUE == isSize && position < 0 )
			{
				pending += ( position * m_maxPart );
				position = 0;
			}
			return TRUE;
		}
	}
	return FALSE;
}

void CNGResizeCtrl::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 )
			{
				UINT flags = SWP_NOZORDER;
				if( !IsWindowVisible( m_hWndParent ) )
					flags |= SWP_NOREDRAW | SWP_NOACTIVATE;
				
				//        static int m_count = 0;
				//        int count = ++m_count;
				
				CRPItemState * items = m_array->GetData();
				HDWP  hdwp = ::BeginDeferWindowPos( 0 );
				//        TRACE( "%08d Start Resize hwnd: 0x%8.8x Flags: 0x%8.8x\n", count, m_hWndParent, flags );
				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 );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -