Hi,
ich ärgere mich gerade mit einer
ActiveX Schnittstelle zu einem Druckprogramm für Etiketten.
1.) Ich muss Drucken:
Geht soweit auch ganz gut (Papier kommt richtig bedruckt aus dem richtigen Slot raus), ABER der Druckaufruf ist Asynchron. Das heisst letztlich, dass der User vorerst absolut keine Rückmeldung bekommt. Blöderweise gehört das Drucken in einen Workflow, und nach dem Drucken muss der User explizit sagen. 'Ja', der Druck passt, Daten so abspeichern oder eben 'Nein', der Druck passt nicht, Vorgang verwerfen - Rollback. Ich muss also den Druck abwarten und darf dem User bis dahin keine andere Eingabemöglichkeit lassen. (Vorgabe wegen ISO-QS-Zertifizierung, dürfen wir als Auftragnehmer nicht dran rütteln).
Von dem
ActiveX Objekt bekomme ich unregelmässig Events, auf die Subscriben kann (Druck beginnt, Druckfortschritt mit Prozentwert, Druck endet, Druck pausiert). Die Informationen reichen mir ja prinzipiell.
Um das geforderte Verhalten zu erreichen wollte ich nun einen Modalen Dialog anzeigen der diese Meldungen auswertet und den Druckfortschritt anzeigt und sich beendet, wenn der Druck beendet ist. Klang für mich ganz plausibel, zumal ich die Druckmethode solange in einer Endlosschleife halten wollte, bis durch das EndDruck-Event ein Flag gesetzt wird und dort dann eine für meine Anwendung Synchrone Druckmethode habe die liefert, ob der Druck erfolgreich war oder ob z.B. der Drucker ein Problem hatte. Von dort hätte ich dann mit dem Workflow weitermachen können.
Problem: ShowDialog() blockiert den Hauptthread - und damit auch alle weiteren Ereignishandler. -> Anwendung Steht komplett nach dem Zeigen des Fortschrittdialoges. Fällt also aus.
Idee 1: Dialog in Thread starten.
Problem: Das Funktioniert auch nur bis zu dem Zeitpunkt, an dem ich den neuen Progressbar-Wert via Invoke() setzen will -> Da der Thread des Dialoges blockiert bleibt die Message da stecken. Unsychronisiert klappt das manchmal, aber eben nicht immer. Ähnliches gilt für das Schliessen des Dialoges - das klappt einfach nicht aus dem Event heraus.
Idee 2: Druck in einen Thread auslagern.
Problem: Durch ShowDialog() ist der Hauptthread blockiert und auch hier bleiben sämtliche Nachrichten die Werte auf dem Modalen Dialog setzen wollen stecken, sobald sie via Invoke auf den anderen Thread gepackt werden. -> Anwendung steht und das
ActiveX Event wird gleich mitblockiert, und somit der ganze Druckprozess.
Wie bekomme ich aus dem Asynchronen Aufruf auf dem
ActiveX-Objekt am Elegantesten einen Synchronen Aufruf in meinem Code hin, und wie kann ich dem Benutzer einen Fortschritt anzeigen und gleichzeitig verhindern, dass er weitere Eingaben tätigen kann, AUSSER ggf. einen 'Abbrechen'Button auf der Fortschrittsanzeige zu drücken, die dem
ActiveX-Objekt in den Events zurückgibt, dass es den Druck abbrechen soll?
2.) Geschwindigkeit:
Nach dem Drucken muss/sollte ich die
ActiveX Schnittstelle aufräumen. Also: 1.) Dokument schliessen, 2.) Anwendungsobjekt schliessen. Funktioniert beim Debuggen auch Einwandfrei, nur beim Test ohne Debugger kommt mir sporadisch (häufig, jedoch nicht immer), nach dem Abschluss des Vorgangs eine Meldung vom Betriebssystem hoch, dass eine Anwendung (eben meine automatisierte Drucksoftware) wegen eines Fehlers beendet wurde und ob ich eine Fehlerberichterstattung senden möchte.
Wie umschiffe ich sowas am besten ohne dass ich explizit zwischen den Aufrufen Dokument Schliessen / Anwendung schliessen einfach das Programm für eine konstante (hoffentlich ausreichende) Zeitspanne schlafen schicke? Da muss es doch auch ne saubere Lösung geben?
Viele Grüße,
Sebastian <-- der vorher noch nie wirklich mit
COM/
DCOM /
ActiveX gearbeitet hat.