窗口大小发生变化,就会发生窗口重绘,窗口中的文字和图形就会擦除掉。要想内容始终显示在窗口中,就要在视类WM_PAINT消息的消息响应函数OnDraw函数中显示。
5.2.1OnDraw函数
void CTextView::OnDraw(CDC* pDC)
{
CTextDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
这个函数不用创建CDC类的对象,它已经通过参数传递进来了,可以直接调用CDC类的成员函数完成绘制功能。
CDC类封装的TextOut函数与Platform SDK提供的TextOut函数区别:
前者不需要DC句柄,因为CDC内部成员变量m_hDC保存了DC句柄。
CString类重载了多个操作符。
CString类构造函数:
CString( );
CString( const CString& stringSrc );
CString( TCHAR ch, int nRepeat = 1 );
CString( LPCTSTR lpch, int nLength );
CString( const unsigned char* psz );
CString( LPCWSTR lpsz );
CString( LPCSTR lpsz );
void CTextView::OnDraw(CDC* pDC)
{
CTextDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CString str("VC++ 深入编程");
pDC->TextOut(50,50,str);
// TODO: add draw code for native data here
}
另一种字符串构造方式:
CString str;
str=“VC++ 深入编程”;
5.2.2添加字符串资源
CString 类还提供了一个成员函数:LoadString
BOOL LoadString( UINT nID );
装载一个nID标识的字符串资源,这样可以直接使用响应的字符串,而不用为字符串变量赋值
定义字符串资源:Resource View->String Table
最底部的空行上单击、添加。
void CTextView::OnDraw(CDC* pDC)
{
CTextDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CString str("VC++ 深入编程");
pDC->TextOut(50,50,str);
str.LoadString(IDS_STRING61446);
pDC->TextOut(0,200,str);
// TODO: add draw code for native data here
}
5.3路径
CDC类提供BeginPath打开一个路径层,进行相应的绘图操作,然后调用EndPath函数关闭这个路径层。
我们可以确认矩阵的左上角坐标,怎么确定右下角坐标呢?
CDC类提供了GetTextExtent函数,获得一个字符串在屏幕上的高度和宽度。
CSize GetTextExtent( const CString& str ) const;
typedef struct tagSIZE {
int cx;
int cy;
} SIZE;
返回一个SIZE类对象。
GetTextMetrics与GetTextExtent,前者获得字体的度量信息,后者是获得字符串的度量信息。
void CTextView::OnDraw(CDC* pDC)
{
CTextDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CString str("VC++ 深入编程");
pDC->TextOut(50,50,str);
CSize sz=pDC->GetTextExtent(str);
str.LoadString(IDS_STRING61446);
pDC->TextOut(0,200,str);
pDC->BeginPath();
pDC->Rectangle(50,50,50+sz.cx,50+sz.cy);
pDC->EndPath();
// TODO: add draw code for native data here
}
与之前的结果一样,若pDC->BeginPath();和pDC->EndPath();注释起来,就会变成下图。
在路径层中绘制矩阵,它对输出的文字是没有影响的
void CTextView::OnDraw(CDC* pDC)
{
CTextDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CString str("VC++ 深入编程");
pDC->TextOut(50,50,str);
CSize sz=pDC->GetTextExtent(str);
str.LoadString(IDS_STRING61446);
pDC->TextOut(0,200,str);
pDC->BeginPath();
pDC->Rectangle(50,50,50+sz.cx,50+sz.cy);
pDC->EndPath();
for(int i=0;i<300;i+=10)
{
pDC->MoveTo(0,i);
pDC->LineTo(300,i);
pDC->MoveTo(i,0);
pDC->LineTo(i,300);
}
// TODO: add draw code for native data here
}
画网格线。网格线把文字盖住了。
CDC类提供了一个SelectClipPath函数,将当前设置的路径层与已有的裁剪区域按照一定模式的一个互操作。
BOOL SelectClipPath( int nMode );
RGN_DIFF:排除当前路径层区域。
在设置路径层与网格线代码之间添加:
pDC->SelectClipPath(RGN_DIFF);
运行,出现如图图像
void CTextView::OnDraw(CDC* pDC)
{
CTextDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CString str("VC++ 深入编程");
pDC->TextOut(50,50,str);
CSize sz=pDC->GetTextExtent(str);
str.LoadString(IDS_STRING61446);
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);
}
// TODO: add draw code for native data here
}
RGN_AND:当前路径层与当前裁剪区域的交集
运行,出现以下图