Как определить, что команда Print завершена в TWebBrowser? - PullRequest
3 голосов
/ 04 декабря 2011
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;

То же самое относится и к предварительному просмотру: WebBrowser1.ExecWB(OLECMDID_PRINTPREVIEW, OLECMDEXECOPT_DODEFAULT, vaIn, vaOut);

Мне нужно подождать (или вызвать событие), пока диалоговые окна Print / Print Preview не будут выполнены, и пользователь выбрал либо печать, либоотмена.

ОБНОВЛЕНИЕ (1)

На основании этот вопрос Я проверял OnCommandStateChange.Он запускается после печати или отмены в диалоговом окне «Печать».но его можно запустить 1 или 2 раза до того, как откроется диалоговое окно.

ОБНОВЛЕНИЕ (2) Найден обходной путь, который может помочь (это базовая идея):

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;

использование:

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

работает как для OLECMDID_PRINT, так и OLECMDID_PRINTPREVIEW, пожалуйста, скажите мне, что вы думаете ...

Ответы [ 3 ]

3 голосов
/ 09 декабря 2011

Когда я искал решение, я обнаружил флаг PRINT_WAITFORCOMPLETION несколько дней назад, но не могу заставить его работать.И хитрость была довольно простой (см. примечание номер 4).Я ошибся при передаче третьего параметра метода ExecWB для команды OLECMDID_PRINT в качестве варианта варианта VT_I4, но он перегружен идля PRINT_WAITFORCOMPLETION необходимо преобразовать в точный тип VT_I2, что в Delphi представлено как smallint.

Вот как сделать диалоговое окно печати модальным (также ответьте на this случайно:)

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;

К сожалению, вы не можете получить никакой обратной связи, если пользователь отправил документ в очередь принтераили отменил диалог.IDM_PRINT не имеет выходного значения, которое вернуло бы это.Другое дело, что даже если пользователь принимает диалоговое окно печати, это не означает, что документ будет напечатан физически.Для этого вам, как сказал Реми, придется следить за очередью принтера.

2 голосов
/ 05 декабря 2011

Задание печати помещается в буфер и выводится в драйвер принтера ОС в фоновом режиме. Веб-браузер не сообщает вам, когда он закончится. ExecWB () завершается, когда задание на печать поставлено в очередь. Вам нужно будет напрямую следить за очередью принтера, чтобы знать, что он делает.

0 голосов
/ 27 июня 2014

Следующий код делает диалоговое окно «Печать» диалоговым окном модели, поэтому только после использования с диалоговым окном «Печать» он вернется в приложение.

WebBrowser1.ExecWB OLECMDID_PRINT, OLECMDEXECOPT_DODEFAULT, 2, 0
...