delphimultithreadingconsoledelphi-2009console-application

How to create a console application that does not terminate?


In C++, a console application can have a message handler in its WinMain procedure, like this:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    HWND hwnd;
    MSG msg;

    #ifdef _DEBUG
    CreateConsole("Title");
    #endif

    hwnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc);
    PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
    while(msg.message != WM_QUIT)
    {
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if(IsDialogMessage(hwnd, &msg))
                continue;
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

    }

    return 0;
}

This makes the process not close until the console window has received a WM_QUIT message. I don't know how to do something similar in Delphi.

My need is not for exactly a message handler, but a lightweight "trick" to make the console application work like a GUI application using threads. So that, for example, two Indy TCP servers could be handled without the console application terminating the process.

How could this be accomplished?


Solution

  • I'm not sure I understand what you need to do, but maybe something like this

    program Project1;
    
    {$APPTYPE CONSOLE}
    
    uses
      Forms,
      Unit1 in 'Unit1.pas' {DataModule1: TDataModule};
    
    begin
      Application.Initialize;
      Application.CreateForm(TDataModule1, DataModule1);
      while not Application.Terminated do
        Application.ProcessMessages;
    end.
    

    gets you started? It is a console application, which will terminate when the console is closed. You could use the Indy components in the data module.

    Edit:

    The alternative without the Forms unit is:

    program Project1;
    
    {$APPTYPE CONSOLE}
    
    uses
      Windows;
    
    var
      Msg: TMsg;
    begin
      while integer(GetMessage(Msg, 0, 0, 0)) <> 0 do begin
        TranslateMessage(Msg);
        DispatchMessage(Msg);
      end;
    end.
    

    I think however that this won't work with most Delphi components - I don't know about Indy, but if one of its units brings the Forms unit in anyway, then the first version is IMO preferable.