Как обнаружить команду печати завершена в Twebbrowser?

StackOverflow https://stackoverflow.com/questions/8376618

  •  28-10-2019
  •  | 
  •  

Вопрос

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Пожалуйста, скажите мне, что вы думаете...

Это было полезно?

Решение

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

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

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 не имеет выходного значения, которое вернет это. Другое дело, что даже если пользователь принимает диалог печати, это не означает, что документ будет физически распечатан. Для этого вам придется, как сказал Реми, отслеживать очередь принтера.

Другие советы

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

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

WebBrowser1.ExecWB OLECMDID_PRINT, OLECMDEXECOPT_DODEFAULT, 2, 0
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top