Frage

procedure TForm1.Button1Click(Sender: TObject);
var 
  vaIn, vaOut: OleVariant;
begin
  WebBrowser1.Navigate('http://www.google.com');
  while WebBrowser1.ReadyState < READYSTATE_COMPLETE do
    Application.ProcessMessages;
  WebBrowser1.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_PROMPTUSER, vaIn, vaOut);

  // HOWTO: WAIT until print <strike>job</strike> dialog is done or canceled

  // UPDATE (1):
  WebBrowser1.Enabled := False;
  WebBrowser1.OnCommandStateChange := WebBrowser1CommandStateChange;
end;

procedure TForm1.WebBrowser1CommandStateChange(Sender: TObject; Command: Integer; Enable: WordBool);
begin
  Memo1.Lines.Add(Format('%d : %d : %d', [WebBrowser1.QueryStatusWB(OLECMDID_PRINT), Command, Ord(Enable)]));
  // TODO: after LAST event when the print dialog closes:
  // WebBrowser1.OnCommandStateChange := nil;
end;

Gleiches gilt für die Vorschau:WebBrowser1.ExecWB(OLECMDID_PRINTPREVIEW, OLECMDEXECOPT_DODEFAULT, vaIn, vaOut);

Ich muss warten (oder ein Ereignis auslösen), bis die Print / Print Preview Dialoge werden durchgeführt, und der Benutzer hat entweder Druck oder Abbrechen ausgewählt.

Update (1)

Bezogen auf diese Frage Ich habe die getestet OnCommandStateChange. Es wird gefeuert nach Drucken oder abbrechen im Dialogfeld Print. aber es kann 1 oder 2 Mal abgefeuert werden Vor Der Dialog öffnet.

Update (2)Ich habe eine Problemumgehung gefunden, die den Trick machen könnte (es ist eine Grundidee):

procedure TForm1.WaitPrintDialog;
var
  t1, t2: DWORD;
  w, wpd: HWND;
begin
  t1 := GetTickCount();
  t2 := t1;
  wpd := 0;
  while ((wpd = 0) and (t2 - t1 <= 5000)) do // 5 sec timeout
  begin
    w := FindWindowEx(0, 0, 'Internet Explorer_TridentDlgFrame', nil);
    if (w <> 0) and (GetWindow(w, GW_OWNER) = Self.Handle) then
    begin
      wpd := w;
    end;
    Application.ProcessMessages;
    t2 := GetTickCount();
  end;
  if wpd <> 0 then // found and no timeout
    while IsWindow(wpd) and (not Application.Terminated) do
    begin
      Application.HandleMessage; // Application.ProcessMessages;
    end;
end;

Verwendungszweck:

WebBrowser1.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_PROMPTUSER, vaIn, vaOut);
WaitPrintDialog;
ShowMessage('Print Done!');

funktioniert beides für OLECMDID_PRINT und OLECMDID_PRINTPREVIEWBitte sag mir, was du denkst ...

War es hilfreich?

Lösung

Wenn ich nach einer Lösung gesucht habe, habe ich das gefunden PRINT_WAITFORCOMPLETION Flag vor ein paar Tagen, kann es aber nicht zum Laufen bringen. Und der Trick war ziemlich einfach (siehe Hinweis nr. 4). Ich habe mich geirrt, wenn ich den dritten Parameter von bestanden habe ExecWB Methode für die OLECMDID_PRINT Befehl als Variantentyp VT_I4 aber es ist überladen und für PRINT_WAITFORCOMPLETION muss in den genauen Typ konvertiert werden VT_I2, was ist in Delphi als smallint.

Hier erfahren Dies ausversehen :)

procedure TForm1.Button1Click(Sender: TObject);
var
  vaIn: OleVariant;
  vaOut: OleVariant;
const
  PRINT_WAITFORCOMPLETION = $02;
begin
  WebBrowser1.Navigate('http://www.google.com');
  while WebBrowser1.ReadyState < READYSTATE_COMPLETE do
    Application.ProcessMessages;

  vaIn := OleVariant(VarAsType(PRINT_WAITFORCOMPLETION, varSmallint));
  WebBrowser1.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_PROMPTUSER, vaIn, vaOut);

  ShowMessage('Print dialog has been closed ...');
end;

Leider können Sie kein Feedback erhalten, wenn der Benutzer das Dokument an die Druckerwarteschlange gesendet oder den Dialog storniert hat. Das IDM_PRINT hat keinen Ausgangswert, der dies zurückgeben würde. Eine andere Sache ist, dass selbst wenn der Benutzer das Druckdialogfeld akzeptiert, dies nicht bedeutet, dass das Dokument physisch gedruckt wird. Dafür müssten Sie, wie Remy sagte, die Druckerwarteschlange überwachen.

Andere Tipps

Der Druckauftrag wird vom Betriebssystem im Hintergrund spulen und an den Druckertreiber ausgegeben. Der Webbrowser sagt Ihnen nicht, wann er fertig ist. Execwb () beendet, sobald der Druckauftrag in der Warteschlange gestellt wurde. Sie müssten die Druckerwarteschlange direkt überwachen, um zu wissen, was er tut.

Der folgende Code macht das Dialogfeld Dialogbox des Drucks zum Dialogfeld "Modell", sodass nur dann, wenn die Verwendung mit dem Dialogfeld "Druck" zur Anwendung zurückkehrt.

WebBrowser1.ExecWB OLECMDID_PRINT, OLECMDEXECOPT_DODEFAULT, 2, 0
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top