Page 2 of 2 FirstFirst 12
Results 11 to 18 of 18

Thread: From scratch or component based?

  1. #11

    From scratch or component based?

    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...
    "All paid jobs absorb and degrade the mind."
    <br />-- Aristotle

  2. #12

    From scratch or component based?

    More like

    [pascal]
    while not Shutdown do
    begin
    if PeekMessage(Msg, HDXWindowHandle, 0, 0, PM_REMOVE) then
    begin
    TranslateMessage(Msg);
    DispatchMessage(Msg);
    end;
    if WindowsFocused and not Shutdown then Shutdown := not GameLoop;
    end;
    [/pascal]

  3. #13

    From scratch or component based?

    Application.OnIdle is exactly the same as providing your own message loop. There is absolutely no difference. Study the VCL source for TApplication to see why. Always remember to set the Done parameter to False so the OnIdle event is continuously triggered.

  4. #14

    From scratch or component based?

    No it's not. Even if you only consider the VCL-Overhead just to have a window and use OnIdle, theres a difference.

  5. #15

    From scratch or component based?

    Always remember to set the Done parameter to False so the OnIdle event is continuously triggered.
    What if (because this is what I do when making games that utilize components) you don't set Done := False but rather in OnIdle just have a call to the main game loop procedure, inside of which there is an infinite loop, that loops until the game is terminated. The program should then only re-enter OnIdle on it's way out of the game loop which at that point is terminating the application. Just wondering if any problems might arise... I don't believe OnIdle will ever get the chance to be called again
    My DGDev forum pascal syntax highlight settings:
    <br />[background=#FFFFFF][comment=#8080FF][normal=#000080]
    <br />[number=#C00000][reserved=#000000][string=#00C000]

  6. #16

    From scratch or component based?

    Xorcist: Because you are not being nice to message handling. By setting Done to False and allowing it to return normally, you are correctly handling any Windows messages that the application receives. Message handling is something that a lot of people tend to ignore. Maybe it's because the VCL hides most of the message handling that people are not even aware of the necessity of it. Play nice with Windows and it will play nice with you.

    Summers Gone: Ok, so there is a difference in executable size, but functionality-wise there is no difference. Performance and functionality is no different. I've done the tests.

  7. #17

    From scratch or component based?

    Sly, you might have to re-explain that to me. I'm not sure I'm getting it all. I never set Done := False because I never leave Application.OnIdle (I immediately enter a seperate infinite loop). All my message handling is done through periodic calls to Application.ProcessMessages. Which I would assume would allow Windows to handle any messages it needs to. How is this different than setting Done := False? From what I understand, Application.OnIdle only gets called externally once and by setting Done := False it basically recalls itself until Done := True. Where exactly is the message handling done in that case? If no specific calls to Application.ProcessMessages are made.
    My DGDev forum pascal syntax highlight settings:
    <br />[background=#FFFFFF][comment=#8080FF][normal=#000080]
    <br />[number=#C00000][reserved=#000000][string=#00C000]

  8. #18

    From scratch or component based?

    TApplication.Run basically works like this:

    1. Have we finished? If yes, end application.
    2. Are any messages waiting in the message queue? (PeekMessage)
    3. If yes, process them. (GetMessage) If received a WM_QUIT, then set finished flag.
    4. Call OnIdle event handler.
    5. If Done is True then wait for the next message. (WaitMessage)
    6. Go to step 1

    You say that you call Application.ProcessMessages in your own loop. This roughly simulates the normal message loop. Sure this may work, but ProcessMessages is a hack that allows an application to seem responsive when the application has entered into an extrememly long loop. It is not intended for constant usage. What I'm getting at is there is a recommended way to write Windows applications at the low level of message processing and using the OnIdle event and setting Done to False is the corresponding method if you are using the VCL in your application.

Page 2 of 2 FirstFirst 12

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •