吵吵   2011-10-28  阅读:4,953

回调函数一直以来就是在vc中一个很有用的东西,尤其是面对事件驱动的时候。当事件产生的时候,你需要调用特定的函数来实现你的要做的事情,回调机制就显得相当重要了,说白了消息机制也是回调的一种啊。至于回调更有利于面向对象的发展什么的就不多说了,这次我们要看看如何回调类中的成员函数。

关于SetTimer如何使用回调函数,以及回调函数的写法参见:
vc使用SetTimer回调函数实现自定义类定时器解决方案

我们发现这已经产生了一个问题了,那就是我们的回调函数是静态的,静态函数也就不存在this指针的,当我们在自定义的类中使用了settimer后,系统会调用回调函数,在这个回调函数中已经没有了this指针,我们如何再调用自定义类的其它成员函数呢,如让一个int自加或者自减之类。

vc

在一般的回调函数中会有可以传递参数的,我们把this指针传入就ok,但是这个回调函数没有这个变量,怎么办?没有办法,就只好用全局变量来做了;

1、定义一个全局变量,为该类的指针。
CAlpha *pAlpha;

2、在构造函数中传递进去改类的指针:
CAlpha:: CAlpha(void)
:m_hWnd((HWND)INVALID_HANDLE_VALUE)
{
pAlpha=(CAlpha *)this;
}

3、在回调函数中使用该指针:

void CALLBACK CAlpha::TimerProc(HWND hwnd,UINT uMsg,UINT_PTR idEvent, DWORD dwTime)
{

pAlpha->AlphaPlus();

pAlpha->SetWindowAlpha(0,pAlpha->GetAlpha(),2);
if(pAlpha->GetAlpha()==255)
{
KillTimer(hwnd,idEvent);

}
}

然后在窗口类中测试一下自定义类的能不能用:
CAlpha alpha;
alpha.Create(this->GetSafeHwnd());
alpha.AlphaWindowShow();
发现原本渐变显示窗口用不了,再回到CAlpha自定义类中找到其中的pAlpha->GetAlpha()发现在定时回调的时候每次都是1,这个问题困扰了很多天,也费了我不少时间,总是想不通,一度认为类的指针在static的静态函数中失去了作用。

几天后偶尔突发奇想,试过之后才知道错在哪里,所以才有了这篇日志:

原来我们测试自定义的程序写错了,错在我将CAlpha alpha;写在了窗口类的一个成员函数中,那么当这个成员函数执行过后alpha这个类也就在内存中消失了,故timer的回调中再使用成员变量都变成0了。

想到这里才汗啊,其实用指针就很好解决这个问题,或者定义为窗口类的一个成员变量。我们选择用指针,就这么写:
CAlpha *alpha=new CAlpha;
alpha->Create(this->GetSafeHwnd());
alpha->AlphaWindowShow();
回头发现就好了,因为用指针new出来的变量需要自己释放才会在内存中清空的,为了试验一下我不停的按按钮,发现内存以每次24k的速度增长,哇,每new一个这个简单的类占用内存可不小啊。

为了让其自己卸载,在完成我们的功能后把自定义类给释放了,于是写在改渐变最后:
if(pAlpha->GetAlpha()==255)
{
KillTimer(hwnd,idEvent);
delete pAlpha;
}
回头再看内存,不增长了,用完这个类就释放了。这个宽口的动画类还没写完,写好了就共享出来啦。

吵吵微信朋友圈,请付款实名加入:

吵吵 吵吵

6条回应:“vc中SetTimer回调类的成员函数”

  1. 长沙律师说道:

    我来啦,来看看,博主又更新了呢

  2. 春妞说道:

    学习了

  3. 贺昌说道:

    技术,羡慕之后闪…

  4. 药浴说道:

    嗯 又有新的收获哦

  5. 99go99说道:

    高手啊,

  6. 地球博客说道:

    太深奥了,老朽看不懂啊。

发表评论

电子邮件地址不会被公开。 必填项已用*标注