• CDC的文字处理程序的编写


    掌握CDC的文字处理程序的编写,如何产生自定义字体和自定义插入符,熟悉对CString类的使用。通过对卡拉OK程序的编写,讲解定时器的使用和DrawText函数的巧妙运用。讲解如何使用CDC的裁减功能。

    1,创建插入符:
    void CreateSolidCaret( int nWidth, int nHeight );//创建插入符
    void CreateCaret( CBitmap* pBitmap );//创建位图插入符
    void ShowCaret( );//显示插入符
    void HideCaret( );//隐藏插入符
    static void PASCAL SetCaretPos( POINT point );//移动插入符号
    说明:
    1)创建插入符要在窗口创建完成之后,CreateSolidCaret函数创建的插入符被初始化为隐藏,所以需要调用ShowCaret()将其显示。
    2)使用CreateCaret函数创建位图插入符的时候,不能使用局部的位图对象关联位图资源。(与资源相关联的C++对象,当它析构的时候会同时把与它相关联的资源销毁。)

    2,获取当前字体信息的度量:CDC::GetTextMetrics
    BOOL GetTextMetrics( LPTEXTMETRIC lpMetrics ) const;
    说明:
    typedef struct tagTEXTMETRIC {
    int tmHeight;//字体高度。Specifies the height (ascent + descent) of characters.
    int tmAscent;//基线以上的字体高度
    int tmDescent;//基线以下的字体高度
    int tmInternalLeading;
    int tmExternalLeading;
    int tmAveCharWidth;//字符平均宽度
    int tmMaxCharWidth;
    int tmWeight;
    BYTE tmItalic;
    BYTE tmUnderlined;
    BYTE tmStruckOut;
    BYTE tmFirstChar;
    BYTE tmLastChar;
    BYTE tmDefaultChar;
    BYTE tmBreakChar;
    BYTE tmPitchAndFamily;
    BYTE tmCharSet;
    int tmOverhang;
    int tmDigitizedAspectX;
    int tmDigitizedAspectY;
    } TEXTMETRIC;

    3,OnDraw函数:
    virtual void OnDraw( CDC* pDC )
    当窗口(从无到有或尺寸大小改变等)要求重绘的时候,会发送WM_PAIN消息,调用OnDraw函数进行重绘。

    4,获取字符串的高度和宽度(区别字符串的长度):
    CDC::GetTextExtent
    CSize GetTextExtent( LPCTSTR lpszString, int nCount ) const;
    CSize GetTextExtent( const CString& str ) const;
    说明:
    The CSize class is similar to the Windows SIZE structure。
    typedef struct tagSIZE {
    int cx;//the x-extent
    int cy;//the y-extent
    } SIZE;


    5,路径层:
    BOOL BeginPath( );
    //在这作图定义路径层剪切区域
    BOOL EndPath( );
    BOOL SelectClipPath( int nMode );//调用这个函数来使当前路径层剪切区域与新剪切区域进行互操作。
    //在这覆盖作图(包含前定义的路径层区域)定义新的剪切区域

    说明:
    1)SelectClipPath Selects the current path as a clipping region for the device context, combining the new region with any existing clipping region by using the specified mode. The device context identified must contain a closed path.
    ////
    nMode:RGN_AND,RGN_COPY,RGN_DIFF,RGN_OR,RGN_XOR
    RGN_AND The new clipping region includes the intersection (overlapping areas) of the current clipping region and the current path.
    RGN_COPY The new clipping region is the current path.
    RGN_DIFF The new clipping region includes the areas of the current clipping region, and those of the current path are excluded.
    RGN_OR The new clipping region includes the union (combined areas) of the current clipping region and the current path.
    RGN_XOR The new clipping region includes the union of the current clipping region and the current path, but without the overlapping areas.
    2)应用:当作图的时候,如果想要在整幅图形其中的某个部分和其它部分有所区别,我们可以把这部分图形放到路径层当中,然后指定调用指定互操作模式调用SelectClipPath( int nMode )函数来使路径层和覆盖在其上新绘图剪切区域进行互操作,达到特殊效果。

    6,关于文本字符串一些函数:
    COLORREF GetBkColor( ) const;//得到背景颜色
    virtual COLORREF SetBkColor( COLORREF crColor );//设置背景颜色
    BOOL SetTextBkColor( COLORREF cr );//设置文本背景颜色
    virtual COLORREF SetTextColor( COLORREF crColor );//设置文本颜色
    virtual BOOL TextOut( int x, int y, LPCTSTR lpszString, int nCount );//输出文本
    BOOL TextOut( int x, int y, const CString& str );
    CString Left( int nCount ) const;//得到字符串左边nCount个字符
    int GetLength( ) const;//得到字符串长度

    7,字体CFont::CFont
    CFont( );//构造函数
    //Constructs a CFont object. The resulting object must be initialized with CreateFont, CreateFontIndirect, CreatePointFont, or CreatePointFontIndirect before it can be used.
    选用字体事例代码组:
    CClientDC dc(this);
    CFont font;//构造字体对象
    font.CreatePointFont(300,"华文行楷",NULL);//初始化字体对象,与字体资源相关联
    CFont *pOldFont=dc.SelectObject(&font);//将新字体选入DC
    ...
    dc.SelectObject(pOldFont);//恢复原字体
    说明:
    1)构造字体对象时候,必须初始化。(初始化是将字体对象与字体资源相关联)。
    2)初始化对象时候,选用的字体也可以是系统字体,但不一定都有效,据测试选用。

    8,在MFC中CEditView 和 cRichEditView类已经完成了初步的文字处理。可以让应用程序的View类以CEditView 和 cRichEditView类为基类。

    9,平滑变色
    CDC::TextOut()是一个字母一个字母的输出,达不到平滑效果。
    CDC::DrawText():将文字的输出局限于一个矩形区域,超出矩形区域的文字都被截断。利用这一特点,可每隔些时间增加矩形大小,从而可实现人眼中的平滑效果。
    CWnd::SetTimer():设置定时器。按设定的时间定时发送WM_TIMER消息。

    说明:
    UINT SetTimer( UINT nIDEvent, UINT nElapse, void (CALLBACK EXPORT* lpfnTimer)(HWND, UINT, UINT, DWORD) );
    //nIDEvent定时器标示,nElapse消息发送间隔时间,void (CALLBACK EXPORT* lpfnTimer)(HWND, UINT, UINT, DWORD)设置回调函数,如果设置则由设置的回调函数处理WM_TIMER消息,如果没有设置回调函数设为NULL,这发送的WM_TIMER消息压入消息队列,交由相关联的窗口处理(添加WM_TIMER消息处理函数OnTimer())。

    afx_msg void OnTimer( UINT nIDEvent );
    //响应WM_TIMER消息,nIDEvent为消息对应定时器标示(可以设置不同的定时器发送WM_TIMER消息)


    问题:
    1,在CCareView类中添加WM_CREATE消息响应函数OnCreate(),WM_CREATE消息是在什么时候被检查到而被响应的呢?
    (猜测:添加WM_CREATE消息后,消息被压入消息队列,然后经过消息循环进行分发到具体窗口,从而进行响应)

    2,现有一文本文件内容已经读入串STR中,要求在视图客户区按原先文本文件中的格式输出。
    问题是,利用CDC的TextOut()来在CView类派生类窗口中输出串时,忽略了串中的TAB、回车换行等格式,无论串有多长均在一行上输出。
    这其中是CDC类成员函数TextOut()忽略串中格式的,还是CView类派生类窗口设置从中做怪呢?怎么解决?

    // TextView.cpp : implementation of the CTextView class
    //

    #include "stdafx.h"
    #include "Text.h"

    #include "TextDoc.h"
    #include "TextView.h"

    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif

    /////////////////////////////////////////////////////////////////////////////
    // CTextView

    IMPLEMENT_DYNCREATE(CTextView, CView)

    BEGIN_MESSAGE_MAP(CTextView, CView)
    //{{AFX_MSG_MAP(CTextView)
    ON_WM_CREATE()
    ON_WM_CHAR()
    ON_WM_LBUTTONDOWN()
    ON_WM_TIMER()
    //}}AFX_MSG_MAP
    // Standard printing commands
    ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
    END_MESSAGE_MAP()

    /////////////////////////////////////////////////////////////////////////////
    // CTextView construction/destruction

    CTextView::CTextView()
    {
    // TODO: add construction code here
    m_strLine="";
    m_ptOrigin=0;
    m_nWidth=0;
    }

    CTextView::~CTextView()
    {
    }

    BOOL CTextView::PreCreateWindow(CREATESTRUCT& cs)
    {
    // TODO: Modify the Window class or styles here by modifying
    // the CREATESTRUCT cs

    return CView::PreCreateWindow(cs);
    }

    /////////////////////////////////////////////////////////////////////////////
    // CTextView drawing

    void CTextView::OnDraw(CDC* pDC)
    {
    CTextDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    // TODO: add draw code for native data here
    //CString str("维新科学技术培训中心");
    CString str;
    str="维新科学技术培训中心";
    pDC->TextOut(50,50,str);

    CSize sz=pDC->GetTextExtent(str);

    str.LoadString(IDS_WEIXIN);
    pDC->TextOut(0,200,str);

    pDC->BeginPath();
    pDC->Rectangle(50,50,50+sz.cx,50+sz.cy);
    pDC->EndPath();
    pDC->SelectClipPath(RGN_DIFF);
    for(int i=0;i<300;i+=10)
    {
    pDC->MoveTo(0,i);
    pDC->LineTo(300,i);
    pDC->MoveTo(i,0);
    pDC->LineTo(i,300);
    }
    }

    /////////////////////////////////////////////////////////////////////////////
    // CTextView printing

    BOOL CTextView::OnPreparePrinting(CPrintInfo* pInfo)
    {
    // default preparation
    return DoPreparePrinting(pInfo);
    }

    void CTextView::OnBeginPrinting(CDC* , CPrintInfo* )
    {
    // TODO: add extra initialization before printing
    }

    void CTextView::OnEndPrinting(CDC* , CPrintInfo* )
    {
    // TODO: add cleanup after printing
    }

    /////////////////////////////////////////////////////////////////////////////
    // CTextView diagnostics

    #ifdef _DEBUG
    void CTextView::AssertValid() const
    {
    CView::AssertValid();
    }

    void CTextView::Dump(CDumpContext& dc) const
    {
    CView::Dump(dc);
    }

    CTextDoc* CTextView::GetDocument() // non-debug version is inline
    {
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTextDoc)));
    return (CTextDoc*)m_pDocument;
    }
    #endif //_DEBUG

    /////////////////////////////////////////////////////////////////////////////
    // CTextView message handlers

    int CTextView::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    if (CView::OnCreate(lpCreateStruct) == -1)
    return -1;

    // TODO: Add your specialized creation code here
    CClientDC dc(this);//构造一个DC
    TEXTMETRIC tm;//
    dc.GetTextMetrics(&tm);//利用dc调用其成员函数

    // CreateSolidCaret(tm.tmAveCharWidth/8,tm.tmHeight);

    //CBitmap bitmap;//放头文件中了,因为全局要析构的
    bitmap.LoadBitmap(IDB_BITMAP1);
    CreateCaret(&bitmap);
    ShowCaret();

    SetTimer(1,100,NULL);
    return 0;
    }

    void CTextView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
    {
    // TODO: Add your message handler code here and/or call default
    CClientDC dc(this);
    CFont font;
    font.CreatePointFont(300,"华文行楷",NULL);
    CFont *pOldFont=dc.SelectObject(&font);
    TEXTMETRIC tm;
    dc.GetTextMetrics(&tm);
    if(0x0d==nChar)
    {
    m_strLine.Empty();
    m_ptOrigin.y+=tm.tmHeight;
    }
    else if(0x08==nChar)
    {
    COLORREF clr=dc.SetTextColor(dc.GetBkColor());
    dc.TextOut(m_ptOrigin.x,m_ptOrigin.y,m_strLine);
    m_strLine=m_strLine.Left(m_strLine.GetLength()-1);
    dc.SetTextColor(clr);
    }
    else
    {
    m_strLine+=nChar;
    }
    CSize sz=dc.GetTextExtent(m_strLine);

    CPoint pt;
    pt.x=m_ptOrigin.x+sz.cx;
    pt.y=m_ptOrigin.y;

    SetCaretPos(pt);
    dc.TextOut(m_ptOrigin.x,m_ptOrigin.y,m_strLine);

    dc.SelectObject(pOldFont);

    CView::OnChar(nChar, nRepCnt, nFlags);
    }

    void CTextView::OnLButtonDown(UINT nFlags, CPoint point)
    {
    // TODO: Add your message handler code here and/or call default
    SetCaretPos(point);
    m_strLine.Empty();
    m_ptOrigin=point;
    CView::OnLButtonDown(nFlags, point);
    }

    void CTextView::OnTimer(UINT nIDEvent)
    {
    // TODO: Add your message handler code here and/or call default
    m_nWidth+=5;

    CClientDC dc(this);
    TEXTMETRIC tm;
    dc.GetTextMetrics(&tm);
    CRect rect;
    rect.left=0;
    rect.top=200;
    rect.right=m_nWidth;
    rect.bottom=rect.top+tm.tmHeight;

    dc.SetTextColor(RGB(255,0,0));
    CString str;
    str.LoadString(IDS_WEIXIN);
    dc.DrawText(str,rect,DT_LEFT);

    rect.top=150;
    rect.bottom=rect.top+tm.tmHeight;
    dc.DrawText(str,rect,DT_RIGHT);

    CSize sz=dc.GetTextExtent(str);
    if(m_nWidth>sz.cx)
    {
    m_nWidth=0;
    dc.SetTextColor(RGB(0,255,0));
    dc.TextOut(0,200,str);
    }

    CView::OnTimer(nIDEvent);
    }

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    记一次生产环境Nginx间歇性502的事故分析过程
    如何为nginx配置https(免费证书)
    nginx + tomcat配置https的两种方法
    证书之间的转换(crt pem key)
    FreeSwitch: ESL Inbound内联模式下如何设置单腿变量
    CompletableFuture笔记
    java中整数常量池(-128~127)上限如何调整?
    redis过期机制及注意事项
    一次完整的通话过程SIP报文分析
    SIPp测试freeswitch用户注册
  • 原文地址:https://www.cnblogs.com/liyuanjinglyj/p/4656643.html
Copyright © 2020-2023  润新知