Timers (WM_TIMER, SetTimer, KillTimer)

Started by
6 comments, last by Sponge99 22 years, 9 months ago
I''m trying to use the windows basic timers for my game. I set a timer for 500 milliseconds with and ID of 1 and no TIMERPROC. I have a WM_TIMER message capturer thingy (don''t know what it''s called) in my WinProc, but it doesn''t work.

case WM_TIMER:			// wParam = timer ID
		{
			if (wParam == 1)
			{
				Lights_Draw(hWnd, OFF, LightCurrent->color);
				KillTimer(hWnd, 1);

				if (LightCurrent->next != NULL)
				{
					LightCurrent = LightCurrent->next;
					Lights_Draw(hWnd, ON, LightCurrent->color);
					SetTimer(hWnd, 1, 500, NULL);
				}
				else
				{
					playstate = USERIN;
					lights_pressed = 0;
					game_length++;
				}
			}

			break;
		}
 
It only seems to work when there is another action going on, like I''m pulling down a menu. Otherwise, it just loops on LightCurrent->color, never advancing to LightCurrent->next. Why is this? I''m getting really annoyed, and its stopped all other progress. I could you give more code if you really want to solve it and need it, but I won''t waste space here. Thanks!
"Now watch as I run away in a womanly fashion." - Batman
Advertisement
I''m not entirely sure what''s happening here, do you mean the WM_TIMER message never gets to your window?

Remember that WM_TIMER is a very low priority message. If there''s a higher priority one (e.g. WM_PAINT or something) then WM_TIMER might be lost.


War Worlds - A 3D Real-Time Strategy game in development.
For my games, I make my own timers and time them with timeGetTime. That would probably be easier to begin with. But as for your code, I''m not sure. It looks to me that, so long as you created a timer with a timer ID of 1, then you should be recieving the message. So long as LightCurrent->next is not NULL, it should be set every 500 ms like you shown. That''s why I don''t think it''s a problem with the timer, but probably the code used to handle it or to start it.
quote:Original post by Dean Harding
Remember that WM_TIMER is a very low priority message. If there''s a higher priority one (e.g. WM_PAINT or something) then WM_TIMER might be lost.

War Worlds - A 3D Real-Time Strategy game in development.


How could I get around it''s low priority? Just place the timer code as the first in my winproc? Above WM_PAINT?
"Now watch as I run away in a womanly fashion." - Batman
Check out Windows Course files at:
http://clio.mit.csu.edu.au/subjects/itc226/
quote:Original post by Sponge99
How could I get around it''s low priority? Just place the timer code as the first in my winproc? Above WM_PAINT?


No, the message acts differently in the system message queue because it''s a timer message. Basically, there is only one timer message allowed at one time, and all other messages take precedence (i.e. when you Peek/GetMessage, the timer won''t be what you see if there''s a more important message).

Typically, the way you work around this is to not use timer messages (i.e. manually check GetTickCount) or use another thread that''s on a timer but posts a user-defined message to the window you want updated. This is cake in MFC, but I''m not sure how you''d do it in win32-native, sorry.

How about this function:
 void wait ( int seconds ){  clock_t endwait;  endwait = clock () + seconds * CLK_TCK ;  while (clock() < endwait) {}} 


Well I hope this might help, (if you want to work in milliseconds, change the int to float, double, whatever.)

------------------------------
-Last Attacker
ICQ: 120585863
E-mail: laextr@icqmail.com
"Take delight in the Lord and He will give you your heart's desires" - Psalm 37:4My Blog
I suspect the comment about WM_TIMER being low priority would be the problem.

Are you handling your WM_PAINT messages? If you aren''t, then the message will just stick in the message queue and stay there until you do. So you''ll never even receive the WM_TIMER message...

ValidateRect(wnd, NULL); // might be all you need...

This topic is closed to new replies.

Advertisement