Как обнаружить команду печати завершена в Twebbrowser?
-
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