我尝试将 mmTimer 与回调函数一起使用,这是一个静态 CALLBACK
函数。
我知道静态函数不能调用非静态函数,谢谢大家,除了静态函数获取指向对象的指针作为参数的情况。
奇怪的是,我的计时器在 Release模式下工作正常,当我尝试在 Debug模式下运行它时,会弹出一个未处理的异常并导致程序崩溃。
void CMMTimerDlg::TimerProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
CMMTimerDlg* p = (CMMTimerDlg*)dwUser;
if(p)
{
p->m_MMTimer += p->m_TimeDelay;
p->UpdateData(FALSE);
}
}
我的问题是: - 有什么办法可以解决这个问题吗? - 如果这个错误发生在 Debug模式下,谁能保证我一旦发布程序就不会发生这个错误?
程序停止的地方是:
#ifdef _DEBUG
void CWnd::AssertValid() const
{
if (m_hWnd == NULL)
return; // null (unattached) windows are valid
// check for special wnd??? values
ASSERT(HWND_TOP == NULL); // same as desktop
if (m_hWnd == HWND_BOTTOM)
ASSERT(this == &CWnd::wndBottom);
else if (m_hWnd == HWND_TOPMOST)
ASSERT(this == &CWnd::wndTopMost);
else if (m_hWnd == HWND_NOTOPMOST)
ASSERT(this == &CWnd::wndNoTopMost);
else
{
// should be a normal window
ASSERT(::IsWindow(m_hWnd));
// should also be in the permanent or temporary handle map
CHandleMap* pMap = afxMapHWND();
ASSERT(pMap != NULL);
当它到达 pMap 时,它会在该断言处停止!!!
这里是静态CALLBACK函数
static void CALLBACK TimerProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2);
这是我设置计时器的方法
UINT unTimerID = timeSetEvent(m_TimeDelay,1,(LPTIMECALLBACK)TimerProc,(DWORD)this,TIME_PERIODIC);
最佳答案
这里的问题是,多媒体计时器 API 与许多其他 API 不同,它对您在回调中可以执行的操作有限制。你基本上是not allowed much您可以更新内部结构,进行一些调试输出,并设置同步事件。
Remarks
Applications should not call any system-defined functions from inside a callback function, except for PostMessage, timeGetSystemTime, timeGetTime, timeSetEvent, timeKillEvent, midiOutShortMsg, midiOutLongMsg, and OutputDebugString.
断言失败会开始显示不允许的消息框,并最终可能导致进程崩溃。此外,诸如 IsWindow
之类的窗口 API 及其同类也是不允许的,它们是进一步导致断言失败的首要原因。
最好是完全避免使用多媒体计时器。在大多数情况下,您有限制较少的替代选项。
关于c - 多媒体计时器在 Release模式下工作正常,但在 Debug模式下工作不正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20310200/