VC++窗口重绘 OnDraw函数 添加字符串资源

目录

窗口重绘

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
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

米酒馆

鼓励鼓励,鼓励很重要啦~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值