目录
窗口重绘
OnDraw函数
添加字符串资源
接上:VC++ 文本编程 插入符 创建图形插入符 CreateCaret函数
接下:VC++路径
窗口重绘
在Windows程序运行时,如果程序窗口大小发生变化,窗口会发生重绘,那么窗口中已输入的文字或图形就会被擦除掉。如果希望输入的内容始终保留在窗口上,就要在响应WM_PAINT消息的函数中将内容再次输出。在MFC应用程序向导产生的视类代码中,给我们提供了一个类似于WM_PAINT消息响应函数的OnDraw函数,当窗口发生重绘时,应用程序框架代码就会调用该函数。
OnDraw函数在CTextView类中,OnDraw函数的定义如例所示。
void CTextView::OnDraw(CDC* /*pDC*/)
{
CTextDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
}
可以在此函数处设置一个断点,调试运行程序,看看程序调用这个函数的时机。我们知道当窗口初次出现时,即从无到有时,会产生WM_PAINT 消息,让窗口重绘,这时程序停在所设置的OnDraw函数断点处。继续调试程序,在调试过程中,可以看到,当窗口尺寸发生变化的时候,也会进入OnDraw函数。因此,如果希望输入的图形或文字始终能够在窗口上显示的话,就可以在这个OnDraw函数中进行处理。
另外,从这个函数的定义可知,当它被调用时,应用程序框架会构造一个 CDC 类对象的指针并传递给这个函数,这给我们提供了方便,在这个函数内部就不需要再去构造CDC类的对象,可以直接使用传递进来的CDC对象指针去调用CDC类的成员函数,完成绘制功能。不过,要注意的是,MFC应用程序向导自动生成的OnDraw函数的代码中形参pDC被注释起来了,在使用时,将注释取消即可。
接下来,我们要实现在程序窗口中输出一串文字这一功能,这可以使用前面介绍的TextOut这个函数来实现。在C语言中,如果要使用字符串的话,那么一般是定义一个char*类型的变量。在MFC中,它提供了一个字符串类:CString,这个类没有基类。一个CString对象由一串可变长度的字符组成。在C语言中,利用char类型指针 *** 作字符串时,一旦给它分配了堆内存,那么它就只能存储已分配大小的字符数量。如果想要另外再多存储些字符,就只能对这个指针所指向的堆内存进行再分配。然而,利用 CString *** 作字符串时,无论存储多少个字符,我们都不需要对它进行内存分配,因为这些 *** 作在 CString类的内部都已经替我们完成了,这就是CString类的好处。在MFC程序中利用CString类对字符串进行 *** 作是很方便的。读者可以在MSDN中查看CString类的成员,将会发现它重载了多个 *** 作符,这为我们 *** 作CString类的对象提供了极大的便利。可以把CString类型的对象当作简单类型的变量一样进行赋值、相加 *** 作,例如利用“=” *** 作符,可以直接把一个字符或另一个CString类型的字符串赋给一个CString类型的对象;利用“+” *** 作符,可以方便地把两个字符串或一个字符与一个字符串联成一个字符串。
CString类提供了多个重载的构造函数(如例代码所示),利用这些构造函数,我们可以构造一个空的CString对象,或者用一个已有的CString对象构造一个新的CString对象,或者用一个字符指针构造一个CString对象。
CString::CString
CString( );
CString( const CString& stringSrc );
throw( CMemoryException );
CString( TCHAR ch, int nRepeat = 1 );
throw( CMemoryException );
CString( LPCTSTR lpch, int nLength );
throw( CMemoryException );
CString( const unsigned char* psz );
throw( CMemoryException );
CString( LPCWSTR lpsz );
throw( CMemoryException );
CString( LPCSTR lpsz );
throw( CMemoryException );
例所示代码就是利用CString类在OnDraw函数内实现字符串显示的代码:
void CTextView::OnDraw(CDC* pDC)
{
CTextDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CString str(_T("风灵"));
pDC -> TextOut(100,100, str);
// TODO: 在此处为本机数据添加绘制代码
}
提示: CDC类封装的TextOut函数与SDK提供的全局TextOut函数的区别:前者不需要DC句柄作为参数,因为CDC内部专门有一个成员变量(m_hDC)保存了DC句柄。
提示: 上面代码中有一个_T宏的使用,该宏的作用与在字面常量字符串前面添加大写字母L的作用是一样的,不同的是,字面常量字符串需要放到括号中,与此类似的还有TEXT宏的使用,例如:CString str(TEXT("VC++深入编程"));可以用【转到定义】功能查看一下_T 宏和 TEXT 宏的定义,就能一清二楚了。
编译并运行Text程序,可以看到在程序窗口中输出了我们指定的字符串,如图所示。并且可以发现,当窗口大小发生改变时,字符串仍显示在窗口当中,这是因为我们是在OnDraw函数中实现字符串的显示 *** 作的。
下面是另一种CString字符串构造形式:
CString str;
str = _T("风灵");
CString 类重载了“=” *** 作符,可以直接把一个字符串赋给一个 CString 对象。可以尝试运行这段代码,将会发现运行结果是一样的。
void CTextView::OnDraw(CDC* pDC)
{
CTextDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CString str;
str = _T("风灵");
pDC->TextOut(100, 100, str);
// TODO: 在此处为本机数据添加绘制代码
}
添加字符串资源
CString类还提供了一个成员函数:LoadString,其声明形式如下:
BOOL LoadString(
UINT nID
);
该函数可以装载一个由nID标识的字符串资源。其好处是,我们可以构造一个字符串资源,在需要使用时将其装载到字符串变量中,这样就不需要在程序中对字符串变量直接赋值了。
在Visual Studio开发环境中,如何定义字符串资源呢?切换到资源视图中,可以看到有一项是String Table,表示字符串表(如图所示)。展开“String Table”节点,双击节点下的字符串表,就会在左边的代码编辑区域打开当前程序的字符串表,其中列出了已经定义的各个字符串,如图所示。在这个字符串表中,第一列是字符串资源的ID号,第二列是字符串资源ID对应的数值,第三列是字符串资源的文本内容。
如果想要添加新的字符串资源,可以在这个字符串表最底部的空行上单击一下,就会自动添加一个字符串资源。本例定义一个 ID 为IDS_STRINGVC的字符串资源,内容为“风灵01”。如图所示。修改上述程序代码,利用LoadString函数加载这个新建的字符串。具体实现代码如下所示。
void CTextView::OnDraw(CDC* pDC)
{
CTextDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CString str;
str = _T("风灵");
pDC->TextOut(100, 100, str);
str.LoadString(IDS_STRINGVC);
pDC -> TextOut(0, 200, str);
// TODO: 在此处为本机数据添加绘制代码
}
接上:VC++ 文本编程 插入符 创建图形插入符 CreateCaret函数
接下:VC++路径
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)