您的位置:首页 > 其它

GDI+绘制矩形,并且实现可旋转、缩放、移动功能(基于MFC对话框)

2017-11-08 15:19 531 查看
1、绘制矩形

创建一个绘制矩形的函数,本次是用绘制多边形的函数定义的,定义绘制四条变的矩形区域。

先进行函数声明:

void DrawRectangle1(Gdiplus::Point rectangle_points[], CPoint oript, CPoint detpt)


然后定义函数(selected_rect_是之前定义了一个矩形框,使画的东西在框的区域内):

void CdrawtestDlg::DrawRectangle1Gdiplus(Gdiplus::Point rectangle_points[], CPoint oript, CPoint detpt){
if (!(oript.x >= selected_rect_.left && oript.x <= selected_rect_.right && oript.y > selected_rect_.top && oript.y < selected_rect_.bottom)) {
return;
}
if (!(detpt.x >= selected_rect_.left && detpt.x <= selected_rect_.right && detpt.y > selected_rect_.top && detpt.y < selected_rect_.bottom)) {
return;
}
if (drawing_mode_ == deawingrectangle) {
rectangle_points[0] = Gdiplus::Point(oript.x, oript.y);
rectangle_points[1] = Gdiplus::Point(detpt.x, oript.y);
rectangle_points[2] = Gdiplus::Point(detpt.x, detpt.y);
rectangle_points[3] = Gdiplus::Point(oript.x, detpt.y);
InvalidateRect(selected_rect_, false);
}
}


 定义变量:

/*矩形定义*/
BOOL is_selected;//是否选中
BOOL is_select;//是否选中
BOOL is_scale;//是否缩放
BOOL is_move;//是否移动


并初始化为FALSE,在对话框点击绘制按钮那响应为TURE。

在ONPaint函数中添加以下代码:

if (drawing_mode_==deawingrectangle||is_move||is_scale)

{

g.DrawPolygon(&pen3,rectangle_point_,4);

}

添加消息响应函数鼠标左键按下的响应,并添加以下代码:

if (draw_mode_ == rectangle) {
drawing_mode_ = deawingrectangle;
rectangle_point_[0].X = point.x;
rectangle_point_[0].Y = point.y;
rectangle_point_[1].X = point.x;
rectangle_point_[1].Y = point.y;
rectangle_point_[2].X = point.x;
rectangle_point_[2].Y = point.y;
rectangle_point_[3].X = point.x;
rectangle_point_[3].Y = point.y;

}


添加鼠标移动的响应函数并编辑:

if (drawing_mode_ == deawingrectangle) {
SetCursor(h_cur_);
DrawRectangle1Gdiplus(rectangle_point_, CPoint(rectangle_point_[0].X, rectangle_point_[0].Y), point);

}


添加鼠标抬起响应函数:

if (drawing_mode_ == deawingrectangle) {
Gdiplus::GraphicsPath gpath_rectangle;
temp_path.AddPolygon(rectangle_point_, 4);
temp_path.AddPath(&gpath_rectangle, FALSE);
gpath_rectangle.Reset();
InvalidateRect(selected_rect_, false);
drawing_mode_ = invalid;
}


这样就可以画矩形了,效果如下:



 

2、添加旋转、缩放并且移动

主要是要跟随鼠标移动进行旋转

首先我们要绘制标志点,当选中标志点的时候矩形旋转

所以在鼠标左键按下的响应函数添加以下代码:

void CdrawtestDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (is_draw)
{
if (draw_mode_==arrow)
{
drawing_mode_=drawingarrow;
arrow_points_[0].X = point.x;
arrow_points_[0].Y = point.y;
arrow_points_[1].X = point.x;
arrow_points_[1].Y = point.y;

11a60
arrow_points_[2].X = point.x;
arrow_points_[2].Y = point.y;
arrow_points_[3].X = point.x;
arrow_points_[3].Y = point.y;
arrow_points_[4].X = point.x;
arrow_points_[4].Y = point.y;
arrow_points_[5].X = point.x;
arrow_points_[5].Y = point.y;

}
if (draw_mode_ == line) {
start_pt_ = point;
drawing_mode_ = drawingline;
}
if (draw_mode_ == rectangle) { drawing_mode_ = deawingrectangle; rectangle_point_[0].X = point.x; rectangle_point_[0].Y = point.y; rectangle_point_[1].X = point.x; rectangle_point_[1].Y = point.y; rectangle_point_[2].X = point.x; rectangle_point_[2].Y = point.y; rectangle_point_[3].X = point.x; rectangle_point_[3].Y = point.y; }
if (draw_mode_ == ellipse) {
drawing_mode_ = drawingellipse;
start_pt_ = old_pt_ = point;
}

}

if (is_selected)
{
Graphics graphics(this->m_hWnd); //构造环境变量指针
Point testPoint(point.x,point.y);//鼠标坐标
Point TestPoint((rectangle_point_[0].X+rectangle_point_[1].X)/2-3,(rectangle_point_[0].Y+rectangle_point_[1].Y)/2-53);//选择坐标
SolidBrush solidBrush(Color(0,0,0,0));
SolidBrush brush1(Color(0,0,0));
Pen pen(Color(255,0,0,0));
GraphicsPath path; //定义路径

/***********************此部分为选中为矩形区域***************************************************************************/
//构造矩形区域
path.AddClosedCurve(rectangle_point_,4); //链接区域
Region pathRegion(&path); //区域指向路径
graphics.FillRegion(&solidBrush,&pathRegion); //填充区域

if (pathRegion.IsVisible(testPoint,&graphics))//如果在选择区域是矩形
{

INT count=path.GetPointCount();
Point* dataPoints=new Point[count];
for (INT j=0;j<count;j++)
{
graphics.FillEllipse(
&brush1,
dataPoints[j].X-3.0f,
dataPoints[j].Y-3.0f,
6.0f,
6.0f
);
//选中标志
graphics.FillEllipse(&brush1,rectangle_point_[0].X-10,rectangle_point_[0].Y-10,6,6);
graphics.FillEllipse(&brush1,rectangle_point_[1].X+10,rectangle_point_[1].Y-10,6,6);
graphics.FillEllipse(&brush1,rectangle_point_[2].X+10,rectangle_point_[2].Y+10,6,6);
graphics.FillEllipse(&brush1,rectangle_point_[3].X-10,rectangle_point_[3].Y+10,6,6);

}
//画选中的把把
PointF point1((rectangle_point_[0].X+rectangle_point_[1].X)/2,(rectangle_point_[0].Y+rectangle_point_[1].Y)/2);
PointF point2((rectangle_point_[0].X+rectangle_point_[1].X)/2,(rectangle_point_[0].Y+rectangle_point_[1].Y)/2-50);
PointF points[2]={point1,point2};
PointF* pPoints=points;
graphics.DrawLine(&pen,point1.X,point1.Y,point2.X,point2.Y);
graphics.FillEllipse(&brush1,(rectangle_point_[0].X+rectangle_point_[1].X)/2-3,(rectangle_point_[0].Y+rectangle_point_[1].Y)/2-53,6,6);

//画选中的中心点
StartPoint.X = rectangle_point_[0].X;
StartPoint.Y = rectangle_point_[0].Y;
EndPoint.X = point.x;
EndPoint.Y = point.y;
C.X=(rectangle_point_[0].X+rectangle_point_[1].X)/2;
C.Y=(rectangle_point_[0].Y+rectangle_point_[3].Y)/2;
graphics.DrawLine(&pen,C.X,C.Y-3,C.X,C.Y+3);
graphics.DrawLine(&pen,C.X-3,C.Y,C.X+3,C.Y);

//初始化缩放坐标点
rectangle_Spoint_[0].X=rectangle_point_[0].X;
rectangle_Spoint_[0].Y=rectangle_point_[0].Y;
rectangle_Spoint_[1].X=rectangle_point_[1].X;
rectangle_Spoint_[1].Y=rectangle_point_[1].Y;
rectangle_Spoint_[2].X=rectangle_point_[2].X;
rectangle_Spoint_[2].Y=rectangle_point_[2].Y;
rectangle_Spoint_[3].X=rectangle_point_[3].X;
rectangle_Spoint_[3].Y=rectangle_point_[3].Y;

//选中中心点
if (C.X-5<point.x && point.x<C.X+5)
{
if (C.Y-5< point.y && point.y<C.Y+5)
{
graphics.FillEllipse(&brush1,C.X-5,C.Y-5,10,10);
is_move = TRUE;
}
}

is_scale=TRUE;//只要在选中去内左键点过,就可以实现缩放功能
}

//testPoint为鼠标坐标,TestPoint为测试坐标,是否选中(粑粑)标志点
else
if(((rectangle_point_[0].X+rectangle_point_[1].X)/2-13) < point.x && point.x<((rectangle_point_[0].X+rectangle_point_[1].X)/2+7)){

if (((rectangle_point_[0].Y+rectangle_point_[1].Y)/2-63)< point.y && point.y<((rectangle_point_[0].Y+rectangle_point_[1].Y)/2-43))
{
graphics.FillEllipse(&brush1,(rectangle_point_[0].X+rectangle_point_[1].X)/2-7,(rectangle_point_[0].Y+rectangle_point_[1].Y)/2-55,15,15);
is_select=TRUE;
}}

else
return;
}

CDialogEx::OnLButtonDown(nFlags, point);
}


在鼠标移动添加以下代码:

void CdrawtestDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
GraphicsPath temp_path;
if (is_draw)
{
if (drawing_mode_ == drawingline) {
SetCursor(h_cur_);
DrawLine(start_pt_, point);
start_pt_ = point;
}
if (drawing_mode_ == drawingarrow) {
SetCursor(h_cur_);
DrawArrow(arrow_points_, CPoint(arrow_points_[0].X, arrow_points_[0].Y), point);
}
if (drawing_mode_ == deawingrectangle) { SetCursor(h_cur_); DrawRectangle1Gdiplus(rectangle_point_, CPoint(rectangle_point_[0].X, rectangle_point_[0].Y), point); }
if (drawing_mode_ == drawingellipse) {
SetCursor(h_cur_);
old_pt_ = point;
DrawEclipse(start_pt_, point);

}
}
if (is_selected)
{
if (is_select)
{
Graphics graphics(this->m_hWnd);
Pen pen(Color(255,0,0,0));
SetCursor(h_move_);
DrawRectangle1Gdiplus(rectangle_point_, CPoint(rectangle_point_[0].X, rectangle_point_[0].Y), point);
StartPoint.X = rectangle_point_[0].X;
StartPoint.Y = rectangle_point_[0].Y;
EndPoint.X = point.x;
EndPoint.Y = point.y;
C.X=(rectangle_point_[0].X+rectangle_point_[1].X)/2;
C.Y=(rectangle_point_[0].Y+rectangle_point_[3].Y)/2;
float theta =atan2f(EndPoint.X-C.X,EndPoint.Y-C.Y);

double R,B;
R=sqrt((double)(C.Y-rectangle_point_[0].Y)*(C.Y-rectangle_point_[0].Y)+(double)(C.X-rectangle_point_[0].X)*(C.X-rectangle_point_[0].X));
B=sin(theta/2)*2*R;

//绘制中间选中标志点
graphics.DrawLine(&pen,C.X,C.Y-3,C.X,C.Y+3);
graphics.DrawLine(&pen,C.X-3,C.Y,C.X+3,C.Y);

////旋转变换成菱形了~~~T-T~~~~
rectangle_points_[0].X=(rectangle_point_[0].X-C.X)*cos(theta)-(rectangle_point_[0].Y-C.Y)*sin(theta)+C.X;
rectangle_points_[0].Y=(rectangle_point_[0].X-C.X)*sin(theta)-(rectangle_point_[0].Y-C.Y)*cos(theta)+C.Y;

rectangle_points_[1].X=(rectangle_point_[1].X-C.X)*cos(theta)-(rectangle_point_[1].Y-C.Y)*sin(theta)+C.X;
rectangle_points_[1].Y=(rectangle_point_[1].X-C.X)*sin(theta)-(rectangle_point_[1].Y-C.Y)*cos(theta)+C.Y;

rectangle_points_[2].X=(rectangle_point_[2].X-C.X)*cos(theta)-(rectangle_point_[2].Y-C.Y)*sin(theta)+C.X;
rectangle_points_[2].Y=(rectangle_point_[2].X-C.X)*sin(theta)-(rectangle_point_[2].Y-C.Y)*cos(theta)+C.Y;

rectangle_points_[3].X=(rectangle_point_[3].X-C.X)*cos(theta)-(rectangle_point_[3].Y-C.Y)*sin(theta)+C.X;
rectangle_points_[3].Y=(rectangle_point_[3].X-C.X)*sin(theta)-(rectangle_point_[3].Y-C.Y)*cos(theta)+C.Y;

graphics.DrawLine(&pen,rectangle_points_[0].X,rectangle_points_[0].Y,rectangle_points_[2].X,rectangle_points_[2].Y);
graphics.DrawLine(&pen,rectangle_points_[1].X,rectangle_points_[1].Y,rectangle_points_[3].X,rectangle_points_[3].Y);

Gdiplus::GraphicsPath gpath_rectangle1;
temp_path.AddPolygon(rectangle_points_, 4);
temp_path.AddPath(&gpath_rectangle1, FALSE);
gpath_rectangle1.Reset();
InvalidateRect(selected_rect_, false);
drawing_mode_ = invalid;

}

if (is_move)//移动代码
{
SetCursor(h_move_);
DrawRectangle1Gdiplus(rectangle_point_, CPoint(rectangle_point_[0].X, rectangle_point_[0].Y), point);
StartPoint.X = rectangle_point_[0].X;
StartPoint.Y = rectangle_point_[0].Y;
EndPoint.X = point.x;
EndPoint.Y = point.y;
double dx,dy;
dx=EndPoint.X-StartPoint.X;
dy=EndPoint.Y-StartPoint.Y;

rectangle_point_[0].X=rectangle_point_[0].X+dx;
rectangle_point_[0].Y=rectangle_point_[0].Y+dy;
rectangle_point_[1].X=rectangle_point_[1].X+dx;
rectangle_point_[1].Y=rectangle_point_[1].Y+dy;
rectangle_point_[2].X=rectangle_point_[2].X+dx;
rectangle_point_[2].Y=rectangle_point_[2].Y+dy;
rectangle_point_[3].X=rectangle_point_[3].X+dx;
rectangle_point_[3].Y=rectangle_point_[3].Y+dy;

Gdiplus::GraphicsPath gpath_rectangle;
temp_path.AddPolygon(rectangle_point_, 4);
temp_path.AddPath(&gpath_rectangle, FALSE);
gpath_rectangle.Reset();
InvalidateRect(selected_rect_, false);
drawing_mode_ = invalid;

}

}


在鼠标抬起添加以下代码:

void CdrawtestDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
GraphicsPath temp_path;
if (is_draw)
{
if (drawing_mode_==drawingline)
{
drawing_mode_=invalid;
temp_path.AddPath(gpath_line_,FALSE);
gpath_line_->Reset();
}
if (drawing_mode_ == drawingarrow) {
GraphicsPath temp_arrow_path;
temp_arrow_path.AddPolygon(arrow_points_, 6);
InvalidateRect(selected_rect_, false);
drawing_mode_ = invalid;
vec_arrow_drawcwlls_.push_back(DrawCell(pen_color_, pen_width_, &temp_arrow_path));
}
if (drawing_mode_ == deawingrectangle) { Gdiplus::GraphicsPath gpath_rectangle; temp_path.AddPolygon(rectangle_point_, 4); temp_path.AddPath(&gpath_rectangle, FALSE); gpath_rectangle.Reset(); InvalidateRect(selected_rect_, false); drawing_mode_ = invalid; }
if (drawing_mode_ == drawingellipse) {
temp_path.AddEllipse(Rect(start_pt_.x, start_pt_.y, old_pt_.x - start_pt_.x, old_pt_.y - start_pt_.y));
InvalidateRect(selected_rect_, false);
drawing_mode_ = invalid;
}
vec_drawcells_.push_back(DrawCell(pen_color_, pen_width_, &temp_path));
}
if (is_selected)
{
if (is_move||is_scale||is_select)
{
Gdiplus::GraphicsPath gpath_rectangle;
temp_path.AddPolygon(rectangle_point_, 4);
temp_path.AddPath(&gpath_rectangle, FALSE);
gpath_rectangle.Reset();
InvalidateRect(selected_rect_, false);
drawing_mode_ = invalid;
}

if (is_Emove)
{
/*temp_path.AddEllipse(Rect(start_pt_.x, start_pt_.y, old_pt_.x - start_pt_.x, old_pt_.y - start_pt_.y));
InvalidateRect(selected_rect_, false);
drawing_mode_ = invalid;*/
}

}

CDialogEx::OnLButtonUp(nFlags, point);
}


并添加滚轮响应实现鼠标控制缩放:

BOOL CdrawtestDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
GraphicsPath temp_path;

if (is_scale)
{

if (zDelta>0)//向上滚
{

rectangle_point_[0].X=rectangle_point_[0].X-5;
rectangle_point_[0].Y=rectangle_point_[0].Y-5;
rectangle_point_[1].X=rectangle_point_[1].X+5;
rectangle_point_[1].Y=rectangle_point_[1].Y-5;
rectangle_point_[2].X=rectangle_point_[2].X+5;
rectangle_point_[2].Y=rectangle_point_[2].Y+5;
rectangle_point_[3].X=rectangle_point_[3].X-5;
rectangle_point_[3].Y=rectangle_point_[3].Y+5;

}
if (zDelta<0)//向下滚
{
//测试代码
rectangle_point_[0].X=rectangle_point_[0].X+5;
rectangle_point_[0].Y=rectangle_point_[0].Y+5;
rectangle_point_[1].X=rectangle_point_[1].X-5;
rectangle_point_[1].Y=rectangle_point_[1].Y+5;
rectangle_point_[2].X=rectangle_point_[2].X-5;
rectangle_point_[2].Y=rectangle_point_[2].Y-5;
rectangle_point_[3].X=rectangle_point_[3].X+5;
rectangle_point_[3].Y=rectangle_point_[3].Y-5;

}

}

return CDialogEx::OnMouseWheel(nFlags, zDelta, pt);
}


好了,这样就可以实现鼠标控制移动,缩放,旋转的功能!

程序下载链接:
http://download.csdn.net/download/weixin_38002417/10109488
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐