GDI+绘制矩形,并且实现可旋转、缩放、移动功能(基于MFC对话框)
2017-11-08 15:19
531 查看
1、绘制矩形
创建一个绘制矩形的函数,本次是用绘制多边形的函数定义的,定义绘制四条变的矩形区域。
先进行函数声明:
然后定义函数(selected_rect_是之前定义了一个矩形框,使画的东西在框的区域内):
定义变量:
并初始化为FALSE,在对话框点击绘制按钮那响应为TURE。
在ONPaint函数中添加以下代码:
if (drawing_mode_==deawingrectangle||is_move||is_scale)
{
g.DrawPolygon(&pen3,rectangle_point_,4);
}
添加消息响应函数鼠标左键按下的响应,并添加以下代码:
添加鼠标移动的响应函数并编辑:
添加鼠标抬起响应函数:
这样就可以画矩形了,效果如下:
![](http://images2017.cnblogs.com/blog/1273174/201711/1273174-20171108150615934-787832192.png)
2、添加旋转、缩放并且移动
主要是要跟随鼠标移动进行旋转
首先我们要绘制标志点,当选中标志点的时候矩形旋转
所以在鼠标左键按下的响应函数添加以下代码:
在鼠标移动添加以下代码:
在鼠标抬起添加以下代码:
并添加滚轮响应实现鼠标控制缩放:
好了,这样就可以实现鼠标控制移动,缩放,旋转的功能!
程序下载链接:
http://download.csdn.net/download/weixin_38002417/10109488
创建一个绘制矩形的函数,本次是用绘制多边形的函数定义的,定义绘制四条变的矩形区域。
先进行函数声明:
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; }
这样就可以画矩形了,效果如下:
![](http://images2017.cnblogs.com/blog/1273174/201711/1273174-20171108150615934-787832192.png)
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
相关文章推荐
- 基于mfc的对话框编程中,实现控件随对话框大小自动缩放以及通过滚动条实现控件移动功能
- MFC中基于对话框利用CRectTracker实现多矩形绘制、选择、拉伸、移动和删除
- Silverlight实现对图片的涂鸦、绘制矩形、圆形、直线、文本,并且能够移动
- android 实现图片旋转,移动,缩放,并且记录变化值,用另外一张图片显示出来
- MFC基于对话框的Media Player如何实现全屏显示功能?
- Silverlight实现对图片的涂鸦、绘制矩形、圆形、直线、文本,并且能够移动
- MFC基于对话框,在对话框上插入图像控件,在图像控件上,画一个绿色的矩形,按键盘上下左右键,矩形在图像控件上移动移动。分别创建一个文本文件和一个二进制文件,对话框退出时,文档内写入保存退出前的矩形的位
- 【IOS】扩展UIImageViewEx实现:手势移动,旋转,缩放(附带一个收缩的文字标签功能)
- 基于对话框的MFC应用程序实现菜单的勾选功能
- 【IOS】扩展UIImageViewEx实现:手势移动,旋转,缩放(附带一个收缩的文字标签功能)
- VS2010-MFC:用OpenGL在对话框中的PictureControl(图片控件)中绘制三维模型,可旋转、平移、缩放,可用于三维模型的预览
- MFC单文档结构,实现OpenGL的绘图,移动,旋转,缩放
- MFC GDI+实现以鼠标为中心缩放图片(并且可以拖动)
- 【IOS】扩展UIImageViewEx实现:手势移动,旋转,缩放(附带一个收缩的文字标签功能)
- MFC GDI+实现以鼠标为中心缩放图片(并且可以拖动)
- MFC GDI+实现以鼠标为中心缩放图片(并且可以拖动)
- 【IOS】扩展UIImageViewEx实现:手势移动,旋转,缩放(附带一个收缩的文字标签功能)
- 基于jQuery实现文本框缩放以及上下移动功能
- 【IOS】扩展UIImageViewEx实现:手势移动,旋转,缩放(附带一个收缩的文字标签功能)