A message loop goes down to core Windows API stuff - you don't get the lovely VCL things. While the VCL is nice, it is a bit less responsive and generates much larger exes than Win32.

The message loop is a pretty simple concept. Whenever Windows does something, it sends a message to every running app which says "this happened. Deal with it as appropriate". Each message is added to a queue, and the message loop takes a message from the queue and processes it (e.g. closing if a WM_QUIT message is received, etc.).

You usually use PeekMessage with games/interactive demos. This takes a message from the queue. You then call TranslateMessage and DispatchMessage. Once you've done this, Windows calls a special function called the WindowProc. This is a big case statement, usually, which might look like this:

[pascal]function WndProc(HWnd: HWND; Msg: UINT; wParam: WPARAM;
lParam: LPARAM): LRESULT; stdcall;
begin
case Msg of
WM_CREATE:
begin
; // init stuff
Result := 0;
end;
WM_CLOSE:
begin
PostQuitMessage(0); // tell the message loop to finish
Result := 0;
end;
else // some other message
Result := DefWindowProc(HWnd, Msg, WParam, LParam);
end;
end;[/pascal]

The main message loop may look something like this:

[pascal]while not Finished do
begin
while PeekMessage(Msg,0,0,0,PM_REMOVE) do
begin
if Msg.message = WM_QUIT then
begin
Finished := True;
Break;
end;

TranslateMessage(Msg);
DispatchMessage(Msg);
end;

// todo other update stuff for one game loop here
end;[/pascal]

It's not something that you can dive into without prior reading, though. Try having a look at this tutorial I wrote that explains some of the concepts. Xorcist has also posted some of his Win32 code in another thread around here...