Question

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;

la même chose pour Preview: WebBrowser1.ExecWB(OLECMDID_PRINTPREVIEW, OLECMDEXECOPT_DODEFAULT, vaIn, vaOut);

Je dois attendre (ou déclencher un événement) jusqu'à ce que les boîtes de dialogue Print / Print Preview sont faites, et l'utilisateur a sélectionné imprimer ou annuler.

UPDATE (1)

Sur la base cette question je l'ai testé le OnCommandStateChange. Il est tiré après impression ou annuler dans la boîte de dialogue d'impression. mais il peut être tiré 1 ou 2 fois avant la boîte de dialogue ouvre.

UPDATE (2) Trouvé une solution de contournement qui pourrait faire l'affaire (il est une idée de base):

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;

utilisation:

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

fonctionne aussi bien pour OLECMDID_PRINT et OLECMDID_PRINTPREVIEW S'il vous plaît dites-moi ce que vous pensez ...

Était-ce utile?

La solution

When I've been looking for a solution I've found the PRINT_WAITFORCOMPLETION flag few days ago but can't get it to work. And the trick was quite easy (see note nr. 4). I've been wrong with passing the third parameter of ExecWB method for the OLECMDID_PRINT command as variant type VT_I4 but it is overloaded and for PRINT_WAITFORCOMPLETION must be converted to the exact type VT_I2, what is in Delphi represented as a smallint.

Here is how to make the print dialog modal (also answer to this by accident :)

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;

Unfortunately you can't get any feedback if user sent the document to the printer queue or cancelled the dialog. The IDM_PRINT has no output value, which would return this. Another thing is that even if user accepts the printing dialog it doesn't mean that the document will be physically printed. For this you would have to, as Remy said, monitor the printer queue.

Autres conseils

The print job is spooled and outputted to the printer driver by the OS in the background. The WebBrowser does not tell you when it is finished. ExecWB() exits once the print job has been queued. You would have to monitor the printer queue directly to know what it is doing.

The following code makes the Print dialogbox a model dialog box, so that only when the use done with the Print dialog he will come back to the application.

WebBrowser1.ExecWB OLECMDID_PRINT, OLECMDEXECOPT_DODEFAULT, 2, 0
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top