掌握CDC的文字处理程序的编写,如何产生自定义字体和自定义插入符,熟悉对CString类的使用。通过对卡拉OK程序的编写,讲解定时器的使用和DrawText函数的巧妙运用。讲解如何使用CDC的裁减功能。 &&VC问题:解决不能自动列出成员:重新打开VC,再加载工程即可。实在不行就删除一下ncb文件,再打开VC试试。 1.创建插入符:void CreateSolidCaret( int nWidth, int nHeight ); //Caret补字号,若宽度、高度设为0,就设为系统默认的窗口编辑的宽度、高度(可用GetSystemMetrics)。而caret是初始化为hidden的。还要用ShowCaret(); 在窗口创建后创建,应该在view类去创建WM_CREATE消息。所以可用CreateSolidCaret(2,10);ShowCaret();//创建、显示插入符。 用GetTextMetrics获取当前字体信息:BOOL GetTextMetrics( LPTEXTMETRIC lpMetrics ) const; typedef struct tagTEXTMETRIC { /* tm */ int tmHeight; //字体高度 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; 对于字体,如对于gh,h的高度是tmAscent升序高度,h下端的线是base line基线,g下端到基线的高度是tmDesent降序高度,所以字体的高度是升序高度加上降序高度。 CClientDC dc(this); TEXTMETRIC tm; dc.GetTextMetrics(&tm); CreateSolidCaret(tm.tmAveCharWidth/8,tm.tmHeight); ShowCaret(); 2.创建图形的插入符:void CreateCaret( CBitmap* pBitmap ); //要构造CBitmap对象 CBitmap bitmap;//通常和资源相关的对象,在析构的时候都要把资源销毁,应把此定义放到头文件里,添加private…… bitmap.LoadBitmap(IDB_BITMAP1); CreateCaret(&bitmap); 3.输出文字:为了让文字始终在程序中都可以看到(因为redraw的时候会擦除),要在view类的OnDraw函数中编写。 要用CString类,没有基类的。在C语言中,对字符串操作一般是对char*操作;在C++中,用CString即可。它还重载了很多操作符。 在void CTest1View::OnDraw(CDC* pDC)中,写: CString str("weixin-中心"); pDC->TextOut(50,50,str); CString类的赋值: 1)CString str;str="adfsfdf"; //因为重载了等号操作符 2)用BOOL LoadString( UINT nID ); //nID是字符资源ID 可在资源中--string table中,空白处双击,然后创建字符串资源,如IDS_WEIXIN,字符串是“sfsf……”。 在定义了CString str;后可用str.LoadString(IDS_WEIXIN);加载赋值。 4.路径程bracket,用BOOL BeginPath( );创建,之后can begin calling GDI drawing functions to define the points that lie in the path,用BOOL EndPath( );关闭。 用CSize GetTextExtent( LPCTSTR lpszString, int nCount ) const; //获取字符串长度 CSize GetTextExtent( const CString& str ) const; //返回CSize,和windows的SIZE结构体类似 typedef struct tagSIZE { int cx; int cy; } SIZE; 在BeginPath和EndPath间用Rectangle画矩形,看不到;在外面画看得到。pDC->Rectangle(50,50,50+sz.cx,50+sz.cy); BOOL SelectClipPath( int nMode ); //模式有RGN_AND/COPY/DIFF/OR/XOR 如用SelectClipPath(RGN_DIFF)则……画到文字矩形区域时,就不画了 5.在WM_CHAR消息中捕获字符输出。 增加一个成员变量public的m_strLen来存放字符串,在构造函数中将 m_strLine=""; 在OnChar中完成输出字符的功能。在OnLButtonDown中移动插入符。移动它用static void PASCAL SetCaretPos( POINT point ); 将字符对象清空:m_strLen.Empty(); 再增加一个CPoint的public变量m_ptOrigin存放插入符坐标。 用COLORREF GetBkColor( ) const;获取当前背景色,返回RGB; 然后用virtual COLORREF SetTextColor( COLORREF crColor ); 设置文本颜色 CString的CString Left( int nCount ) const;函数,取左边的一些字符串。GetLength得到字符串长度 void CTest1View::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default CClientDC dc(this); TEXTMETRIC tm; dc.GetTextMetrics(&tm); if(0x0d==nChar) //asc=13为回车 { m_strLine.Empty(); m_ptOrigin.y+=tm.tmHeight; } else if(0x08==nChar) //BACKSPACE { 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); CView::OnChar(nChar, nRepCnt, nFlags); } 6.CFont类,必须用初始化函数初始化 如BOOL CreatePointFont( int nPointSize, LPCTSTR lpszFaceName, CDC* pDC = NULL ); CFont font; font.CreatePointFont(300,"楷体",NULL); CFont *pOldFont=dc.SelectObject(&font); dc.TextOut(m_ptOrigin.x,m_ptOrigin.y,m_strLine); dc.SelectObject(pOldFont); 7.CEditView类,或CRichEditView有处理文字的一些功能。 8. virtual int DrawText( LPCTSTR lpszString, int nCount, LPRECT lpRect, UINT nFormat ); int DrawText( const CString& str, LPRECT lpRect, UINT nFormat );//将文字的输出局限在一定矩形范围内 lpRect是限制的矩形,nFormat是输出格式(DT_CENTER等) 创建定时器UINT SetTimer( UINT nIDEvent, UINT nElapse, void (CALLBACK EXPORT* lpfnTimer)(HWND, UINT, UINT, DWORD) ); nIDEvent是定时器的标识,nElapse指定流逝值(以毫秒为单位),回调函数(当定时器时间达到时就调用它) 若回调函数设置为NULL,则发送以CWnd对象为句柄的WM_TIMER消息到消息队列中。 可在OnCreate里设置定时器,如 SetTimer(1,100,NULL);在WM_TIMER消息中设置,由nIDEvent判断定时器。 void CTest1View::OnTimer(UINT nIDEvent) //用DrawText平滑的输出 { // TODO: Add your message handler code here and/or call default m_nWidth+=5; CClientDC dc(this); TEXTMETRIC tm; dc.GetTextMetrics(&tm); CRect rt; rt.left=0; rt.top=200; rt.right=m_nWidth; rt.bottom=rt.top+tm.tmHeight; dc.SetTextColor(RGB(255,0,0)); CString str; str.LoadString(IDS_WEIXIN); dc.DrawText(str,rt,DT_LEFT); CView::OnTimer(nIDEvent); } 在后面比较DT_RIGHT的区别,就是从矩形的右边开始输出,结果像矩形从左向右移动一样。 rt.top=150; rt.bottom=rt.top+tm.tmHeight; dc.DrawText(str,rt,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); }
(孙鑫 五) 文本编程
最新推荐文章于 2023-05-18 14:08:29 发布