11.6.3 截图功能的设计与实现(2)
(1)开始绘制橡皮筋框、拖动及缩放橡皮筋框都需要先按下鼠标左键。因此需要首先重载鼠标左键按下事件。
- 01 void CCatchDlg::OnLButtonDown(UINT nFlags, CPoint point)
- 02 {
- 03 int nHitTest;
- 04 nHitTest=m_rectTracker.HitTest(point); //获取鼠标与橡皮筋框的位置关系
- 05 m_bShowMsg=TRUE; //是否显示信息
- 06 UpdateWindow();
- 07 if(nHitTest<0)
- 08 {//判断击中位置
- 09 if(!m_bFirstDraw)
- 10 {
- 11 m_startPt=point;
- 12 m_bDraw=TRUE;
- 13 m_bFirstDraw=TRUE;
- 14 SetTip(); //显示提示信息
- 15 UpdateWindow();
- 16 }
- 17 }
- 18 else
- 19 {
- 20 if(m_bFirstDraw)
- 21 { //第一次绘制橡皮筋框
- 22 m_rectTracker.Track(this,point,TRUE);
- 23 SendMessage(WM_LBUTTONUP,NULL,NULL);
- 24 UpdateWindow();
- 25 }
- 26 }
- 27 CDialog::OnLButtonDown(nFlags, point);
- 28 }
【代码解析】
第3、4行获取鼠标按下位置与橡皮筋框之间的关系。第7行判断鼠标按下位置是否在橡皮筋框上活橡皮筋框内,否则在第9行判断是否第一次绘制橡皮筋框,如是则在第11行记录橡皮筋框的起始点,在第13行标识已经开始绘制橡皮筋框,并在第14行显示提示信息。如果鼠标按下位置不在橡皮筋框上及橡皮筋框内,则开始绘制橡皮筋框,并发送抬起鼠标左键的消息。
UpdateWindow()函数是自定义函数,其刷新了除信息编辑框之外的所有区域。实现如下:
- 01 void CCatchDlg::UpdateWindow()
- 02 {
- 03 CRect rect1;
- 04 GetWindowRect(rect1); //获取当前全屏对话框窗口大小
- 05 CRect rect2;
- 06 m_eTip.GetWindowRect(rect2); //获取编辑框窗口大小
- 07 CRgn rgn,rgn1,rgn2;
- 08 rgn.CreateRectRgn(0,0,50,50);
- 09 rgn1.CreateRectRgnIndirect(rect1);
- 10 rgn2.CreateRectRgnIndirect(rect2);
- 11 rgn.CombineRgn(&rgn1,&rgn2,RGN_DIFF); //获取更新区域,但编辑框窗口除外
- 12 InvalidateRgn(&rgn);
- 13 }
【代码解析】
第3、4行获取当前窗体区域,第5、6行获取消息编辑框的大小。第7~10行获取这两个区域的补集,即主窗体中除去消息编辑框外的区域。第12行刷新这个补集区域。
(2)鼠标左键按下后,需要移动鼠标才能够实现编辑框的绘制、拖动及缩放功能。因此还需要重载鼠标移动处理函数。
- 01 void CCatchDlg::OnMouseMove(UINT nFlags, CPoint point)
- 02 {
- 03 if(m_bDraw)
- 04 { //是否已经绘制橡皮筋框
- 05 m_rectTracker.m_rect.SetRect(m_startPt.x+1, m_startPt.y+1,
- point.x,point.y);
- 06 m_bFirstDraw=TRUE;
- 07 UpdateWindow();
- 08 }
- 09 modifyColor();
- 10 CDialog::OnMouseMove(nFlags, point);
- 11 }