• VC学习笔记:文本图形


    VC学习笔记:文本图形

     SkySeraph OCT.30th 2010  HQU

    Email-zgzhaobo@gmail.com  QQ-452728574

    Latest Modified Date:NOV.2th 2010 HQU

    文本输出

    • 输出指定字体格式文本[1]

    void CSpecificFontView::OnDraw(CDC* pDC)

    {

    CSpecificFontDoc* pDoc = GetDocument();//获取视图关联的文档对象

    ASSERT_VALID(pDoc);//验证文档对象

    CFont Font;

    Font.CreateFont(24,24,0,0,FW_NORMAL,0,TRUE,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,

                CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_ROMAN,"宋体");

    CFont *pOldFont = NULL;

    pOldFont = pDC->SelectObject(&Font);

    pDC->TextOut(10,10,"同一个世界,同一个梦想!");

    pDC->SelectObject(pOldFont);

    Font.DeleteObject();

    }

    • 在矩形区域居中位置输出信息[1]

    void CDrawTextView::OnDraw(CDC* pDC)

    {

    CDrawTextDoc* pDoc = GetDocument();

    ASSERT_VALID(pDoc);

    CRect rc(100,20,300,200);

    CString str = "我爱北京,我爱奥运!";

    CBrush brush(RGB(0,0,0,0));

    pDC->FrameRect(rc,&brush); // 用黑色画刷绘制一个矩形

    pDC->DrawText(str,rc,DT_CENTER|DT_SINGLELINE|DT_VCENTER);//在矩形区域绘制文本

    brush.DeleteObject();//释放画刷对象

    }

    函数说明:

    FrameRect

    用指定的画刷为指定的矩形画边框。边框的宽和高总是一个逻辑单元。

    DrawText

    用于在某一个区域内输出文本    &&  TextOut用于在指定的坐标输出文本

    • 利用制表位空值文本输出[1]

    void CTaboutView::OnDraw(CDC* pDC)

    {

    CTaboutDoc* pDoc = GetDocument();

    ASSERT_VALID(pDoc);

    int pts[4] = {100,150,300,400};

    pDC->TabbedTextOut(0,20,"\t2008\t北京奥运\t同一个世界\t同一个梦想",4,pts,0);

    }

    • 设置字体和颜色[1]

    void CSelFontView::OnDraw(CDC* pDC)

    {

    CSelFontDoc* pDoc = GetDocument();

    ASSERT_VALID(pDoc);

    CFont Font;                                                                //定义一个字体对象

    //创建字体

    Font.CreateFont(12,12,2700,0,FW_NORMAL,0,0,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,

               CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_ROMAN,"黑体");

    CFont *pOldFont = NULL;                                                //定义一个字体指针

    pOldFont = pDC->SelectObject(&Font);                        //选中创建的字体

    pDC->SetTextColor(RGB(255,0,0)); //设置输出文本颜色

    pDC->TextOut(100,50,"北京奥运");                        //输出文本信息

    pDC->SelectObject(pOldFont);                                        //恢复之前选中的字体

    Font.DeleteObject();        //释放字体对象

    Font.CreatePointFont(120,"黑体",pDC);//创建字体

    pOldFont = pDC->SelectObject(&Font);//选中创建的字体

    pDC->TextOut(120,70, "同一个世界");

    pDC->TextOut(120,90, "同一个梦想");

    pDC->SelectObject(pOldFont);        //恢复之前选中的字体

    Font.DeleteObject();        

    }

    • 在路径上输出文字[1]

    void CPathFontView::OnDraw(CDC* pDC)

    {

    CPathFontDoc* pDoc = GetDocument();

    ASSERT_VALID(pDoc);

    CFont mFont;        

    //创建字体

    VERIFY(mFont.CreateFont(

    150, 50, 0, 0, FW_HEAVY, TRUE, FALSE,

    0, ANSI_CHARSET, OUT_DEFAULT_PRECIS,       

    CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,            

    DEFAULT_PITCH | FF_SWISS, "宋体"));

    CPen pen(PS_SOLID,2,RGB(255,0,0));

    pDC->SelectObject(&pen);

    pDC->BeginPath();//开始一个路径

    CFont *pOldFont = pDC->SelectObject(&mFont);//

    pDC->SetBkMode(TRANSPARENT);//设置画布的背景模式为透明

    pDC->TextOut(30,30,"嫦娥一号探月卫星");

    pDC->EndPath();//关闭路径

    pDC->StrokePath();//用当前的画笔绘制路径

    mFont.DeleteObject();

    pDC->SelectObject(pOldFont);

    }

    • 在图像背景上输出透明文本[1]

    void CTransTextView::OnDraw(CDC* pDC)

    {

    CTransTextDoc* pDoc = GetDocument();

    ASSERT_VALID(pDoc);

    // TODO: add draw code for native data here

    CBitmap bmp;//定义位图

    bmp.LoadBitmap(IDB_BKBITMAP);//加载位图

    BITMAP bInfo;//定义位图结构

    bmp.GetBitmap(&bInfo);//获取位图信息

    int width = bInfo.bmWidth;

    int height = bInfo.bmHeight;

    CDC memDC;//定义一个设备上下文

    memDC.CreateCompatibleDC(pDC);//创建一个兼容的设备上下文

    memDC.SelectObject(&bmp);//选中位图对象

    pDC->BitBlt(0,0,width,height,&memDC,0,0,SRCCOPY); //在设备上下文中绘制位图

    memDC.DeleteDC();//释放设备上下文

    bmp.DeleteObject();//释放位图对象

    CFont mFont;                                                                        //定义一个字体对象

    //创建字体

    VERIFY(mFont.CreateFont(                                        

    24, 20, 0, 0, FW_HEAVY, FALSE, FALSE,

    0, ANSI_CHARSET, OUT_DEFAULT_PRECIS,

    CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,

    DEFAULT_PITCH | FF_SWISS, "宋体"));

    CFont* pOldFont = pDC->SelectObject(&mFont);

    pDC->SetBkMode(TRANSPARENT);//设置透明的背景模式

    pDC->SetTextColor(RGB(0,255,0));//设置文本颜色

    pDC->TextOut(60,60,"田园生活");

    pDC->SelectObject(pOldFont);

    mFont.DeleteObject();

    }

    绘制图形

    • 一些函数

    画点

    CDC::SetPixel()/CDC::SetPixelV()

    后者不需要返回实际像素点的RGB,较快

    当前位置获取

    CDC::GetCurrentPosition

    原型CPoint GetCurrentPosition( ) const;

    折线

    Polyline/PolyPolyline/PolylineTo

    Polyline和PolyPolyline既不使用当前位置,也不更新当前位置;而PolylineTo总是把当前位

    置作为起始点,并且在折线画完之后,还把折线终点所在位置设为新的当前位置

    矩形和圆角矩形

    Rectangle和RoundRect

     

     

    • 利用线条绘制多边形[1]

    void CDrawLineView::OnDraw(CDC* pDC)

    {

    CDrawLineDoc* pDoc = GetDocument();

    ASSERT_VALID(pDoc);

    //绘制矩形

    CPen pen(PS_SOLID,2,RGB(255,0,0));

    CPen *pOldPen = pDC->SelectObject(&pen);

    pDC->MoveTo(50,30);

    pDC->LineTo(240,30);//绘制上边框

    pDC->LineTo(240,120);//绘制右边框

    pDC->LineTo(50,120);  //绘制下边框

    pDC->LineTo(50,30);//绘制左边框

    //绘制多变形

    pDC->MoveTo(300,50);//设置当前坐标

    pDC->LineTo(400,50);//绘制上边框

    pDC->LineTo(450,100);//绘制右斜边框

    pDC->LineTo(400,150);//绘制右斜边框

    pDC->LineTo(300,150); //绘制底边框

    pDC->LineTo(250,100);//绘制左上边框

    pDC->LineTo(300,50);//绘制左上边框

    //绘制弧线

    CRect rc(500,50,600,100);

    pDC->Arc(500,50,600,100,520,70,560,30);

    CBrush brush(RGB(255,0,0));

    pDC->FrameRect(rc,&brush);

    pDC->SelectObject(pOldPen);

    }

    • 直接绘制多边形[1]

    void CPolyView::OnDraw(CDC* pDC)

    {

    CPolyDoc* pDoc = GetDocument();

    ASSERT_VALID(pDoc);

    CRect rc(20,20,80,80);

    pDC->Rectangle(rc);//绘制矩形区域

    CRect RndRC(20,100,80,160);

    pDC->RoundRect(RndRC,CPoint(10,10));//绘制圆角矩形

    CPoint pts[6] = {CPoint(300,50),CPoint(400,50),CPoint(450,100),

                 CPoint(400,150),CPoint(300,150),CPoint(250,100)};//定义多边形端点

    pDC->Polygon(pts,6);//绘制多边形

    }

    • 绘制控件外观[1]

    void CDrawCtrlView::OnDraw(CDC* pDC)

    {

    CDrawCtrlDoc* pDoc = GetDocument();

    ASSERT_VALID(pDoc);

    //绘制按钮

    CRect rc(50,50,120,80);

    pDC->DrawFrameControl(rc,DFC_BUTTON,DFCS_BUTTONPUSH);

    //绘制标题栏关闭按钮

    CRect CapRC(130,50,160,80);

    pDC->DrawFrameControl(CapRC,DFC_CAPTION,DFCS_CAPTIONHELP);

    //绘制滚动条按钮

    CRect ScrollRC(170,50,200,80);

    pDC->DrawFrameControl(ScrollRC,DFC_SCROLL,DFCS_SCROLLCOMBOBOX);

    }

    函数说明:

    BOOL DrawFrameControl(LPRECT lpRect,UINT nType,UINT nState);

    lpRect:控件所在的矩形区域; nState:绘制控件的风格或状态

    nType:控件类型,DFC_BUTTON、DFC_CAPTION/标题栏、DFC_MENU、DFC_SCROLL/滚动条;

    • 填充矩形区域[1]

    void CFillRCView::OnDraw(CDC* pDC)

    {

    CFillRCDoc* pDoc = GetDocument();//获取文档对象

    ASSERT_VALID(pDoc);//验证文档

    CRect rc(30,40,100,120);

    CBrush brush(RGB(128,128,128));

    //使用颜色填充区域

    pDC->FillRect(rc,&brush);

    brush.DeleteObject();

    CBitmap bmp;

    bmp.LoadBitmap(IDB_BKBITMAP);

    brush.CreatePatternBrush(&bmp);//创建位图画刷

    CRect bmpRC(110,40,200,120);

    //使用位图填充区域

    pDC->FillRect(bmpRC,&brush);

    bmp.DeleteObject();//释放位图

    brush.DeleteObject();//释放画刷

    //填充选区

    CRect rectrc(210,40,300,120);

    CRect hrc(280,60,350,140);

    pDC->Rectangle(rectrc);

    pDC->Rectangle(hrc);

    HRGN hRect = CreateRectRgn(210,40,300,120);

    HRGN hrgn = CreateRectRgn(280,60,350,140);

    HRGN hret = CreateRectRgn(0,0,0,0);

    CombineRgn(hret,hRect,hrgn,RGN_AND);//组合选取,获取两个选取的公共部分

    brush.CreateSolidBrush(RGB(255,0,0));//创建一个颜色画刷

    CRgn rgn;//定义一个选区对象

    rgn.Attach(hret);//将选区对象附加一个选区句柄

    pDC->FillRgn(&rgn,&brush);//

    brush.DeleteObject();

    rgn.Detach();//分离选区

    DeleteObject(hRect);

    DeleteObject(hrc);

    DeleteObject(hret);

    }

    绘图实例:课程成绩直方图

    ①用MFC AppWizard创建一个默认的单文档应用程序Ex_Draw

    ②为CEx_DrawView类添加一个成员函数DrawScore,用来根据成绩来绘制直方图,该函数的代码如下:

    void CEx_DrawView::DrawScore(CDC *pDC, float *fScore, int nNum)

    // fScore是成绩数组指针,nNum是学生人数

    {

    int nScoreNum[] = { 0, 0, 0, 0, 0};    // 各成绩段的人数的初始值

    // 下面是用来统计各分数段的人数

    for (int i=0; i<nNum; i++)   

         {

    int nSeg = (int)(fScore[i]) / 10;    // 取数的"十"位上的值

    if (nSeg < 6)    nSeg = 5;    // <60分

    if (nSeg == 10 ) nSeg = 9;        // 当为100分,算为>90分数段

    nScoreNum[nSeg - 5] ++;        // 各分数段计数

    }

    int nSegNum = sizeof(nScoreNum)/sizeof(int);    // 计算有多少个分数段

           // 求分数段上最大的人数

    int nNumMax = nScoreNum[0];                   

    for (i=1; i<nSegNum; i++)   

        {

    if (nNumMax < nScoreNum[i]) nNumMax = nScoreNum[i];

    }

    CRect rc;

    GetClientRect(rc);

    rc.DeflateRect( 40, 40 );                // 缩小矩形大小

    int nSegWidth = rc.Width()/nSegNum;        // 计算每段的宽度

    int nSegHeight = rc.Height()/nNumMax;        // 计算每段的单位高度

    COLORREF crSeg = RGB(0,0,192);            // 定义一个颜色变量

    CBrush brush1( HS_FDIAGONAL, crSeg );

    CBrush brush2( HS_BDIAGONAL, crSeg );

    CPen   pen( PS_INSIDEFRAME, 2, crSeg );

    CBrush* oldBrush = pDC->SelectObject( &brush1 );    // 将brush1选入设备环境

    CPen* oldPen = pDC->SelectObject( &pen );        // 将pen选入设备环境

    CRect rcSeg(rc);

    rcSeg.right = rcSeg.left + nSegWidth;        // 使每段的矩形宽度等于nSegWidth

    CString strSeg[]={"<60","60-70","70-80","80-90",">=90"};

    CRect rcStr;

    for (i=0; i<nSegNum; i++)   

          {

                      // 保证相邻的矩形填充样式不相同

    if (i%2)

    pDC->SelectObject( &brush2 );   

    else

    pDC->SelectObject( &brush1 );   

    rcSeg.top = rcSeg.bottom - nScoreNum[i]*nSegHeight - 2;    // 计算每段矩形的高度

    pDC->Rectangle(rcSeg);

    if (nScoreNum[i] > 0)   

                      {

    CString str;

    str.Format("%d人", nScoreNum[i]);

    pDC->DrawText( str, rcSeg, DT_CENTER | DT_VCENTER | DT_SINGLELINE );

    }

    rcStr = rcSeg;

    rcStr.top = rcStr.bottom + 2;        rcStr.bottom += 20;

    pDC->DrawText( strSeg[i], rcStr, DT_CENTER | DT_VCENTER | DT_SINGLELINE );

                     // 后面还会讲到

    rcSeg.OffsetRect( nSegWidth, 0 );        // 右移矩形

    }

    pDC->SelectObject( oldBrush );            // 恢复原来的画刷属性

    pDC->SelectObject( oldPen );            // 恢复原来的画笔属性

    }

    ③在CEx_DrawView::OnDraw函数中添加下列代码:

    void CEx_DrawView::OnDraw(CDC* pDC)

    {

    CEx_DrawDoc* pDoc = GetDocument();

    ASSERT_VALID(pDoc);

    float fScore[] = {66,82,79,74,86,82,67,60,45,44,77,98,65,90,66,76,66,

                          62,83,84,97,43,67,57,60,60,71,74,60,72,81,69,79,91,69,71,81};

    DrawScore(pDC, fScore, sizeof(fScore)/sizeof(float));

    }

     

    Author:         SKySeraph

    Email/GTalk: zgzhaobo@gmail.com    QQ:452728574

    From:         http://www.cnblogs.com/skyseraph/

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,请尊重作者的劳动成果。

  • 相关阅读:
    sql2005创建存储过程
    sql 2005 调用存储过程
    sql2005创建存储过程(需要注意的几点)
    c# 日期处理
    Worldwind WMS Server安装
    Ubuntu11.10 设置默认Terminal为Terminator
    WordPress中文标题无法显示的解决方法
    Unknown Source的出现及解决
    Windows下 ant配置 以及 Unable to locate tools.jar
    安装WordPress中文包四步曲
  • 原文地址:https://www.cnblogs.com/skyseraph/p/1870875.html
Copyright © 2020-2023  润新知