📄 select.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 + -