【发布时间】:2018-06-24 14:13:10
【问题描述】:
背景
MFC 的CWnd::SetTimer 简单地调用WinAPI 的SetTimer。
_AFXWIN_INLINE UINT_PTR CWnd::SetTimer(UINT_PTR nIDEvent, UINT nElapse,
void (CALLBACK* lpfnTimer)(HWND, UINT, UINT_PTR, DWORD))
{ ASSERT(::IsWindow(m_hWnd)); return ::SetTimer(m_hWnd, nIDEvent, nElapse,
lpfnTimer); }
但是SetTimer 和CWnd::SetTimer 文件不一样。
1。 nIDEvent参数
SetTimer:
如果 hWnd 参数不是 NULL 并且 hWnd 指定的窗口已经有一个值为 nIDEvent 的计时器,然后现有的计时器被新的计时器替换。当 SetTimer 替换定时器时,定时器会被重置。
CWnd::SetTimer:
指定非零计时器标识符。如果计时器标识符是唯一的,则SetTimer返回相同的值。否则,SetTimer确定一个新的唯一值并返回它。对于窗口计时器(具有 NULL 回调函数),该值必须仅对于与当前窗口关联的其他窗口计时器是唯一的。对于回调计时器,该值对于所有进程中的所有计时器必须是唯一的。因此,当您创建回调计时器时,返回的值很可能与您指定的值不同。
SetTimer 不依赖回调参数,总是替换现有的定时器。但是CWnd::SetTimer依赖于回调参数,如果指定回调,可能会生成一个新的定时器ID,因为该值对于所有进程中的所有定时器必须是唯一的。
2。返回值
SetTimer:
如果函数成功并且 hWnd 参数不是 NULL,则返回值是一个非零整数。应用程序可以将 nIDEvent 参数的值传递给 KillTimer 函数以销毁计时器。
CWnd::SetTimer:
如果函数成功,则新定时器的定时器标识符。此值可能等于也可能不等于通过nIDEvent参数传入的值。应用程序应始终将返回值传递给 KillTimer 成员函数以终止计时器。
SetTimer 不会生成新的定时器 id,也不会返回定时器 id,所以调用 KillTimer 时带有 nIDEvent 参数。但是CWnd::SetTimer在某些情况下会生成新的计时器id,所以用返回值调用KillTimer。
那么,哪个文件是正确的?
我想使用带有回调的 WinAPI SetTimer,它可以在我的电脑上运行。但是如果某些平台没有替换现有的定时器,我无法接受回调定时器。
【问题讨论】:
-
我依赖
SetTimer()的记录行为,它似乎像宣传的那样工作。如果你真的想知道,你应该运行一些简单的测试。 -
当MFC和WinAPI文档有区别的时候,我一般都是靠后者。毕竟它是信息的主要来源。
-
尤其是在这种情况下,MFC 只是转发到 API。据我所知,MFC 文档在编写时是正确的,但 API 发生了变化,MFC 从未更新以匹配。
-
MFC 是否可以追溯到 16 位 Windows?在现代世界中,对“所有进程”的限制没有多大意义。
-
@MarkRansom,是的:MFC 于 1992 年与 Microsoft 的 C/C++ 7.0 编译器一起推出,用于 16 位版本的 Windows,作为 Windows API 的极薄的面向对象的 C++ 包装器(维基百科) .