Advertisement

Message Loops and PeekMessage

Started by August 26, 2002 05:58 PM
12 comments, last by bazee 22 years, 4 months ago
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
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?
Advertisement
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.
"Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music." - Kristian Wilson, Nintendo, Inc, 1989
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.
Well are you preserving the DX state when focus is lost? And are you restoring it properly when focus is regained?
"Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music." - Kristian Wilson, Nintendo, Inc, 1989
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 MSGDo          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 LoopEnd 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]
"after many years of singularity, i'm still searching on the event horizon"
Advertisement
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?
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.
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.
"after many years of singularity, i'm still searching on the event horizon"
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.

Former Microsoft XNA and Xbox MVP | Check out my blog for random ramblings on game development

This topic is closed to new replies.

Advertisement