C++学习 2019

编程入门 行业动态 更新时间:2024-10-16 02:23:29

C++学习 2019

C++学习 2019

1.继续截屏工具

1.1 考虑将桌面位图用栈来进行存储

1.首先我们是在主窗口中进行保存位图的,因此我们需要在 Frame 类中添加头文件 stack ,并创建一个成员用来存储位图: stack<CBitmap*> btmp_box ;对于这个栈,我们需要在 Frame 的析构函数中循环删除栈中的元素,在构造函数中获取桌面的位图并存储到这个栈中;
2.在构造函数中,我们首先创获取桌面DC: CWindowDC windc(GetDesktopWindow()) ;
3.我们创建一个兼容性DC用来拷贝桌面位图: CDC cmptdc ; cmptdc.CreateCompatibleDC(&windc) ;
4.定义一个空位图对象(用来存放桌面的位图): CBitmap* p_bitmap = new CBitmap ;对于这个位图对象,我们创建其兼容性空位图: p_bitmap->CreateCompatibleBitmap(&windc, m_screen_cx, m_screen_cy) ;其中的 m_screen_cx 与 m_screen_cy 是屏幕的宽和高,可以通过 ::GetSystemMetrics 函数获得;
5.将空位图选择进兼容性DC句柄: cmptdc.SelectObject(p_bitmap) ;
6.将位图拷贝到兼容性DC上(从主DC上往下拿图片,因此是兼容性DC调用的函数): cmptdc.BitBlt(0, 0, m_screen_cx, m_screen_cy, &windc, 0, 0, SRCCOPY) ;
7.将桌面位图压到栈中: btmp_box.push(p_bitmap) ;

CMainFrame::CMainFrame()
{// 1. 获取桌面图片// 1.1 获取桌面的长宽m_screen_cx = ::GetSystemMetrics(SM_CXSCREEN);m_screen_cy = ::GetSystemMetrics(SM_CYSCREEN);// 1.2 获取一张空位图,并将桌面的图放到空位图里CWindowDC windc(GetDesktopWindow());CDC cmptdc;cmptdc.CreateCompatibleDC(&windc);CBitmap *p_bitmap = new CBitmap;p_bitmap->CreateCompatibleBitmap(&windc, m_screen_cx, m_screen_cy);cmptdc.SelectObject(p_bitmap);cmptdc.BitBlt(0, 0, m_screen_cx, m_screen_cy, &windc, 0, 0, SRCCOPY);// 2. 将桌面位图拷贝到栈中btmp_box.push(p_bitmap);
}

1.2 将栈的栈顶位图进行显示

1.首先确定是在 View 类的 OnDraw 函数中进行显示位图的操作;
2.由于会用到 Frame 类的成员 btmp_box ,因此需要首先创建 Frame 的对象: CMainFrame *pFrame = (CMainFrame *)AfxGetMainWnd() ;
3.创建目标DC: CClientDC target_dc(this) ;
4.创建兼容性DC: CDC cdc ; cdc.CreateCompatibleDC(&target_dc) ;
5.选择位图进兼容性DC: cdc.SelectObject(pFrame->btmp_box.top()) ;
6.拷贝操作: target_dc.BitBlt(0, 0, pFrame->m_screen_cx, pFrame->m_screen_cy, &cdc, 0, 0, SRCCOPY) ;

void CShutScreenView::OnDraw(CDC* /*pDC*/)
{CShutScreenDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);if (!pDoc)return;// 3. 对栈顶图片进行显示CMainFrame *pFrame = (CMainFrame *)AfxGetMainWnd();CClientDC target_dc(this);CDC cdc;cdc.CreateCompatibleDC(&target_dc);cdc.SelectObject(pFrame->btmp_box.top());target_dc.BitBlt(0, 0, pFrame->m_screen_cx, pFrame->m_screen_cy, &cdc, 0, 0, SRCCOPY);
}

1.3 给工具条添加按钮

1.首先我们需要在之前只有一个“X”的工具条上继续创建几个图标用于画直线、曲线、三角形、矩形等操作的按钮;
2.我们需要知道四类消息分别会经过哪几个类;
标准消息:先查找子类的消息映射表(若消息存在则执行,否则查找父类的消息映射表),再查找父类的消息映射表,再到更高级的父类的消息映射表
命令消息:消息的流经类的顺序 View->Doc->DocTempture(Doc模版)->Frame->App
控件消息:先查找子窗口的消息映射表,再查找父窗口的消息映射表
自定义消息:查找调用的类的消息映射表
3.其次我们在 View 类中定义一个变量用来记录我们点击的是哪一个工具条的按钮: int m_draw_type ;使用枚举类型表示 m_draw_type : enum {CURVE, LINE, RECTANGLE, TRIANGLE, CIRCLE} ;枚举的顺序由工具条按钮的顺序决定;在 View 类的构造函数里默认为画曲线(int值为0);
4.将工具条按钮的值修改为连续的(我的值从EXIT开始依次为):32771(ID_TOOLBAR_EXIT)、32772(ID_TOOLBAR_CURVE)、32773(ID_TOOLBAR_LINE)、32774(ID_TOOLBAR_RECT)、32775(ID_TOOLBAR_TRIANGLE)、32776(ID_TOOLBAR_CIRCLE) ;
5.更改为连续的之后我们就可以进行批量的操作: ON_COMMAND_RANGE(ID_TOOLBAR_CURVE, ID_TOOLBAR_CIRCLE, &CShutScreenView::OnDrawTypeChange) (第一个参数是起始的ID,第二个参数是结束的ID,第三个参数是处理函数的地址);
6.在 View 类中定义一个批量处理的函数: afx_msg void OnDrawTypeChange(UINT uID) (参数是用来记录传入的是第几个按钮的ID);在函数中进行更改绘图的变量 m_draw_type: m_draw_type = uID - ID_TOOLBAR_CURVE ;

BEGIN_MESSAGE_MAP(CShutScreenView, CView)... ...ON_COMMAND_RANGE(ID_TOOLBAR_CURVE, ID_TOOLBAR_CIRCLE, &CShutScreenView::OnDrawTypeChange)
END_MESSAGE_MAP()enum {CURVE, LINE, RECTANGLE, TRIANGLE, CIRCLE};CShutScreenView::CShutScreenView()
{// 默认为画曲线m_draw_type = CURVE;
}void CShutScreenView::OnDrawTypeChange(UINT uID)
{// 更改画图的样式m_draw_type = uID - ID_TOOLBAR_CURVE;
}

1.4 当按下按钮后进行绘图

1.首先回忆之前我们进行的操作:在 LButtonDown 中标记开始绘图并记录按下鼠标的坐标,在 LButtonUp 中停止绘图,在 OnMouseMove 中进行绘图;
2.给 View 类添加上述三个命令,并添加一个用来标记是否进行绘制的 bool 型变量和一个记录鼠标按下时坐标的 CPoint 变量: bool is_draw ; CPoint pointDown ; is_draw 在 View 的构造里初始化为 false ;
3.在 LButtonDown 函数中记录开始画: pointDown = point ; is_draw = true ;
4.在 LButtonUp 函数中停止画: is_draw = false ;
5.在 OnMouseMove 函数中进行绘制,首先判断一下是否进行画图,若画图则获取DC CClientDC dc(this) ,并判断画的是什么图形(画曲线时需要一直显示,画其他的图形则需要删除之前绘制的,所以大体分为画曲线和画非曲线);
6.画曲线时: dc.MoveTo(pointDown) ; dc.LineTo(point) ; pointDown = point ;
7.画非曲线时使用 switch 语句来进行分割;

void CShutScreenView::OnLButtonDown(UINT nFlags, CPoint point)
{// 记录按下的坐标并画图pointDown = point;is_draw = true;CView::OnLButtonDown(nFlags, point);
}void CShutScreenView::OnLButtonUp(UINT nFlags, CPoint point)
{// 抬起则取消画图is_draw = false;// pointDown = point;CView::OnLButtonUp(nFlags, point);
}void CShutScreenView::OnMouseMove(UINT nFlags, CPoint point)
{// 先判断是否需要进行画图if(is_draw){// 需要画图则进行获取dcCClientDC dc(this);// 画曲线if(m_draw_type == CURVE){CPen pen(PS_DASH, 3, color);			// color = RGB(255, 0, 0),写在了 View 的构造函数中dc.SelectObject(pen);dc.MoveTo(pointDown);dc.LineTo(point);pointDown = point;return;}// 其他画图类型switch (m_draw_type){case LINE:{dc.MoveTo(pointDown);dc.LineTo(point);}break;case RECTANGLE:{dc.SelectStockObject(NULL_BRUSH);dc.Rectangle(pointDown.x, pointDown.y, point.x, point.y);}break;case  TRIANGLE:{POINT pointArr[] = {{(pointDown.x+point.x)/2, pointDown.y},{point.x, point.y},{pointDown.x, point.y}};														// 设置一个三角形的三个角的数组dc.Polygon(pointArr, 3);								// 绘制一个多边形}break;case CIRCLE:{dc.Ellipse(pointDown.x, pointDown.y, point.x, point.y);}break;default:break;}}CView::OnMouseMove(nFlags, point);
}

1.5 在绘制图形的过程中,我们可以选择一种画笔来绘制边框有颜色的图形, CPen pen(PS_DASH, 3, color) ;在使用DC进行选中即可: dc.SelectObject(pen) 。

更多推荐

C++学习 2019

本文发布于:2024-03-05 17:44:56,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1712958.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!