Skip to main content
gamedev.net
🔒 Locked

[.net] Message Loop in .NET

Started by Shinkage Dec 10, 2005 at 5:46 PM 7 replies 11.8k views
Original Post
Shinkage
Shinkage
I've seen people asking here and there about the best way to implement a message loop in .NET, and wasn't able to locate any other posts on the topic, so I thought I'd share the way I do it, as much to get input on any potential problems with the technique as anything. Quite simply, I do it exactly the same way as I'd make a message loop when programming for the Windows API in C++. If you use C#, you need to mess around with P/Invoke stuff, but if you use Managed C++ it's just a matter of a few lines of code. So to start off with the Managed C++ version it's as simple as this...

#include <windows.h>
...
System::Windows::Form ^mainWindow;
...
// Here's your very simple message loop.
MSG message;
while(mainWindow->Created)
{
	while( PeekMessage( &message, (HWND)mainWindow->Handle.ToPointer(), 0, 0, PM_REMOVE ) )
	{
		TranslateMessage( &message );
		DispatchMessage( &message );
		if( !mainWindow->Created )
			break;
	}
}





My question is, is there anything wrong with handling Windows message processing this way? I haven't run into any problems, but my with .NET there's a hidden "gotchya" waiting in the shadows as often as not. One thing I should note, is that while it should be possible to do the same thing in C# by defining the necessary structures and importing the necessary functions (see www.pinvoke.net for a reference on how to do this), in my limited experience trying to do so it doesn't actually work. The problem is that calling PeekMessage seems to randomly throw exceptions for no discernable reason. Anybody have any experience that could shed some light on why this might be? I see that this problem is documented on the pinvoke.net site, but there's no indication of any solution. Specifically, I get this problem when I do the same as above using the following definitions (cut and pasted from pinvoke.net really)...

[StructLayout(LayoutKind.Sequential)]
public struct MSG
{
    public IntPtr hwnd;
    public uint message;
    public IntPtr wParam;
    public IntPtr lParam;
    public uint time;
    public POINT pt;
}

[DllImport("user32.dll")]
static extern bool PeekMessage(out MSG lpMsg, HandleRef hWnd, uint MsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);

[DllImport("user32.dll")]
static extern bool TranslateMessage([In] ref MSG lpMsg);

[DllImport("user32.dll")]
static extern IntPtr DispatchMessage([In] ref MSG lpmsg);





capn_midnight
capn_midnight
i've used the PeekMessage method in C# and it works wonderfully. It is significantly faster (I would wager at least 25%) than using a Timer or a while loop with Application.DoEvents() at the end. This PeekMessage method is even recommended by the Managed DirectX team itself.
Shinkage
Shinkage
Quote:
Original post by capn_midnight
i've used the PeekMessage method in C# and it works wonderfully. It is significantly faster (I would wager at least 25%) than using a Timer or a while loop with Application.DoEvents() at the end. This PeekMessage method is even recommended by the Managed DirectX team itself.


Hm, I'll admit it's been a while since I've tried it in C#... could be the problem I used to experience was fixed. Anybody else ever had problems with using PeekMessage in C# (or any .NET language other than Managed C++ where you don't have direct access to the platform SDK)?
Shinkage
Shinkage
Quote:
Original post by acid2
Would that be this post? Miller's blog is at: http://blogs.msdn.com/tmiller


Unless somebody wants to point out a flaw in the way I'm doing it, I think my method is superior to Tom Miller's because there's no event handling overhead and it allows you to fine tune exactly how much message processing gets done at any particular point (you could choose to only process a certain number of Windows messages per frame if you wanted for example).
thezbuffer
thezbuffer
This is the 'history' of the Managed DirectX render loop.

http://www.thezbuffer.com/articles/185.aspx

I don't know if there are any gotchas with your approach, maybe Tom was trying to strike a balance between speed/memory perf and yet not totally taking over the message processing.
ZMan
Rob Loach
Rob Loach
The Tao Framework might interest you as it's full of P/Invoked methods. To be more precise, P/Invoke binding to OpenGL, SDL, etc.
Rob Loach [Website] [Projects] [
Shinkage
Shinkage
Quote:
Original post by Rob Loach
The Tao Framework might interest you as it's full of P/Invoked methods. To be more precise, P/Invoke binding to OpenGL, SDL, etc.


I actually program in C++/CLI when I'm doing .NET work. All the goodness of the .NET platform and direct access to native code without all that mucking around with P/Invoke. Faster too since I believe there's a bit of overhead for P/Invoke calls. The talk about P/Invoke was just out of curiosity from when I tried it before in C# and got strange crashes.

Quote:
Original post by thezbuffer
I don't know if there are any gotchas with your approach, maybe Tom was trying to strike a balance between speed/memory perf and yet not totally taking over the message processing.


Is there any reason you wouldn't want to completely take over the message processing in a game's main loop? Better control and less overhead, assuming there isn't any extra hidden type stuff going on in the standard DoEvents/Run call that I'm missing out on (the main thing I'm trying to find out).

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.