Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Drucken mit ShellExecuteEx - Eigenes Programm wird träge (https://www.delphipraxis.net/3888-drucken-mit-shellexecuteex-eigenes-programm-wird-traege.html)

APP 4. Apr 2003 11:54


Drucken mit ShellExecuteEx - Eigenes Programm wird träge
 
Hallo,
ich drucke mit ShellExecuteEx viele unterschiedliche Dokumente nacheinader (in einer Schleife) aus, möchte nun aber, dass der User die Möglichkeit hat, das Ausdrucken zu unterbrechen.
Bei sehr großen Dokumenten reagiert meine Applikation aber sehr träge auf jeden Knopfdruck.

Hat da jemande eine Idee?

Delphi-Quellcode:
PROCEDURE TForm1.Button2Click(Sender: TObject);
VAR
  ShExecInfo                 : TShellExecuteInfo;
//  alParam                    : ARRAY[0..99] OF Char;
  i                          : Integer;
BEGIN
  FOR i := 0 TO ListBox1.Items.Count - 1 DO
    BEGIN
      CloseIt := TRUE;
      IF NOT FileExists(ListBox1.Items.Strings[i]) THEN
        BEGIN
          MessageDlg('File: ' + ListBox1.Items.Strings[i] + ' not found', mtError, [mbOk], 0);
          Continue;
        END;
      FillChar(ShExecInfo, SizeOf(ShExecInfo), 0);
      WITH ShExecInfo DO
        BEGIN
          cbSize := SizeOf(ShExecInfo);
          fMask := SEE_MASK_NOCLOSEPROCESS;      //  SEE_MASK_NOCLOSEPROCESS OR SEE_MASK_FLAG_DDEWAIT;
          lpFile := PChar(ListBox1.Items.Strings[i]);
          lpVerb := 'print';
          nShow := SW_SHOW;
        END;
      IF ShellExecuteEx(@ShExecInfo) THEN
        BEGIN
          WaitForSingleObject(ShExecInfo.hProcess, 0);
          Application.ProcessMessages;
          IF CloseIt = FALSE THEN Exit; // Wird vom ExitButton False gesetzt
        END
      ELSE
        ShowMessage('Fehler beim Öffnen');
      Application.ProcessMessages;
    END;
  showMessage('Ready');
END;

Chewie 4. Apr 2003 12:11

Du könntest Threads benutzen: Die Benutzersteuerung läuft im Hauptthread unnd der Druck-Vorgang in einem eigenen Thread.

APP 4. Apr 2003 17:45

Tja, scheint eine gute Idee zu sein, habe aber mit Threads noch nichts am Hut, könntest Du ein paar Code-Schnipsel posten?

Luckie 4. Apr 2003 17:59

Code-Schnipsel zu Threads? Das sind nicht nur ein, zwei Zeilen. Aber bei Delphi ist im Demo-Verzeichnis ein Threading-Demo da bei.

APP 5. Apr 2003 12:56

@Luckie,
aufgrund Deines Kommentars schließe ich daraus, dass es für mein Problem wohl keine andere (simplere) Lösung gibt. Insgeheim hatte ich gehofft, es gibt dazu irgendwelche API-Tricks oder Callbacks, o.ä., aber ich werde mir nun wohl die Demos zu Gemüte führen (müssen). :mrgreen:

Christian Seehase 5. Apr 2003 16:03

Moin Armin,

hier einmal ein, sehr einfaches, Beispiel zu TThread:

Delphi-Quellcode:
type
  TcsDownloadThread = class(TThread)
  private
    FsSource : string;
    FsDest  : string;
  public
    constructor Create(const AsSource : string; const AsDest : string);
    procedure Execute; override;
  end;

constructor TcsDownloadThread.Create(const AsSource, AsDest: string);
begin
  FsSource       := AsSource;
  FsDest         := AsDest;
  FreeOnTerminate := true; // Thread freigeben, wenn beendet
  inherited Create(false); // False = sofort starten
end;

procedure TcsDownloadThread.Execute;
begin
  URLDownLoadToFile(nil,PChar(FsSource),PChar(FsDest),0,nil); // Datei herunterladen
  Terminate; // dann beenden
end;

APP 5. Apr 2003 17:10

@Chris,
vielen Dank für Dein Beispiel, währenddessen habe ich den Holzhammer :freak: ausgepackt und erhöhe mal während der ShellExecuteEx-Phase die Proirität meines Programms:

Delphi-Quellcode:
         SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
         TRY
            IF ShellExecuteEx(@ShExecInfo) THEN
               BEGIN
                  aHandle := ShExecInfo.HProcess;
                  WaitForSingleObject(ShExecInfo.hProcess, 0);
                  Application.ProcessMessages;
                  IF CloseIt = FALSE THEN
                     BEGIN
                        CloseHandle(aHandle);
                        Exit;
                     END;
               END
            ELSE
               ShowMessage('Fehler beim Öffnen');
            Application.ProcessMessages;
         FINALLY
            SetPriorityClass(GetCurrentProcess, NORMAL_PRIORITY_CLASS);
         END;
Es scheint zu funktionieren, allerdings werde ich Dein obiges Beispiel aufnehmen und mal versuchen anzupassen, da Deine Lösung (und Chewies Idee mit den Threads) natürlich viel eleganter ist!

APP 5. Apr 2003 18:13

@Chris,
Dein Code-Schnipsel war genau das Richtige!

Ich habe ihn ein bißchen zum Spielen umgebaut -und siehe da es funktioniert :dancer:

Vielen Dank nochmal!


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:56 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz