9.MFC绘图

一、MFC绘图

  1.相关问题

    WIN32 - HDC

    MFC - CDC类对象

  2.相关类

   (1)CDC类 - 父类CObject,封装了关于绘图的各种API函数,还封装了成员变量m_hDC(保存绘图设备句柄)

   (2)CDC类的子类

      CClientDC - 封装了在客户区中绘图的绘图设备,::GetDC

      CWindowDC - 封装了在整个窗口中绘图的绘图设备,::GetWindowDC

      CPaintDC - 封装了在WM_PAINT消息中绘图的绘图设备,::BeginPaint

  相关代码:在视图中处理菜单消息,绘图

复制代码
void CT23_MFCCDCView::OnClient()
{
    CClientDC dc(this);
    dc.TextOutW(0, 0, L"MFCCDCView::OnClient");//里面其实调的WIN32函数
    //WIN32实现
    //::TextOut(dc.m_hDC, 100, 100, L"MFCCDCView::OnClient", strlen("MFCCDCView::OnClient"));
}

void CT23_MFCCDCView::OnWindow()
{
    CWindowDC dc(AfxGetApp()->m_pMainWnd);
    dc.TextOutW(10, 330, L"MFCCDCView::OnWindow");//里面其实调的WIN32函数
    //WIN32实现
    //::TextOut(dc.m_hDC, 0, 330, L"MFCCDCView::OnClient", strlen("MFCCDCView::OnClient"));
}

void CT23_MFCCDCView::OnPaint()
{
    CPaintDC dc(this);
    dc.TextOutW(0, 0, L"MFCCDCView::OnPaint");
}
复制代码

  运行结果:

  

   (3)CGDIObjecct - 父类CObject,封装了了成员变量m_hObject(保存了相应GDI绘图对象句柄)

   (4)CGDIObject的子类

      CPen - 封装了画笔的使用

      CBrush - 封装画刷的使用

      CFont - 封装了字体的使用

      CBitmap - 封装了位图的使用

      CRgn - 封装了关于复合(不规则)图形的绘制

        a.将简单基本图像通过运算,构建一个复杂的集合运算

        b.使用

          利用一些列CRgn::CreateXXX,创建基本图形

          利用CRgn::CombineRgn将基本图形通过指明的运算进行组合

          填充复合图形

  相关代码:在视图中处理菜单消息,绘图  

复制代码
void CT24_MFCGDIView::OnBmp()
{
    CClientDC dc(this);
    CBitmap bmp;
    bmp.LoadBitmapW(IDB_BITMAP1);
    //CDC memdc;
    //memdc.CreateCompatibleDC(&dc);
    //CBitmap *oldBmp = memdc.SelectObject(&bmp);
    //dc.BitBlt(100, 100, 48, 48, &memdc, 0, 0, SRCCOPY);
    //memdc.SelectObject(oldBmp);
    //bmp.DeleteObject();
    //memdc.DeleteDC();

    //WIN32实现
    HDC memdc = ::CreateCompatibleDC(dc.m_hDC);
    HGDIOBJ oldBmp = ::SelectObject(memdc, bmp.m_hObject);
    ::BitBlt(dc.m_hDC, 100, 100, 48, 48, memdc, 0, 0, SRCCOPY);
    ::SelectObject(memdc, oldBmp);
    ::DeleteObject(bmp.m_hObject);
    ::DeleteObject(memdc);
}


void CT24_MFCGDIView::OnBrush()
{
    CClientDC dc(this);
    //CBrush brush( RGB(0, 255, 0) );  //实心画刷
    CBrush brush(HS_CROSS, RGB(0, 255, 0));  //虚线画刷
    CBrush *oldBrush = dc.SelectObject(&brush);
    dc.Rectangle(50, 50, 250, 250);
    dc.SelectObject(oldBrush);
    brush.DeleteObject();

    //WIN32实现
    //HGDIOBJ hOldBrush = ::SelectObject(dc.m_hDC, brush.m_hObject);
    //Rectangle(dc.m_hDC, 100, 100, 300, 300);
    //::SelectObject(dc.m_hDC, hOldBrush);
    //brush.DeleteObject();
}


void CT24_MFCGDIView::OnFont()
{
    CClientDC dc(this);
    CFont font;
    font.CreatePointFont(300, L"黑体");
    CFont *oldFont = dc.SelectObject(&font);
    dc.TextOutW(100, 100, L"用黑体字体画");
    dc.SelectObject(oldFont);
    font.DeleteObject();
}


void CT24_MFCGDIView::OnPen()
{
    CClientDC dc( this );
    CPen pen( PS_SOLID, 10, RGB(255,0,0) );
    CPen *oldPen = dc.SelectObject(&pen);
    dc.Rectangle(50, 50, 250, 250);
    dc.SelectObject(oldPen);
    pen.DeleteObject();

    //WIN32实现
    //HGDIOBJ hOldPen = ::SelectObject(dc.m_hDC, pen.m_hObject);
    //Rectangle(dc.m_hDC, 100, 100, 300, 300);
    //::SelectObject(dc.m_hDC, hOldPen);
    //::DeleteObject(pen.m_hObject);
}


void CT24_MFCGDIView::OnRgn()
{
    CRgn rgn1;
    rgn1.CreateEllipticRgn(50, 50, 250, 250);
    CRgn rgn2;
    rgn2.CreateEllipticRgn(150, 150, 350, 350);
    //rgn1.CombineRgn(&rgn1, &rgn2, RGN_AND);  //rgn1此时代表复合图形
    //rgn1.CombineRgn(&rgn1, &rgn2, RGN_OR);
    rgn1.CombineRgn(&rgn1, &rgn2, RGN_XOR);
    CBrush brush(RGB(0,255,0));
    CClientDC dc(this);
    dc.FillRgn(&rgn1, &brush);
}
View Code
复制代码

  运行结果:

  (1)画笔

  

  (2)画刷

  

  (3)字体

  

  (4)位图

  

  (5)复合图形

  

二、练习:实现简易的画图工具

  ::SetCapture - 捕获鼠标

  ::ReleaseCapture - 释放鼠标

  int  ::SetRop2( HDC  hdc,                 //绘图设备句柄

                            int     fnDrawMode );  //R2_NOT取反色 

  相关代码: 

复制代码
CPoint ptStart;  //图形的起点
CPoint ptCur;    //图形的当前点
int g_kind = 0;
void CT25_MFCDrawView::OnPen()
{
    g_kind = 1;
}
void CT25_MFCDrawView::OnLine()
{
    g_kind = 2;
}
void CT25_MFCDrawView::OnRect()
{
    g_kind = 3;
}
void CT25_MFCDrawView::OnEll()
{
    g_kind = 4;
}
void CT25_MFCDrawView::OnLButtonDown(UINT nFlags, CPoint point)
{
    ::SetCapture(this->m_hWnd);
    ptStart = point;
    ptCur = point;
    CView::OnLButtonDown(nFlags, point);
}
void CT25_MFCDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
    ::ReleaseCapture();
    CView::OnLButtonUp(nFlags, point);
}
void CT25_MFCDrawView::OnMouseMove(UINT nFlags, CPoint point)
{
    CClientDC dc(this);
    if (nFlags & MK_LBUTTON)  //鼠标左键按下
    {
        if (1 == g_kind)//铅笔
        {
            dc.MoveTo(ptStart);
            dc.LineTo(point);
            ptStart = point;//起点随时在变
        }
        else if (2 == g_kind)//直线
        {
            dc.SetROP2(R2_NOT);            
            dc.MoveTo(ptStart);//覆盖前一次的线
            dc.LineTo(ptCur);
            dc.MoveTo(ptStart);  
            dc.LineTo(point);
            ptCur = point;
        }
        else if (3 == g_kind)//矩形
        {
            dc.SetROP2(R2_NOT);
            HBRUSH hBrush = (HBRUSH)::GetStockObject(NULL_BRUSH);
            HBRUSH hOldBrush = (HBRUSH)::SelectObject(dc.m_hDC, hBrush);
            dc.Rectangle(ptStart.x, ptStart.y, ptCur.x, ptCur.y);
            dc.Rectangle(ptStart.x, ptStart.y, point.x, point.y);
            ptCur = point;
            ::SelectObject(dc.m_hDC, hOldBrush);
        }
        else//圆形
        {
            dc.SetROP2(R2_NOT);
            HBRUSH hBrush = (HBRUSH)::GetStockObject(NULL_BRUSH);
            HBRUSH hOldBrush = (HBRUSH)::SelectObject(dc.m_hDC, hBrush);
            dc.Ellipse(ptStart.x, ptStart.y, ptCur.x, ptCur.y);
            dc.Ellipse(ptStart.x, ptStart.y, point.x, point.y);
            ptCur = point;
            ::SelectObject(dc.m_hDC, hOldBrush);
        }
    }
    CView::OnMouseMove(nFlags, point);
}
View Code
复制代码

  运行结果:

  

  

 

posted @   甩锅侠  阅读(2933)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示