无法设置CWinApp上的SetTimer函数

时间:2018-04-23 16:59:43

标签: c++ mfc

我目前正在制作一个C ++ MFC应用程序,我需要一个计时器来每隔30秒左右调用一个名为OnTimer的函数。现在,我有一个看起来像这样的课程:

class CMyApp : public CWinApp
{
    // Do some stuff...
    DECLARE_MESSAGE_MAP()

    BOOL InitInstance()
    {
        // m_pMainWnd is an object in CWinApp that allows me to render a window

        m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);

        // Do some stuff with this window

        ::SetTimer(NULL, 0, 30000, 0);
    }

    afx_msg void OnTimer(WPARAM wParam, LPARAM lParam)
    {
        // I want this function to execute every 30 seconds
        // This function manipulates the window
    }
}

BEGIN_MESSAGE_MAP(CMyApp, CWinApp)
    ON_THREAD_MESSAGE(WM_TIMER, OnTimer)
END_MESSAGE_MAP()

CMyApp theApp;

此方法确实可以调用OnTimer,但不是每30秒调用一次。事实上,OnTimer现在似乎每分钟被召唤数百次。我的问题是:如何设置班级的计时器?

我尝试过的事情

我尝试将用户扩展名从ON_THREAD_MESSAGE更改为ON_WM_TIMER,更改为ON_COMMAND,以及更改为ON_MESSAGE。对于任何不是ON_THREAD_MESSAGE的内容,我都会收到错误

error C2440: 'static_cast' : cannot convert from 'void (__thiscall CMyApp::* )(WPARAM,LPARAM)' to 'LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)'

我不确定,但我认为SetTimer可能正在操纵某些CWinApp特定功能,而CWnd SetTimer未被操作,并被设置为某个默认值。不过,我在这里很黑暗,任何帮助都会受到赞赏。

1 个答案:

答案 0 :(得分:3)

ON_THREAD_MESSAGE适用于用户定义的消息,而不是WM_TIMER

根据SetTimer文档,窗口句柄必须有效,并且计时器标识符必须为非零才能创建新计时器。例如:

::SetTimer(m_pMainWnd->m_hWnd, 1, 30000, NULL);
or 
m_pMainWnd->SetTimer(1, 30000, NULL);

可以在主GUI窗口中处理消息。例如CMainFrameCMyCMDIFrameWndm_pMainWnd指向的任何内容。

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
    ON_WM_TIMER()
    ...
END_MESSAGE_MAP()

void CMainFrame::OnTimer(UINT id)
{
    TRACE("OnTimer(%d)\n", id);
}

或者,您可以在NULL中使用::SetTimer进行窗口处理,但必须提供回调函数:

VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
    TRACE("TimerProc\n");
}

::SetTimer(NULL, 2, 30000, TimerProc);