11.6.3 截图功能的设计与实现(1)
在实现了复制桌面图像到窗体背景后,用户便可以在窗体上选取合适的区域进行截图。选取区域需要借助橡皮筋,因此截图功能首先需要实现的就是绘制橡皮筋框。
- 01 void CCatchDlg::OnPaint()
- 02 {
- 03 CPaintDC dc(this);
- 04 if(m_bShowMsg&&m_bFirstDraw)
- 05 {//显示截取矩形大小信息
- 06 CRect rect;
- 07 m_rectTracker.GetTrueRect(&rect);
- 08 SetMessage(rect);
- 09 }
- 10 if(m_bFirstDraw)
- 11 {//画出橡皮筋矩形
- 12 m_rectTracker.Draw(&dc);
- 13 }
- 14 }
【代码解析】
在窗体的OnPaint()函数的第12行实现了绘制橡皮筋框的功能。而在这个函数的第4~9行实现了显示橡皮筋框信息的功能。在第7行获取橡皮筋框的大小信息,然后在第8行将橡皮筋框的大小作为参数调用自定义函数SetMessage()。SetMessage()函数实现了在绘制、拖动、缩放橡皮筋框时,提示橡皮筋框的大小及位置的功能,实现如下:
- 01 void CCatchDlg::SetMessage(CRect dRect)
- 02 {
- 03 CClientDC dc(this);
- 04 CPoint pt;
- 05 GetCursorPos(&pt); //获取鼠标位置
- 06 const int space=3; //截取矩形大小信息离鼠标间隔
- 07 CPen pen(PS_SOLID,1,RGB(147,147,147));
- 08 dc.SetTextColor(RGB(147,147,147)); //设置字体颜色大小
- 09 CFont font;
- 10 font.Create PointFont(90,"宋体");
- 11 dc.SelectObject(&font); //将字体选入设备
- 12 dc.SetBkMode(TRANSPARENT);
- 13 TEXTMETRIC tm;
- 14 int charHeight;
- 15 CSize size;
- 16 int lineLength;
- 17 dc.GetTextMetrics(&tm);
- 18 charHeight = tm.tmHeight+tm.tmExternalLeading; //得到字体高度
- 19 size=dc.GetTextExtent("顶点位置 ",strlen("顶点位置 "));
- 20 lineLength=size.cx;
- 21 //初始化矩形,以保证写下6行文字
- 22 CRect rect(pt.x+space,pt.y-charHeight*6-space,pt.x+lineLength+
- space,pt.y-space);
- 23 int x = GetDeviceCaps(dc, HORZRES);
- 24 int y = GetDeviceCaps(dc, VERTRES);
- 25 CRect rectTemp;
- 26 //当矩形到达桌面边缘时调整方向和大小
- 27 if((pt.x+rect.Width())>=x) //桌面上方不能显示完整矩形
- 28 {
- 29 rectrectTemp=rect;
- 30 rectrectTemp.left=rect.left-rect.Width()-space*2;
- 31 rectrectTemp.right=rect.right-rect.Width()-space*2;;
- 32 rect=rectTemp;
- 33 }
- 34 if((pt.y-rect.Height())<=0) //桌面右方不能显示完整矩形
- 35 {
- 36 rectrectTemp=rect;
- 37 rectrectTemp.top=rect.top+rect.Height()+space*2;;
- 38 rectrectTemp.bottom=rect.bottom+rect.Height()+space*2;;
- 39 rect=rectTemp;
- 40 }
- 41 dc.SelectObject((HBRUSH)GetStockObject(NULL_BRUSH));
- 42 dc.Rectangle(rect); //创建空画刷画矩形
- 43 rect.top+=2;
- 44 CString string(" 顶点位置 ");
- 45 dc.TextOut(rect.left,rect.top,string); //在矩形中显示文字
- 46 string.Format(" (%d,%d)",dRect.left,dRect.top);
- 47 dc.TextOut(rect.left,rect.top+charHeight,string); //显示顶点位置
- 48 string=" 矩形大小 ";
- 49 dc.TextOut(rect.left,rect.top+charHeight*2,string);
- 50 string.Format(" (%d,%d)",dRect.Width(),dRect.Height());
- 51 dc.TextOut(rect.left,rect.top+charHeight*3,string);
- //显示橡皮筋大小
- 52 string=" 光标坐标 ";
- 53 dc.TextOut(rect.left,rect.top+charHeight*4,string);
- 54 string.Format(" (%d,%d)",pt.x,pt.y);
- 55 dc.TextOut(rect.left,rect.top+charHeight*5,string);
- //显示当前光标位置
- 56 }
【代码解析】
第5、6行获取当前鼠标的位置。第9~11行设置当前设备环境字体大小及颜色。第12行将设备字体背景色设置为透明。第14~18行获取当前设备字体的高度及宽度。第22行定义一个矩形,在这个矩形中将要显示第6行信息,每行信息6个字符宽度。第23、24行获取屏幕的高度及宽度(像素)。在第27行判断当前橡皮筋框到屏幕左边之间的距离,是否满足显示信息的长度,当不能满足时,在第29~32行将信息框显示到橡皮筋框内部。同理,在第34行判断橡皮筋框及屏幕下边框之间的距离是否能够现实第6行信息数据,不能时,在第36~39行将信息显示到橡皮筋框的内部。第41、42行用空画刷绘制显示信息的矩形。第46、47行在矩形内显示橡皮筋框的顶点信息,第48~51行显示橡皮筋的大小信息,第52~55行显示当前鼠标光标的坐标(即橡皮筋框左下角顶点坐标)。
用户需要通过鼠标动作来实现绘制、拖动及缩放橡皮筋框,这3个动作都是通过鼠标左键来实现的,因此需要重载鼠标左键事件。