我目前正在制作一个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未被操作,并被设置为某个默认值。不过,我在这里很黑暗,任何帮助都会受到赞赏。
答案 0 :(得分:3)
ON_THREAD_MESSAGE
适用于用户定义的消息,而不是WM_TIMER
根据SetTimer文档,窗口句柄必须有效,并且计时器标识符必须为非零才能创建新计时器。例如:
::SetTimer(m_pMainWnd->m_hWnd, 1, 30000, NULL);
or
m_pMainWnd->SetTimer(1, 30000, NULL);
可以在主GUI窗口中处理消息。例如CMainFrame
,CMyCMDIFrameWnd
或m_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);