Archived

This topic is now archived and is closed to further replies.

Message Loops and PeekMessage

This topic is 5587 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all, I''m using VB but I''m hoping C/C++/Windows coders will be the ones to help me out here. I''m writing a game engine using DirectX and VB. I decided to write the windows code and message loop myself (instead of using VB Forms). I used some of the Windows API functions I''d learned while using C++ (I''m still a newbie in C++). And guess what, it all worked Here''s the code for my message loop:
  

Private Sub iWindows_MessageLoop(DoProcessing As iMessageLoop)
Dim Message As MSG
    Do While GetMessage(Message, 0, 0, 0)
        DispatchMessage Message
        DoProcessing.DoProcessing
    Loop
End Sub

  
The only problem was, that the GetMessage function waits for a message to be put in the queue. It''s not a good idea in a demanding program such as a 3D game to spend most of your processing time waiting for a windows message. So I rewrote the function to be more aggressive, with PeekEvents like this:
  

Private Sub iWindows_MessageLoop(DoProcessing As iMessageLoop)
Dim Message As MSG
    Do
        If PeekMessage(Message, 0, 0, 0, PM_REMOVE) Then
            If (Message.Message = WM_QUIT) Then
                Exit Do
            Else
                DispatchMessage Message
            End If
        End If
        DoProcessing.DoProcessing
    Loop
End Sub

  
Which also worked, and was alot more efficient! I was really happy... until I switched the focus to another window At which point it seemed to freeze up my whole computer to the point where I could do nothing but reboot it. I tried it again, just to see if it was a fluke, but it wasn''t. This is bad because I''ve only seen Windows XP crash once in 8 months I''ve had it So... what am I doing wrong? I know that adding DoEvents will get rid of the problem, but doesn''t that defy the purpose of using PeekEvents? Any help will be much appreciated. Thanks

Share this post


Link to post
Share on other sites
OK, so I found that the code doesn''t totally freeze Windows... but slows it down rediculously... such as the cursor moves only once every 10 seconds etc. I''ve tried everything to do with PeekMessage but still I have this problem. I''ve checked all the MSDN documentation on it but still can''t figure it out. Does nobody have any ideas?

Share this post


Link to post
Share on other sites
Use taskmanager to see if when you exit your application that its process dies with it. Sometimes it wont depending on how you handle your messages. If so then the problem is that there are several processes running in the Task Manager from previous instances of your application.

Share this post


Link to post
Share on other sites
Looking at the task manager, the process shuts down correctly, as long as I keep the focus on the window all the time. If the window loses focus, thats when it freezes up and I use the task manager to get rid of it.

Share this post


Link to post
Share on other sites
I think you are DoProcessing-ing while you don't have any message to process. The DoProcessing should be below DispatchMessage, instead of outside the 'IF PeekMessage'.

[edited by - DerekSaw on August 26, 2002 11:25:42 PM]

Oooops.. I think you want to use the idle time. If so, try having a boolean variable to indicate whether you are on focus or not (set the variable under the message WM_ACTIVATEAPP or similar ). If not in focus, call WaitMessage.

    
Private Sub iWindows_MessageLoop(DoProcessing As iMessageLoop)
Dim Message As MSG
Do
If PeekMessage(Message, 0, 0, 0, PM_REMOVE) Then
If (Message.Message = WM_QUIT) Then
Exit Do
Else
DispatchMessage Message
End If
ELSE
IF bActivated THEN
DoProcessing.DoProcessing
ELSE
WaitMessage
ENDIF
End If
Loop
End Sub

I haven't touch VB for a long time. So there might be some syntax error.

[edited by - DerekSaw on August 26, 2002 11:27:57 PM]

Share this post


Link to post
Share on other sites
xDS4Lx, could you explain exactly what you mean by "preserving the DX state"? I''m not sure if the answer is yes or no, but I think you might be onto something there.

DerekSaw, thankyou I tried your suggestion, but it didn''t work. I think you misunderstood due to my badly named functions. The code I posted is inside my actual engine, in a DLL. DoProcessing is a very general function that must be implemented by a specific program using the engine. So DoProcessing could be doing literally anything a program wants to do - in my test case simply clearing the backbuffer with a random color, and then showing it. For performance reasons (I want a very high FPS in my games), the DoProcessing function must be called as often as possible, especially when there are no messages in the queue, as this is the best time to do some processing, I guess?

Share this post


Link to post
Share on other sites
DerekSaw, thankyou your second suggestion sounds alot better. I''ll try it I''ve been wondering how Visual Basic does all this stuff behind the scenes, when you use VB Forms.

Share this post


Link to post
Share on other sites
Is your application windowed or full-screen? If it is full screen, I suggest that you don''t draw anything to DX when your app is out of focus (for DX, your app should be automatically minimized, rite? . Maybe that slows down things... I may be wrong.

Share this post


Link to post
Share on other sites
quote:
Original post by bazee
I decided to write the windows code and message loop myself (instead of using VB Forms).

Just because you have no forms in your app, doesn''t mean there''s no message pump. Every VB app has one, regardless of whether or not there''s forms in the app. Why not just let Windows handle it? Why did you feel the need to do this anyway? If you''re worried about input, use DirectInput.

Share this post


Link to post
Share on other sites
Thankyou! DerekSaw your solution works perfectly

My application is both windowed and fullscreen, you can switch between them at run time by pressing a key (later on I will put this function on an options screen or something).

Machaira, I felt the need to do this for several reasons.

- Curiosity. I''m learning lots. Also, when I move onto C++ this will also be essential knowledge.

- Control. My own window object can do alot more than a VB form can.

- Performance. I''m not sure if there will be much of a performance increase, but I won''t know unless I try.

- Lean-ness (I need a better word, lol). VB Forms do alot of things which I don''t need for a simple DX window.

There remain a few unanswered questions, but I think I can figure them myself from here.

How comes the application freezes up without this extra code? I''m assuming its just because it falls into a very tight loop.

How do I go about creating an application with multiple windows? I guess I must only stop processing if all windows are inactive.

And what if my application has no windows at all? How do I know when I''m inactive then? I guess I will have to voluntarily become inactive every so often to avoid hogging CPU.

See, a stupid VB programmer is becoming more enlightened

Share this post


Link to post
Share on other sites
Testing the performance, the FPS seems to have have gone from 68 to 90 FPS, consistently and this is for code that does exactly the same thing (I''m only commenting out 1 line of code for another to switch between VB forms and my own windows, both implementations are using the same interface). So I guess it really was worth my (and everyone who answered to my post)''s trouble.

Share this post


Link to post
Share on other sites
I''m making an online multiplayer RPG. So far I''ve got multiple players running around a randomly generated 3D landscape. But, thats all so far... no building, fighting, magic etc. Ofcourse, I plan to put this all in eventually. While I''m waiting for further design docs I have been refining the engine. Until now it had used a VB form. I''m using quadtrees together with dynamic level of detail to make the game fast... but then I figured just improving the basic message loop would be far more worthwhile, since it only took a day and gave a huge benefit. It took me ages to do the other stuff (well, 8 months). As soon as I get time, I''ll put up a website about the game.

Share this post


Link to post
Share on other sites