使用CLabel类的不解事项

本文探讨了在MFC环境下使用CLabel类实现一组静态控件的颜色动态切换,包括通过不同事件触发颜色变化的方法及在线程中调用所遇到的问题与解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这样的一个问题:界面上一组(一堆)静态控件,比如模拟控制器上许多按钮,当某个信号来时,一些设置为红色(故障),当另一个信号来时,一些设置为绿色(正常),使用了CLabel类,在http://www.codeproject.com/KB/static/clabel.aspx上下载,因为它可以直观设置【背景色】。

因为是“一组按钮”(不是一个),程序应该用循环的方式来遍历“每一个按钮”,而不是直接去直观的“按钮2设置颜色、按钮2设置颜色,。。。。按钮N设置颜色”。第一次我选用了循环遍历控件ID下标方式,以下程序是选择了两个静态控件做例子:


使用VC创建一个基于对话框的程序,上面添加两个静态文本框(IDC_STATIC01、IDC_STATIC02)和一个按钮,两个静态文本框分别关联CLabel类:

在头文件中:

CLabel m1;

CLabel m2;

在实现cpp文件初始化函数OnInitDialog中:

m1.SubclassDlgItem(IDC_STATIC01,this);

m2.SubclassDlgItem(IDC_STATIC02,this);

在cpp实现文件中,写一个让它闪烁的函数:

//
// 奇数时为红色,偶数时为绿色
//
void CTest2Dlg::SetColors(int x)
{
	int i;

	for (i=IDC_STATIC01; i<=IDC_STATIC02;i++)
	{	

		if(x%2)
		{
			CLabel *p = ((CLabel *)GetDlgItem(i));
			p->SetBkColor(RGB(0, 255, 0));	
		}
		else
		{
			CLabel *p = ((CLabel *)GetDlgItem(i));
			p->SetBkColor(RGB(255, 0, 0));
		}
	}
}

这个成员函数,大家可以使用按钮事件来调用它,一切都是正常(闪烁)的:

void CTest2Dlg::OnOK() 
{
	static y=0;
	SetColors(y++);
}
也可以使用SetTimer调用,也是正常闪烁的:

void CTest2Dlg::OnOK() 
{

	SetTimer(1, 100, 0);
}


void CTest2Dlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	static int x=0;
	SetColors(x++);
	CDialog::OnTimer(nIDEvent);
}

但是这样就不正常了:在按钮事件中创建一个线程MyControllingFunction,在线程函数中调用SetColors:

void CTest2Dlg::OnOK() 
{
	AfxBeginThread(MyControllingFunction, this);
}


UINT  MyControllingFunction( LPVOID pParam )
{
	CTest2Dlg *p = (CTest2Dlg *)pParam;
	int x = 0;
	while(1)
	{
		Sleep(100);

		p->SetColors(x++);
	}

	return 1L;
}

报错:MFC42D!CFrameWnd::'RTTI Base Class Descriptor at .........,分别将线程函数设置为静态类成员函数和友元函数,问题依旧,百思不得其解!


好像是

CLabel *p = ((CLabel *)GetDlgItem(i));

转换类型时失败,但是为何在按钮事件(或者时钟触发事件)中直接调用,又不失败呢?

最后的解决办法:不使用控件ID下标循环:

定义时:

	CLabel	m[2];
关联时:

for (int i=0; i<2; i++)
	{
		m[i].SubclassDlgItem(IDC_STATIC01+i,this);
	}

设置闪烁颜色时:

void CTest2Dlg::SetColors(int x)
{
	int i;

	for (i=0; i<=2;i++)
	{	

		if(x%2)
		{

			m[i].SetBkColor(RGB(0, 255, 0));
		}
		else
		{
			m[i].SetBkColor(RGB(255, 0, 0));
		}
	}
}

因为起到了同样的遍历静态控件的效果,只好暂时到此为止。

观察CLabel的源码,没看出什么问题,并且自己也尝试写过一个CColorStatic类(只是实现设置背景颜色),在http://blog.youkuaiyun.com/dijkstar/article/details/7184752,用第一方式调用(线程函数循环ID下标),是正常的!更加百思不得其解,先到此。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值