我用VC的类向导生成了一个基于CWnd的类,在类里面我想用到计时器,但当程序一旦执行到SetTimer(...)时,程序就崩溃了,请高手指点代码节选如下:
CMyClass : public CWnd
{
    ...    public:
BOOL Stop();
BOOL Start();    protected:
//{{AFX_MSG(CMyClass)
afx_msg void OnTimer(UINT nIDEvent);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
}
BEGIN_MESSAGE_MAP(CMyClass, CWnd)
//{{AFX_MSG_MAP(CMyClass)
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMyClass message handlersvoid CMyClass::OnTimer(UINT nIDEvent) 
{
// TODO: Add your message handler code here and/or call default

CWnd::OnTimer(nIDEvent);
}BOOL CMyClass::Start()
{
SetTimer(1, 10000,NULL );
return TRUE;
}
BOOL CMyClass::Stop()
{
KillTimer(1);//销毁定时器
return TRUE;
}以下是使用该类:class CHelloDlg : public CDialog
{
    ....    CMyClass myclass;    afx_msg void OnStart();
}
void CHelloDlg::OnStart() 
{
// TODO: Add your control notification handler code here
myclass.Start();
}

解决方案 »

  1.   

    我测试了一下,
    发现你的CMyClass myclass对象没有初始化成功,返回的是0x000000
    所以在调用settimer的时候需要断言ASSERT(::IsWindow(m_hWnd))这里跳出
      

  2.   

    先要创建窗口 myclass.Create() 
      

  3.   

    m_nTimer = SetTimer(1, 10000,NULL );KillTimer(m_nTimer);   
    void CALLBACK EXPORT TimerProc(HWND hWnd, // handle of CWnd that called SetTimerUINT nMsg, // WM_TIMERUINT nIDEvent // timer identificationDWORD dwTime // system time);
      

  4.   

    smaltdd,请问没有初始化成功是怎么回事?谢谢
      

  5.   

    同意1楼的说法,对象没有初始化BOOL CvidiconDlg::OnInitDialog()
    {
      ....
      myclass = NULL;  myclass = new CmyClass;}
      

  6.   


    你继承了Cwnd类,这个类是一个窗口类,需要你create一个窗口或者控件出来,而你的CMyclass自己什么都没有做,所以初始化的时候空的窗口指针。。
      

  7.   


    谢谢!发现Create()有很多参数,我毕竟不是很懂MFC,有点怕麻烦,请问有没有其它更方便的基类可以使用Timer的?说明:CMyClass 继承CWnd,只是想用计时器,不使用其它CWnd的特征
      

  8.   

    1、不用窗口的话,自己写timer处理的回调函数。具体查看MSDN中SetTimer函数。SetTimer
    The SetTimer function creates a timer with the specified time-out value. UINT_PTR SetTimer(
      HWND hWnd,              // handle to window
      UINT_PTR nIDEvent,      // timer identifier
      UINT uElapse,           // time-out value
      TIMERPROC lpTimerFunc   // timer procedure
    );
    Parameters
    hWnd 
    [in] Handle to the window to be associated with the timer. This window must be owned by the calling thread. If this parameter is NULL, no window is associated with the timer and the nIDEvent parameter is ignored. 
    nIDEvent 
    [in] Specifies a nonzero timer identifier. If the hWnd parameter is NULL, this parameter is ignored. 
    If the hWnd parameter is not NULL and the window specified by hWnd already has a timer with the value nIDEvent, then the existing timer is replaced by the new timer. When SetTimer replaces a timer, the timer is reset. Therefore, a message will be sent after the current time-out value elapses, but the previously set time-out value is ignored. uElapse 
    [in] Specifies the time-out value, in milliseconds. 
    lpTimerFunc 
    [in] Pointer to the function to be notified when the time-out value elapses. For more information about the function, see TimerProc. 
    If lpTimerFunc is NULL, the system posts a WM_TIMER message to the application queue. The hwnd member of the message's MSG structure contains the value of the hWnd parameter. 2、使用线程来代替计时器。
      

  9.   

    看楼主的定时器窗口类,无非是想实现定时器的功能,不想显示窗口。所以可以使用不带窗口句柄的API实现定时的功能
    timeSetEvent
    timeKillEvent
    详细使用方法参看
    http://cache.baidu.com/c?m=9d78d513d9d431ab4f9a96690c66c0171843f0152ba6a10208d38449e3732b455015e9ac56510774d0d27d1716de4d4b9ef52235775d2feddd8eca5ddcc88f356acd6223706bc71e54890eafbc11738637902db8f304b7eab161cfffc5d3a816098844040ec2a3cd001715bc78f0133197f3d915521d51aded37658b0f206dc87d1df450f997663d4496f6da5c38a771912642c9de22b03912c177d5081c5038d729a60f255b4e962b56e8443a04e69f2e843d794723c22de8e597ebae3edb9db377c5b8dcaf28951499d2ea8e7a427658ff25b8a0b8a53d1336&p=882a9445c0950af909a7c771094b&user=baidu
      

  10.   

    你用CWnd派生类的目的是什么?如果不是要使用窗口,就不需要这样派生类,把定时放在CHelloDlg类中。
      

  11.   

    解决了,谢谢回贴的各位兄弟,谢谢baosanr!我不想让其它类来干预这个定时函数,也不想把问题搞得太复杂,所以我最终采用了baosanr的timeSetEvent方法。具体代码如下:
    #include <mmsystem.h>
    #pragma comment(lib,"winmm.lib") class CMyClass  
    {
    public:
    CMyClass();
    virtual ~CMyClass();
    BOOL Stop();
    BOOL Start();private:
    UINT TimerID;
    static void CALLBACK TimerProc(UINT wTimerID, UINT msg,DWORD dwUser,DWORD dwl,DWORD dw2);
    };
    BOOL CMyClass::Start()
    {
    TimerID = timeSetEvent(1000, 5, (LPTIMECALLBACK)TimerProc,(DWORD)this,TIME_PERIODIC);
    return TRUE;
    }
    BOOL CMyClass::Stop()
    {
    timeKillEvent(TimerID);
    return TRUE;
    }void CALLBACK CMyClass::TimerProc(UINT wTimerID, UINT msg,DWORD dwUser,DWORD dwl,DWORD dw2)
    {
    static i=0;
    TRACE("===== %2d ====\n",i++);
    }下午再结贴