Search code examples
delphimessage-queuedelphi-7indy

Added the {APPTYPE CONSOLE} directive and now my application runs very slowly. Moving the mouse makes it run faster


I am trying to extend a 3rd party application so that it can be invoked via command line in addition to using the windows form GUI (mixed mode is desired). It's a fairly simple program which basically loads a file and then you click a button it starts sending UDP network packets.

I need to invoke the application from another and would like to pass in an argument and need to be able to return the ExitCode to the calling app. From what i've read, in order to do so you need to add the compiler directive {APPTYPE CONSOLE}.

I did this and my application worked as I wanted it to except sending the network packets slowed down to a crawl. I found that whenever I moved my mouse around on the form. That the network transfer rate increased significantly. I suspect there is some type of Windows Message queue problem and moving mouse is causing interrupts which in turn is causing the message queue to be processed?

I have googled around and tried calling Application.ProcessMessages and PeekMessages in a Timer with a 1ms interval and that didn't help at all. I found in this user manual for some other application it says that Indy 10 is supported in both APPTYPE CONSOLE and GUI types. Quite frankly this just confuses me as I would have assumed that all network library would work in both modes... but like I said I'm not familiar with Delphi.

I am positive that the issue is isolated to a single line in my application and that is whether or not {APPTYPE CONSOLE} is included or not.

Anyone have any ideas?

Version Info:
Delphi 7 Personal (Build 4.453)
Indy 9.0.4


Solution

  • If you add {APPTYPE CONSOLE} to your application even though you desire mixed mode execution, then you will have to live with a console even when the application is in GUI mode. You can of course close the console, but this will cause some flicker and feels a bit hackish to me.

    You should be able to do what you want without a console program. A small test program proves that the exit code can be read from a GUI program:

    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
      Close;
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      ExitCode := 42;
      Timer1.Interval := 1000;
      Timer1.Enabled := TRUE;
    end;
    

    If this is executed with the following cmd file:

    @echo off
    start /WAIT project1.exe
    echo %ERRORLEVEL%
    

    the program shows its main form for 1 second, closes, and the script prints 42 to the console window.

    Now for capturing the output - doing this from a GUI program is actually easier than doing it from a console program, if you allow for the use of a temporary file. You need to start the program with a command line parameter anyway, so why not give it the name of a temporary file, wait for the application to finish, read in the file and delete it afterwards?