绘图

用不同方法在不同窗口中绘制线条

 复制代码
void CMyView::OnLButtonUp(UINT nFlags, CPoint point) 
{
    // TODO: Add your message handler code here and/or call default
    //MessageBox("WM_LBUTTONUP");
    // 
    // 1:利用SDK全局函数实现画线功能
    // 
    HDC hdc;
    hdc = ::GetDC(m_hWnd);
    ::MoveToEx(hdc,m_ptOld.x,m_ptOld.y,NULL);
    ::LineTo(hdc,point.x,point.y);
    ::ReleaseDC(m_hWnd,hdc);

    // 2:利用MFC的CDC类实现画线功能
    // 
    CDC *pDC = GetDC();
    pDC->MoveTo(m_ptOld);
    pDC->LineTo(point);
    ReleaseDC(pDC);

    // 3:利用MFC的CClientDC类实现画线功能
    // 
    CClientDC dc(this);
    dc.MoveTo(m_ptOld);
    dc.LineTo(point);

    // 4:利用MFC的CWindowDC类实现画线功能
    // 
    CWindowDC dc_2(this);
    dc_2.MoveTo(m_ptOld);
    dc_2.LineTo(point);

    // 5:利用MFC的CWindowDC类在父窗口中实现画线功能
    // 
    CWindowDC dc_3(GetParent());
    dc_3.MoveTo(m_ptOld);
    dc_3.LineTo(point);

    // 6:利用MFC的CWindowDC类在桌面窗口中实现画线功能
    // 
    CWindowDC dc_4(GetDesktopWindow());
    dc_4.MoveTo(m_ptOld);
    dc_4.LineTo(point);

    CView::OnLButtonUp(nFlags, point);
}
 

现在来分析上面的代码。

1:首先想想要完成画线这样一个功能该怎么做呢?

从按下鼠标左键开始,移动鼠标至另一位置,松开鼠标左键,整个操作过程就是要PC实现画线的充分条件;PC处理完成后通过显示屏展现结果。到此为止,我们接触的全是硬件(操作的鼠标、看到的屏幕)。难道我们直接和硬件打交道吗?NO!和硬件打交道的是OS,我们只要和OS打交道就行了,OS就是人与机器之间的翻译员。

2:上面代码就是跟OS交流的语言,告诉OS我要干什么,怎么干。然后OS翻译我们的意思给机器,之后机器就把事情干好了。

3:我要操作系统这么做。

 复制代码
    // 1:利用SDK全局函数实现画线功能
    // 
    HDC hdc;//设备上下文句柄
    hdc = ::GetDC(m_hWnd);//把窗口和设备上下文句柄关联起来
    ::MoveToEx(hdc,m_ptOld.x,m_ptOld.y,NULL);//初始化点的位置
    ::LineTo(hdc,point.x,point.y);//移动到这个点
    ::ReleaseDC(m_hWnd,hdc);//释放句柄资源
 

OS把上面的代码翻译成机器代码给机器看,机器一看,哦,这样哦。

4:上面代码中2到6的方法都是依据方法1为基础的。MFC把API函数封装到类中,就造出了CDC,CClientDC...等等这样的类。它们工作原理都差不多,如下:在构造函数中完成窗口与设备上下文句柄的关联工作,在MoveTo中调用API函数MoveTo,在LineTo函数中调用API函数LineTo,具体情况请看源代码。

 
void CMyView::OnLButtonUp(UINT nFlags, CPoint point) 
{
    // TODO: Add your message handler code here and/or call default
    // 设备描述表(Device Context,DC)是一个信息结构体,包含物理输出设备及其驱动程序。
    // 在Windows平台下,所有的的图形操作都是通过它完成。
    //MessageBox("WM_LBUTTONUP");
    // 
    

    // 绘制彩色线条
    // 
    //CPen pen(PS_SOLID,10,RGB(255,0,0));// PS_SOLID实心
    CPen pen(PS_DASH,1,RGB(255,0,0));// PS_DASH虚线,宽度<=1时才有效。
    CClientDC dc(this);
    CPen *pOldPen = dc.SelectObject(&pen);
    dc.MoveTo(m_ptOld);
    dc.LineTo(point);
    dc.SelectObject(pOldPen);

    // 使用画刷绘图
    // 
    CBrush brush(RGB(0,255,0));// 共有4个构造函数
    CBrush *oldBrush;
    oldBrush = dc.SelectObject(&brush);// 先把自己定义的画刷选到设备描述表
    dc.FillRect(CRect(m_ptOld,point),NULL);// 用自己定义的画刷
    //dc.FillRect(CRect(m_ptOld,point),&brush);// 指定画刷
    //dc.FillRect(CRect(m_ptOld,point),NULL);// 系统最初默认的画刷颜色是白色
    
    // 位图画刷
    // 
    CBitmap bitmap;
    bitmap.LoadBitmap(IDB_BITMAP1);
    CBrush brush_2(&bitmap);
    dc.FillRect(CRect(m_ptOld,point),&brush_2);

    // 透明画刷
    // 
    dc.Rectangle(CRect(m_ptOld,point));

    // 画刷句柄转换为画刷对象
    // 
    CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
    oldBrush = dc.SelectObject(pBrush);
    dc.Rectangle(CRect(m_ptOld,point));

    m_bDraw = FALSE;

    CView::OnLButtonUp(nFlags, point);
}
 
 
void CMyView::OnMouseMove(UINT nFlags, CPoint point) 
{
    // TODO: Add your message handler code here and/or call default
    //MessageBox("WM_MOUSEMOVE");
    // 绘制连续线条
    CClientDC dc(this);
    if (TRUE == m_bDraw)
    {
        dc.MoveTo(m_ptOld);
        dc.LineTo(point);
        m_ptOld = point;
    }
    
    CView::OnMouseMove(nFlags, point);
}
 
 
posted @ 2012-05-02 13:16  DaBan  阅读(247)  评论(0编辑  收藏  举报