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

📄 select.cpp

📁 电子白板程序
💻 CPP
字号:
// Select.cpp: implementation of the CSelect class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Select.h"
#include "DrawView.h"

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

#pragma comment( lib , "msimg32.lib" )
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSelect::CSelect( CDrawView & v ) : CDrawBase( v )
{
	this->draw.tag = SELECT;
}

CSelect::~CSelect()
{
	if( this->view )
	{
		DRAW_MAP & dmap = this->view.GetDrawMap();
		
		for( DRAW_MAP::iterator itr = dmap.begin(); itr != dmap.end(); itr ++ )
			
			itr->second->Select( CRect( 0 , 0 , 0 , 0 ) );
		//刷新
		this->view.Invalidate();
	}
}

HCURSOR CSelect::GetCursor( void )
{
	static HCURSOR hCursor = ::AfxGetApp()->LoadCursor( IDC_ERASE );

	if( this->draw.brush.lbStyle == BS_NULL )
		
		return hCursor;
	//设定鼠标形状
	CPoint point;

	::GetCursorPos( &point );

	this->view.ScreenToClient( &point );

	if(  this->rgn.GetSafeHandle( ) && this->rgn.PtInRegion( point ) )

		return ::AfxGetApp( )->LoadStandardCursor( IDC_SIZEALL );

	return CDrawBase::GetCursor();
}

void CSelect::OnDraw( CDC * pDC )
{
	if( this->bitmap.GetSafeHandle() )
	{
		CDC memDC;

		memDC.CreateCompatibleDC( pDC );

		memDC.SelectObject( &this->bitmap );

		BITMAP bm;

		this->bitmap.GetBitmap( &bm );
		//透明显示,Win98下无效
		::TransparentBlt( pDC->GetSafeHdc() , this->bitmap_point.x , this->bitmap_point.y , bm.bmWidth , bm.bmHeight , memDC.GetSafeHdc() , 0 , 0 , bm.bmWidth , bm.bmHeight , RGB( 255 , 255 , 255 ) );
	}
	else
	{
		CPen pen( PS_DOT , 1 , RGB( 0 , 0 , 0 ) );
		
		pDC->SelectObject( &pen );
		
		pDC->SelectStockObject( NULL_BRUSH );
		
		CRect rc( this->draw.start , this->draw.end );
		
		rc.NormalizeRect();
		
		pDC->Rectangle( rc );
	}
}

char * CSelect::Encode( int & size , bool erase )
{	//返回的缓冲区,首先图元id为空
	char * buffer = new char[ 2 ];
	//赋值[0]代表id,[1]代表删除与否
	buffer[ 0 ] = '\0'; buffer[ 1 ] = this->GetProp().brush.lbStyle == BS_NULL;
	//发送的缓冲区
	size = 2;

	DRAW_MAP & dmap = this->view.GetDrawMap();
	//选择图元
	if( ! this->rgn.GetSafeHandle() )
	{
		this->rgn.CreateRectRgn( 0 , 0 , 0 , 0 );
		
		if( this->draw.start.x == this->draw.end.x && this->draw.start.y == this->draw.end.y )
		{
			this->draw.end.x += 1; this->draw.end.y += 1;
		}		
		CRect rect( this->draw.start , this->draw.end );
		
		for( DRAW_MAP::iterator itr = dmap.begin(); itr != dmap.end(); )
		{			
			if( itr->second->GetProp().page == this->view.GetPage() && itr->second->Select( rect ) )
			{   //把选择的图元进行删除
				if( this->GetProp().brush.lbStyle == BS_NULL )
				{	//编码
					int s0;
					//单个图元
					char * b0 = itr->second->Encode( s0 , true );
					//组合后的图元
					char * b1 = new char[ size + s0 ];
					//保留原来buffer有的数据
					memcpy( b1 , buffer , size );
					//添加新的数据
					memcpy( b1 + size , b0 , s0 );
					//清除旧的缓冲区
					delete []buffer;
					//单个图元的内存也要删除
					delete []b0;
					
					buffer = b1;
					
					size += s0;
					
					delete itr->second;
					
					itr = dmap.erase( itr );
				}
				else //纯粹的选择
				{
					CRgn r;

					CRect rc( itr->second->GetProp().start , itr->second->GetProp().end );

					rc.NormalizeRect();
					//保存图元所在的最大矩形空间
					if( rc.left == rc.right ) rc.right ++;

					if( rc.top == rc.bottom ) rc.bottom ++;

					r.CreateRectRgn( rc.left , rc.top , rc.right , rc.bottom );
					
					this->rgn.CombineRgn( &this->rgn , &r , RGN_OR );
                    
					itr ++;
				}
			}
			else 

				itr ++;
		}
	}//图元移动过,发送移动数据到外部程序
	else if( this->GetProp().brush.lbStyle != BS_NULL )
	{
		for( DRAW_MAP::iterator itr = dmap.begin(); itr != dmap.end(); itr++ )
		
			if( itr->second->IsSelect() )
			{	//编码
				int s0;
				//单个图元
				char * b0 = itr->second->Encode( s0 , false );
				//组合后的图元
				char * b1 = new char[ size + s0 ];
				//保留原来buffer有的数据
				memcpy( b1 , buffer , size );
				//添加新的数据
				memcpy( b1 + size , b0 , s0 );
				//清除旧的缓冲区
				delete []buffer;
				//清除组合后的图元内存
				delete []b0;
				
				buffer = b1;
				
				size += s0;
			}
	}//根据选中的图元创建一个位图
	this->CreateBitmap();

	if( size == 2 ) 
	{
		delete []buffer; 
		
		buffer = NULL;
		
		size = 0;
	}
	this->draw.start.x = this->draw.end.x = 0;

	this->draw.start.y = this->draw.end.y = 0;

	return buffer;
}

bool CSelect::Decode( char * buffer , int size )
{
	char * id;

	int s;

	DRAW_MAP::iterator itr;
	//删除
	if( buffer[ 1 ] )
	{	//定位到图元id位置
		s = 2 * sizeof( char );

		buffer += s;

		size -= s;

		while( size > 0 )
		{	//图元id
			id = buffer;
			//查找图元,找到则删除
			if( ( itr = this->view.GetDrawMap().find( id ) ) != this->view.GetDrawMap().end() )
			{
				delete itr->second;

				this->view.GetDrawMap().erase( itr );
			}//移动到下一个图元
			s = strlen( id ) + 1;
			
			buffer += s;

			size -= s;
		}
	}//修改
	else
	{	//定位到图元id位置
		s = 2 * sizeof( char );
		
		buffer += s;

		size -= s;

		while( size > 0 )
		{	//图元id
			id = buffer; 
			//图元id的长度
			s = strlen( id ) + 1;
			//定位到图元属性
			buffer += s;

			size -= s;
			//查找图元,找到则替换属性
			if( ( itr = this->view.GetDrawMap().find( id ) ) != this->view.GetDrawMap().end() )

				memcpy( &itr->second->GetProp() , buffer , sizeof( DRAW ) );
			 //属性值大小
			 s = sizeof( DRAW );
			 //偏移属性
			 buffer += s;

			size -= s;
		}
	}
	return true;
}

void CSelect::CreateBitmap( void )
{
	CRect rc;

	this->rgn.GetRgnBox( &rc );

	if( this->GetProp().brush.lbStyle != BS_NULL && this->rgn.GetSafeHandle() && this->rgn.GetRgnBox( &rc ) != NULLREGION )
	{	//10是线条的最大宽度
		rc.InflateRect( 10 , 10 , 10 , 10 );

		if( this->bitmap.GetSafeHandle() ) this->bitmap.DeleteObject();

		CClientDC dc( &this->view );

		CDC memDC;
		
		memDC.CreateCompatibleDC( &dc );
		
		this->bitmap.CreateCompatibleBitmap( &dc , rc.Width() , rc.Height() );
		
		memDC.SelectObject( &this->bitmap );
		
		memDC.FillSolidRect( 0 , 0 , rc.Width() , rc.Height() , memDC.GetBkColor() );
		//在选中的位图中显示被选中的图元
		for( DRAW_MAP::iterator itr = this->view.GetDrawMap().begin(); itr != this->view.GetDrawMap().end(); itr ++ )
		{
			if( itr->second->IsSelect() )
			{
				itr->second->GetProp().start.x -= rc.left; itr->second->GetProp().start.y -= rc.top;

				itr->second->GetProp().end.x -= rc.left; itr->second->GetProp().end.y -= rc.top;

				itr->second->OnDraw( &memDC );

				itr->second->GetProp().start.x += rc.left; itr->second->GetProp().start.y += rc.top;

				itr->second->GetProp().end.x += rc.left; itr->second->GetProp().end.y += rc.top;
			}
		}//位图起点
		this->bitmap_point = rc.TopLeft();
	}
}

void CSelect::OnLButtonDown( UINT nFlags, CPoint point )
{
	CDrawBase::OnLButtonDown( nFlags , point );
	
	if( this->rgn.GetSafeHandle() && ! this->rgn.PtInRegion( point ) )
	{	//删除区域
		this->rgn.DeleteObject(); 
		//删除选中的位图
		if( this->bitmap.GetSafeHandle() ) this->bitmap.DeleteObject();

		DRAW_MAP & dmap = this->view.GetDrawMap();
		
		for( DRAW_MAP::iterator itr = dmap.begin(); itr != dmap.end(); itr ++ )
		
			itr->second->Select( CRect( this->draw.start , this->draw.end ) );
		//刷新
		this->view.Invalidate();
	}
}

void CSelect::OnMouseMove( UINT nFlags, CPoint point )
{	//设定鼠标形状
	if(  this->rgn.GetSafeHandle( ) )
	{
		HCURSOR hCursor = ::AfxGetApp( )->LoadStandardCursor( MAKEINTRESOURCE( this->rgn.PtInRegion( point ) ? IDC_SIZEALL : IDC_ARROW ) );

		::SetClassLong( this->view.GetSafeHwnd( ) , GCL_HCURSOR , ( long )hCursor );
	}
	if( ( nFlags & MK_LBUTTON ) && this->rgn.GetSafeHandle() )
	{
		CPoint pt = point - this->GetProp().end;

		this->GetProp().end = point;

		this->bitmap_point.Offset( pt );
		
		this->view.Invalidate();
	}
	else

		CDrawBase::OnMouseMove( nFlags , point );
}

void CSelect::OnLButtonUp( UINT nFlags, CPoint point )
{
	if( this->rgn.GetSafeHandle() )
	{
		CRect rc;

		this->rgn.GetRgnBox( &rc );

		CPoint offset = this->bitmap_point - rc.TopLeft();
		//增加位图和鼠标位置的误差CPoint(10,10)
		offset.Offset( 10 , 10 );

		this->rgn.OffsetRgn( offset );

		for( DRAW_MAP::iterator itr = this->view.GetDrawMap().begin(); itr != this->view.GetDrawMap().end(); itr ++ )
		{
			if( itr->second->IsSelect())
			{
				itr->second->GetProp().start.x += offset.x; itr->second->GetProp().start.y += offset.y;

				itr->second->GetProp().end.x += offset.x; itr->second->GetProp().end.y += offset.y;
			}
		}
	}
}

⌨️ 快捷键说明

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