zoukankan      html  css  js  c++  java
  • 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/

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

  • 相关阅读:
    LeetCode 811. Subdomain Visit Count (子域名访问计数)
    LeetCode 884. Uncommon Words from Two Sentences (两句话中的不常见单词)
    LeetCode 939. Minimum Area Rectangle (最小面积矩形)
    LeetCode 781. Rabbits in Forest (森林中的兔子)
    LeetCode 739. Daily Temperatures (每日温度)
    三种方式实现按钮的点击事件
    239. Sliding Window Maximum
    14.TCP的坚持定时器和保活定时器
    13.TCP的超时与重传
    12.TCP的成块数据流
  • 原文地址:https://www.cnblogs.com/skyseraph/p/1870875.html
Copyright © 2011-2022 走看看