Results 1 to 7 of 7

Thread: Execute executable in "modal" mode

  1. #1

    Execute executable in "modal" mode

    Ik wil een executable opstarten. De hoofdapplicatie moet hierop wachten. Volgens de site van freepascal moet dat op de volgende manier.

    Het probleem van beide onderstaande methoden is dat de hoofdapplicatie nog steeds luistert naar muisklikken (klikken op button1 of verslepen van het formulier). Deze doet ie pas uitvoeren natdat het subproces (notpad.exe) gesloten is.

    Dat is dus niet wat ik wil :-)


    Code:
    // http://wiki.freepascal.org/Executing_External_Programs
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      showmessagE('test');
    end;
    
    procedure launch;
    var
      AProcess: TProcess;
    begin
      AProcess := TProcess.Create(nil);
      AProcess.CommandLine := 'notepad.exe';
      AProcess.Options := AProcess.Options + [poWaitOnExit];
      AProcess.Execute;
      AProcess.Free;
    end;
    
    
    procedure TForm1.Button2Click(Sender: TObject);
    begin
      //Form1.Enabled:= false;
      //SysUtils.ExecuteProcess(UTF8ToSys('notepad.exe "' + 'file.txt' + '"'), '', []);
      launch;
      //Form1.enabled := true;
    end;

  2. #2
    De makkelijkste manier is denk ik om een modal venstertje te tonen en dat venstertje deze code uit te laten voeren. Daarmee blokkeer je de rest van de applicatie en je kunt met een paar regels code voorkomen dat de gebruiker al te veel met het venster zelf kan. Daarbij kun je er een tekst op zetten die duidelijk maakt aan de gebruiker dat hij eerst Notepad moet afsluiten.

    Maar als het echt om Notepad gaat, kun je dan niet beter een TMemo gebruiken?
    1+1=b

  3. #3
    Een nieuw venster met een TMemo zou een oplossing zijn. Maar dan moet ik ook wat tekst bewerkings functions erin zetten. (voelt als het wiel opnieuw uitvinden).

    Maar is dit normaal gedrag dan?

    Is er niet een workaround? Behalve het hele window onzichtbaar te maken?

  4. #4
    Ik gaf toch een workaround in de vorm van een global 'wacht' venstertje om je applicatie mee te blokkeren?

    Alles wat je wilt is een work-around. Het normale gedrag voor een besturingssysteem als Windows is natuurlijk dat je een applicatie kunt blijven gebruiken terwijl de andere draait.
    Bijkomend gedrag is dat messages opgespaard worden. Dat zie je als je een langdurige procedure uitvoert. Voer maar eens Sleep(5000) uit en klik tijdens die 5 seconden overal op je form. Die clicks worden ook ineens allemaal uitgevoerd zodra je programma weer reageert.

    Je kunt ook zelf met message loops gaan sleutelen, je hele applicatie verbergen, of de wachtprocedure in een thread zetten en de status van deze thread uitlezen als er op een button geklikt wordt. Dat laatste is misschien nog wel het beste, omdat je daarmee je hele applicatie door kunt laten draaien en alleen de functies kunt uitschakelen die daadwerkelijk moeten wachten.

    Maar een TMemo is nog steeds een goeie kandidaat. Ik weet natuurlijk niet precies wat je allemaal moet kunnen bewerken, maar functies als printen en opslaan als, nieuw en openen, heb je waarschijnlijk helemaal niet nodig. Ik denk eigenlijk dat je er met Save en de items in het menu Edit wel zult zijn, of schat ik dat verkeerd in?

    Het wiel opnieuw uitvinden is namelijk niet echt nodig. Dat hebben de makers van Delphi al voor je gedaan.
    • Zet een TMemo en een TActionList op je form.
    • Dubbelklik de action list om de action list editor te openen.
    • Click het pijltje (of druk Ctrl+Ins) om een nieuwe standard action in te voegen.
    • Selecteer alle actions in de category 'Edit' en druk op OK.
    • Voeg de volgende code toe in je FormCreate event, om de actions te koppelen aan je memo.
      Delphi Code:
      1. var
      2.   i: Integer;
      3. begin
      4.   for i := 0 to ActionList1.ActionCount - 1 do
      5.     if ActionList1.Actions[i].Category = 'Edit' then
      6.       (ActionList1.Actions[i] as TEditAction).Control := Memo1;
    • Maak voor de duidelijkheid een menu of toolbar met een item voor elk van deze actions.

    En tadaah! Je eigen embedded notepad in 5 minuten klikken en 3 regels code.

    [edit]
    Oh, heb je die eigenlijk ook in Lazarus?

    [edit2]
    Ja, Ook in Lazarus werkt het zo, behalve dat je daar de actions 1 voor 1 moet toevoegen, omdat je er niet meerdere kunt selecteren. Gratis product zeker.
    Last edited by GolezTrol; 25-Dec-12 at 09:39.
    1+1=b

  5. #5
    He, dat koppelen is best gaaf. Echter blijf ik daar ook met een aantal puntjes zitten.

    Overigens dacht ik dat het een goed idee om een tweede form te openen als Modal en dan de exe te starten, maar dit geeft ook problemen. Ik wil namelijk wachten tot de executable afgesloten is.
    Als ik de form Modal start en start de exe pas nadat het form gesloten is

    Ik denk dat ik dus maar de belangrijkste knoppen op het mainform disable als ik de exe start.

    Dat ActionList krijg ik ook niet helemaal zoals ik het wil. In een MainMenu koppel ik ook Actions. Als ik dan letters weghaal in de Memo gaat "ongedaan maken" wel aan maar zet ie het niet terug als ik erop druk.
    Knippen en Plakken werkt wel goed. Wellicht een fout aan mijn kant of een bug in Lazarus.

    Thanks voor alle hulp


    grrrrrrrrrr....nou disable ik de toolbarbuttons voordat ik de executable aftrap en nog buffert ie acties.


    Code:
    ///////////////////////////////////////////////////////////////////////////////////
    procedure TfrmMain.ControlsEnabled(ControlsEnabledStatus: TControlsEnabled);
    ///////////////////////////////////////////////////////////////////////////////////
    
      /////////////////////////////////////////////////////////////////////////////////
      procedure ColorLabelsOnScrollbox(Scrollbox: TScrollBox; AColor: TColor);
      /////////////////////////////////////////////////////////////////////////////////
      var
        i: integer;
        item: TObject;
      begin
        for i:=Scrollbox.ControlCount-1 downto 0 do
        begin
          item := Scrollbox.Controls[i];
          if (item is TMyLabel) then
            TMyLabel(item).Font.Color := AColor;
        end;
      end;
    var
      ABoolean, AEnableHostsEdit: boolean;
    begin
    
      case ControlsEnabledStatus of
        ceAllEnabled:
        begin
          ABoolean := true;
          AEnableHostsEdit := true;
        end;
        ceAllDisabled:
        begin
          ABoolean := false;
          AEnableHostsEdit := false;
        end;
        ceOnlyHostsEditEnabled:
        begin
          ABoolean := false;
          AEnableHostsEdit := true;
        end;
      end;
    
      tbtnRefresh.Enabled := ABoolean;
      tbtnEditGoldenfile.Enabled := ABoolean;
      tbtnAbout.Enabled := ABoolean;
      scrollboxHosts.Enabled := ABoolean;
      scrollboxRedactions.Enabled := ABoolean;
      rgFilter.Enabled := ABoolean;
    
      tbtnEditHostsfile.Enabled := AEnableHostsEdit;
      menuEditHostsfile.Enabled := AEnableHostsEdit;
    
      if ABoolean = false then
      begin
        ColorLabelsOnScrollbox(scrollboxRedactions, LABEL_DISABLED_COLOR);
        ColorLabelsOnScrollbox(scrollboxHosts, LABEL_DISABLED_COLOR);
      end
      else begin
        ColorLabelsOnScrollbox(scrollboxRedactions, LABEL_ENABLED_COLOR);
        ColorLabelsOnScrollbox(scrollboxHosts, LABEL_ENABLED_COLOR);
      end;
    
    end;     
    
    
    procedure LaunchNotepadAndWait;
    var
      AProcess: TProcess;
    begin
      AProcess := TProcess.Create(nil);
      AProcess.CommandLine := 'notepad.exe';
      AProcess.Options := AProcess.Options + [poWaitOnExit];
      AProcess.Execute;
      AProcess.Free;
    end;
    
    
    ///////////////////////////////////////////////////////////////////////////////////
    procedure TfrmMain.EditHostsfile(AFilename: string);
    // http://wiki.lazarus.freepascal.org/Executing_External_Programs
    ///////////////////////////////////////////////////////////////////////////////////
    var
      sBefore, sAfter: string;
    begin
      sBefore := uCommon.FileModifiedDateAsString(AFilename);
      ControlsEnabled(ceAllDisabled);
      Application.ProcessMessages;
    
      //SysUtils.ExecuteProcess(UTF8ToSys('notepad.exe "' + AFilename + '"'), '', []);
      LaunchNotepadAndWait;
      sAfter := uCommon.FileModifiedDateAsString(AFilename);
      ControlsEnabled(ceAllEnabled);
    
    
      (* on error or file modified then re-init *)
      if (sBefore = '') or (sAfter = '') or (sBefore <> sAfter) then
        Initialize;
    end;
    Last edited by MisterE; 26-Dec-12 at 20:41.

  6. #6
    Quote Originally Posted by MisterE View Post
    Overigens dacht ik dat het een goed idee om een tweede form te openen als Modal en dan de exe te starten, maar dit geeft ook problemen. Ik wil namelijk wachten tot de executable afgesloten is.
    Als ik de form Modal start en start de exe pas nadat het form gesloten is
    Dan moet je dat form de executable laten starten. ShowModal komt pas terug als het form gesloten wordt. Je zult dus bijvoorbeeld vanuit het OnShow event (of OnActivate, waarschijnlijk) de executable moeten starten.

    Beter is het dan om dat te doen in een aparte thread, en daarna een modal form te starten dat die thread in de gaten houdt.
    1+1=b

  7. #7
    Quote Originally Posted by GolezTrol View Post
    Dan moet je dat form de executable laten starten. ShowModal komt pas terug als het form gesloten wordt. Je zult dus bijvoorbeeld vanuit het OnShow event (of OnActivate, waarschijnlijk) de executable moeten starten.

    Beter is het dan om dat te doen in een aparte thread, en daarna een modal form te starten dat die thread in de gaten houdt.
    Ik heb nu een andere oplossing, ik zet een "processmessages" NA het eindigen van de exe. Dan worden de gecachde events op een formulier losgelaten waar alles uit staat. Een crappy oplossing maar het werkt wel :>

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

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
  •