windows-nt/Source/XPSP1/NT/base/mvdm/wow32/wutmr.c

771 lines
22 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
*
* WOW v1.0
*
* Copyright (c) 1991, Microsoft Corporation
*
* WUTMR.C
* WOW32 16-bit User Timer API support
*
* History:
* Created 07-Mar-1991 by Jeff Parsons (jeffpar)
* 24-Feb-1993 reworked to use array of timer functions - barryb
--*/
#include "precomp.h"
#pragma hdrstop
MODNAME(wutmr.c);
LIST_ENTRY TimerList;
// Element Zero is unused.
STATIC PTMR aptmrWOWTimers[] = {
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL
};
STATIC TIMERPROC afnTimerFuncs[] = {
NULL, W32Timer1, W32Timer2, W32Timer3,
W32Timer4, W32Timer5, W32Timer6, W32Timer7,
W32Timer8, W32Timer9, W32Timer10, W32Timer11,
W32Timer12, W32Timer13, W32Timer14, W32Timer15,
W32Timer16, W32Timer17, W32Timer18, W32Timer19,
W32Timer20, W32Timer21, W32Timer22, W32Timer23,
W32Timer24, W32Timer25, W32Timer26, W32Timer27,
W32Timer28, W32Timer29, W32Timer30, W32Timer31,
W32Timer32, W32Timer33, W32Timer34
};
/* Timer mapping functions
*
* The basic 16-bit timer mapping operations are Add, Find and Free. When
* a 16-bit app calls SetTimer, we call Win32's SetTimer with W32TimerProc
* in place of the 16-bit proc address. Assuming the timer is successfully
* allocated, we add the timer to our own table, recording the 16-bit proc
* address.
*/
//
// Search for a timer by its 16-bit information. Looks in the list of
// active timers. If the timer is found by this routine, then SetTimer()
// has been called and KillTimer() has not yet been called.
//
PTMR IsDuplicateTimer16(HWND16 hwnd16, HTASK16 htask16, WORD wIDEvent)
{
register PTMR ptmr;
register INT iTimer;
//
// Excel calls SetTimer with hwnd==NULL but dispatches the
// WM_TIMER messages with hwnd!=NULL. so call it a match if
// hwnd16!=NULL and ptmr->hwnd16==NULL
//
for (iTimer=1; iTimer<NUMEL(aptmrWOWTimers); iTimer++) {
ptmr = aptmrWOWTimers[iTimer];
if (ptmr) {
if (LOWORD(ptmr->dwEventID) == wIDEvent &&
ptmr->htask16 == htask16 &&
(ptmr->hwnd16 == hwnd16 || !ptmr->hwnd16)) {
return ptmr;
}
}
}
return NULL;
}
//
// This is called to free *ALL* timers created with a given hwnd16
// ie. All timers created by SetTimer(hwnd != NULL, id, duration)
// This should only be called when the hwnd is being destroyed: DestroyWindow()
//
VOID FreeWindowTimers16(HWND hwnd32)
{
register PTMR ptmr;
register INT iTimer;
HAND16 htask16;
htask16 = CURRENTPTD()->htask16;
for (iTimer=1; iTimer<NUMEL(aptmrWOWTimers); iTimer++) {
ptmr = aptmrWOWTimers[iTimer];
if (ptmr) {
if (ptmr->htask16 == htask16 && GETHWND16(hwnd32) == ptmr->hwnd16) {
// we can't wait for Win32 to kill the timer for us during its
// normal DestroyWindow() handling because it might send another
// WM_TIMER message which we are now not ready to handle.
KillTimer(ptmr->hwnd32, ptmr->dwEventID);
// now free our WOW structures supporting this timer
FreeTimer16(ptmr);
}
}
}
}
//
// Search for a timer by its 32-bit information. Looks in the list of
// all timers (including those that have already been killed by KillTimer().
//
//
PTMR FindTimer32(HWND16 hwnd16, DWORD dwIDEvent)
{
register PTMR ptmr;
HAND16 htask16;
htask16 = CURRENTPTD()->htask16;
//
// Excel calls SetTimer with hwnd==NULL but dispatches the
// WM_TIMER messages with hwnd!=NULL. so call it a match if
// hwnd16!=NULL and ptmr->hwnd16==NULL
//
for (ptmr = (PTMR)TimerList.Flink; ptmr != (PTMR)&TimerList; ptmr = (PTMR)ptmr->TmrList.Flink) {
if (ptmr->dwEventID == dwIDEvent &&
ptmr->htask16 == htask16 &&
(ptmr->hwnd16 == hwnd16 || (hwnd16 && !ptmr->hwnd16))) {
return ptmr;
}
}
return (PTMR)NULL;
}
//
// Search for a timer by its 16-bit information. Looks in the list of
// all timers (including those that have already been killed by KillTimer().
//
//
PTMR FindTimer16(HWND16 hwnd16, HTASK16 htask16, WORD wIDEvent)
{
register PTMR ptmr;
//
// Excel calls SetTimer with hwnd==NULL but dispatches the
// WM_TIMER messages with hwnd!=NULL. so call it a match if
// hwnd16!=NULL and ptmr->hwnd16==NULL
//
for (ptmr = (PTMR)TimerList.Flink; ptmr != (PTMR)&TimerList; ptmr = (PTMR)ptmr->TmrList.Flink) {
if (LOWORD(ptmr->dwEventID) == wIDEvent &&
ptmr->htask16 == htask16 &&
(ptmr->hwnd16 == hwnd16 || (hwnd16 && !ptmr->hwnd16))) {
return ptmr;
}
}
return (PTMR)NULL;
}
//
// Search for a killed timer by its 16-bit information.
//
//
PTMR FindKilledTimer16(HWND16 hwnd16, HTASK16 htask16, WORD wIDEvent)
{
register PTMR ptmr;
for (ptmr = (PTMR)TimerList.Flink; ptmr != (PTMR)&TimerList; ptmr = (PTMR)ptmr->TmrList.Flink) {
if (ptmr->wIndex == 0 &&
ptmr->htask16 == htask16 &&
ptmr->hwnd16 == hwnd16 &&
(LOWORD(ptmr->dwEventID) == wIDEvent || !hwnd16)) {
// 1. the timer has been killed and
// 2. the timer is in this task and
// 3. the hwnds match (both might be 0) and
// 4. the IDs match, or the hwnds are both 0 (in that case,
// IDs are ignored)
return ptmr;
}
}
return (PTMR)NULL;
}
VOID FreeTimer16(PTMR ptmr)
{
WOW32ASSERT(ptmr->wIndex == 0 || ptmr == aptmrWOWTimers[ptmr->wIndex]);
aptmrWOWTimers[ptmr->wIndex] = NULL;
RemoveEntryList(&ptmr->TmrList);
free_w(ptmr);
}
VOID DestroyTimers16(HTASK16 htask16)
{
PTMR ptmr, next;
for (ptmr = (PTMR)TimerList.Flink; ptmr != (PTMR)&TimerList; ptmr = next) {
next = (PTMR)ptmr->TmrList.Flink;
if (ptmr->htask16 == htask16) {
//
// don't call KillTimer() if the timer was associated with
// a window and the window is gone, USER has already
// cleaned it up.
//
if (ptmr == aptmrWOWTimers[ptmr->wIndex] && (!ptmr->hwnd32 || IsWindow(ptmr->hwnd32))) {
if ( KillTimer(ptmr->hwnd32, ptmr->dwEventID) ) {
LOGDEBUG(LOG_IMPORTANT,
("DestroyTimers16:Killed %04x\n",ptmr->dwEventID));
} else {
LOGDEBUG(LOG_ERROR,
("DestroyTimers16:FAILED %04x\n",ptmr->dwEventID));
}
}
FreeTimer16(ptmr);
}
}
}
VOID W32TimerFunc(UINT index, HWND hwnd, UINT idEvent, DWORD dwTime)
{
PARM16 Parm16;
register PTMR ptmr;
ptmr = aptmrWOWTimers[index];
if ( !ptmr ) {
LOGDEBUG(LOG_ALWAYS,(" W32TimerFunc ERROR: cannot find timer %08x\n", idEvent));
return;
}
if (ptmr->dwEventID != idEvent) {
//
// This is an extra timer message which was already in the message
// queue when the app called KillTimer(). The PTMR isn't in the
// array, but it is still linked into the TimerList.
//
LOGDEBUG(LOG_WARNING,(" W32TimerFunc WARNING: Timer %08x called after KillTimer()\n", idEvent));
for (ptmr = (PTMR)TimerList.Flink; ptmr != (PTMR)&TimerList; ptmr = (PTMR)ptmr->TmrList.Flink) {
if (ptmr->dwEventID == idEvent) {
break;
}
}
if ( ptmr == (PTMR)&TimerList ) {
LOGDEBUG(LOG_ALWAYS,(" W32TimerFunc ERROR: cannot find timer %08x (second case)\n", idEvent));
return;
}
}
Parm16.WndProc.hwnd = ptmr->hwnd16;
Parm16.WndProc.wMsg = WM_TIMER;
Parm16.WndProc.wParam = LOWORD(ptmr->dwEventID);
Parm16.WndProc.lParam = dwTime;
Parm16.WndProc.hInst = 0; // callback16 defaults to ss
CallBack16(RET_WNDPROC, &Parm16, ptmr->vpfnTimerProc, NULL);
}
/*++
BOOL KillTimer(<hwnd>, <nIDEvent>)
HWND <hwnd>;
INT <nIDEvent>;
The %KillTimer% function kills the timer event identified by the <hwnd> and
<nIDEvent> parameters. Any pending WM_TIMER messages associated with the
timer are removed from the message queue.
<hwnd>
Identifies the window associated with the given timer event. This must
be the same value passed as the hwnd parameter to the SetTimer function
call that created the timer event.
<nIDEvent>
Specifies the timer event to be killed. If the application called
%SetTimer% with the <hwnd> parameter set to NULL, this must be the event
identifier returned by %SetTimer%. If the <hwnd> parameter of %SetTimer%
was a valid window handle, <nIDEvent> must be the value of the
<nIDEvent> parameter passed to %SetTimer%.
The return value specifies the outcome of the function. It is TRUE if the
event was killed. It is FALSE if the %KillTimer% function could not find the
specified timer event.
--*/
ULONG FASTCALL WU32KillTimer(PVDMFRAME pFrame)
{
ULONG ul;
register PTMR ptmr;
register PKILLTIMER16 parg16;
HWND16 hwnd16;
WORD wIDEvent;
HAND16 htask16;
GETARGPTR(pFrame, sizeof(KILLTIMER16), parg16);
htask16 = CURRENTPTD()->htask16;
hwnd16 = (HWND16)parg16->f1;
wIDEvent = parg16->f2;
ptmr = IsDuplicateTimer16(hwnd16, htask16, wIDEvent);
if (ptmr) {
ul = GETBOOL16(KillTimer(ptmr->hwnd32, ptmr->dwEventID));
aptmrWOWTimers[ptmr->wIndex] = NULL;
ptmr->wIndex = 0;
}
else {
ul = 0;
LOGDEBUG(LOG_IMPORTANT,(" WU32KillTimer ERROR: cannot find timer %04x\n", wIDEvent));
}
FREEARGPTR(parg16);
RETURN(ul);
}
/*++
WORD SetTimer(<hwnd>, <nIDEvent>, <wElapse>, <lpTimerFunc>)
HWND <hwnd>;
int <nIDEvent>;
WORD <wElapse>;
FARPROC <lpTimerFunc>;
The %SetTimer% function creates a system timer event. When a timer event
occurs, Windows passes a WM_TIMER message to the application-supplied
function specified by the <lpTimerFunc> parameter. The function can then
process the event. A NULL value for <lpTimerFunc> causes WM_TIMER messages
to be placed in the application queue.
<hwnd>
Identifies the window to be associated with the timer. If hwnd is NULL,
no window is associated with the timer.
<nIDEvent>
Specifies a nonzero timer-event identifier if the <hwnd> parameter
is not NULL.
<wElapse>
Specifies the elapsed time (in milliseconds) between timer
events.
<lpTimerFunc>
Is the procedure-instance address of the function to be
notified when the timer event takes place. If <lpTimerFunc> is NULL, the
WM_TIMER message is placed in the application queue, and the %hwnd%
member of the %MSG% structure contains the <hwnd> parameter given in the
%SetTimer% function call. See the following Comments section for
details.
The return value specifies the integer identifier for the new timer event.
If the <hwnd> parameter is NULL, an application passes this value to the
%KillTimer% function to kill the timer event. The return value is zero if
the timer was not created.
Timers are a limited global resource; therefore, it is important that an
application check the value returned by the %SetTimer% function to verify
that a timer is actually available.
To install a timer function, %SetTimer% must receive a procedure-instance
address of the function, and the function must be exported in the
application's module-definition file. A procedure-instance address can be
created using the %MakeProcInstance% function.
The callback function must use the Pascal calling convention and must be
declared %FAR%.
Callback Function:
WORD FAR PASCAL <TimerFunc>(<hwnd>, <wMsg>, <nIDEvent>, <dwTime>)
HWND <hwnd>;
WORD <wMsg>;
int <nIDEvent>;
DWORD <dwTime>;
<TimerFunc> is a placeholder for the application-supplied function name. The
actual name must be exported by including it in an %EXPORTS% statement in
the application's module-definition file.
<hwnd>
Identifies the window associated with the timer event.
<wMsg>
Specifies the WM_TIMER message.
<nIDEvent>
Specifies the timer's ID.
<dwTime>
Specifies the current system time.
--*/
ULONG FASTCALL WU32SetTimer(PVDMFRAME pFrame)
{
ULONG ul;
register PTMR ptmr;
register PSETTIMER16 parg16;
HWND16 hwnd16;
WORD wIDEvent;
WORD wElapse;
DWORD vpfnTimerProc;
DWORD dwTimerProc32;
HAND16 htask16;
INT iTimer;
GETARGPTR(pFrame, sizeof(SETTIMER16), parg16);
ul = 0;
htask16 = CURRENTPTD()->htask16;
hwnd16 = (HWND16)parg16->f1;
wIDEvent = parg16->f2;
wElapse = parg16->f3;
// Don't allow WOW apps to set a timer with a period of less than
// 55 ms. Myst and Winstone depend on this.
if (wElapse < 55) wElapse = 55;
vpfnTimerProc = VPFN32(parg16->f4);
ptmr = IsDuplicateTimer16(hwnd16, htask16, wIDEvent);
if (!ptmr) {
// Loop through the slots in the timer array
iTimer = 2;
while (iTimer < NUMEL(aptmrWOWTimers)) {
/*
** Find a slot in the arrays for which
** no pointer has yet been allocated.
*/
if ( !aptmrWOWTimers[iTimer] ) {
//
// See if there is already thunking information for this
// timer. If there is, delete it from the list of timer
// info and re-use its memory because this new timer
// superceeds the old thunking information.
//
ptmr = FindKilledTimer16(hwnd16, htask16, wIDEvent);
if (ptmr) {
RemoveEntryList(&ptmr->TmrList);
} else {
// Allocate a TMR structure for the new timer
ptmr = malloc_w(sizeof(TMR));
}
aptmrWOWTimers[iTimer] = ptmr;
if (!ptmr) {
LOGDEBUG(LOG_ALWAYS,(" WOW32 ERROR: TMR allocation failure\n"));
return 0;
}
break; // Fall out into initialization code
}
iTimer++;
}
if (iTimer >= NUMEL(aptmrWOWTimers)) {
LOGDEBUG(LOG_ALWAYS,(" WOW32 ERROR: out of timer slots\n"));
return 0;
}
// Initialize the constant parts of the TMR structure (done on 1st SetTimer)
InsertHeadList(&TimerList, &ptmr->TmrList);
ptmr->hwnd16 = hwnd16;
ptmr->hwnd32 = HWND32(hwnd16);
ptmr->htask16 = htask16;
ptmr->wIndex = (WORD)iTimer;
}
// Setup the changeable parts of the TMR structure (done for every SetTimer)
if (vpfnTimerProc) {
dwTimerProc32 = (DWORD)afnTimerFuncs[ptmr->wIndex];
} else {
dwTimerProc32 = (DWORD)NULL;
}
ptmr->vpfnTimerProc = vpfnTimerProc;
ptmr->dwTimerProc32 = dwTimerProc32;
ul = SetTimer(
ptmr->hwnd32,
(UINT)wIDEvent,
(UINT)wElapse,
(TIMERPROC)dwTimerProc32 );
//
// USER-generated timerID's are between 0x100 and 0x7fff
//
WOW32ASSERT(HIWORD(ul) == 0);
if (ul) {
ptmr->dwEventID = ul;
//
// when hwnd!=NULL and nEventID==0 the API returns 1 to
// indicate success but the timer's ID is 0 as requested.
//
if (!wIDEvent && ptmr->hwnd32)
ptmr->dwEventID = 0;
} else {
// Since the real SetTimer failed, free
// our local data using simply our own timer ID
FreeTimer16(ptmr);
}
FREEARGPTR(parg16);
RETURN(ul);
}
VOID CALLBACK W32Timer1(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(1, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer2(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(2, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer3(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(3, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer4(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(4, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer5(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(5, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer6(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(6, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer7(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(7, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer8(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(8, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer9(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(9, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer10(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(10, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer11(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(11, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer12(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(12, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer13(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(13, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer14(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(14, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer15(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(15, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer16(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(16, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer17(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(17, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer18(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(18, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer19(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(19, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer20(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(20, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer21(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(21, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer22(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(22, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer23(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(23, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer24(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(24, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer25(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(25, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer26(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(26, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer27(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(27, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer28(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(28, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer29(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(29, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer30(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(30, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer31(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(31, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer32(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(32, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer33(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(33, hwnd, idEvent, dwTime);
}
VOID CALLBACK W32Timer34(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
{
WOW32ASSERT(msg == WM_TIMER);
W32TimerFunc(34, hwnd, idEvent, dwTime);
}