¿Cómo detectar el comando de impresión ha terminado en twebbrowser?
-
28-10-2019 - |
Pregunta
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;
Lo mismo ocurre con la vista previa:WebBrowser1.ExecWB(OLECMDID_PRINTPREVIEW, OLECMDEXECOPT_DODEFAULT, vaIn, vaOut);
Necesito esperar (o activar un evento) hasta que el Print
/ Print Preview
Los diálogos se realizan y el usuario ha seleccionado imprimir o cancelar.
Actualización (1)
Residencia en esta pregunta Probé el OnCommandStateChange
. Se dispara después Imprimir o cancelar en el cuadro de diálogo Imprimir. pero se puede disparar 1 o 2 veces antes de Se abre el diálogo.
Actualización (2)Encontró una solución que podría hacer el truco (es una idea básica):
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;
uso:
WebBrowser1.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_PROMPTUSER, vaIn, vaOut);
WaitPrintDialog;
ShowMessage('Print Done!');
Funciona tanto para OLECMDID_PRINT
y OLECMDID_PRINTPREVIEW
Por favor, dígame lo que usted piensa...
Solución
Cuando he estado buscando una solución, he encontrado el PRINT_WAITFORCOMPLETION
Flag hace unos días, pero no puede hacer que funcione. Y el truco fue bastante fácil (ver Nota nr. 4). Me he equivocado al pasar el tercer parámetro de ExecWB
Método para el OLECMDID_PRINT
comando como tipo variante VT_I4
pero está sobrecargado y para PRINT_WAITFORCOMPLETION
debe convertirse al tipo exacto VT_I2
, lo que hay en Delphi representado como un smallint
.
Aquí se explica cómo hacer el diálogo de impresión modal (también responda a este por accidente :)
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;
Desafortunadamente, no puede recibir ningún comentario si el usuario envió el documento a la cola de impresora o canceló el cuadro de diálogo. los IDM_PRINT
no tiene valor de salida, lo que devolvería esto. Otra cosa es que incluso si el usuario acepta el diálogo de impresión, no significa que el documento se imprima físicamente. Para esto, como dijo Remy, monitorear la cola de la impresora.
Otros consejos
El trabajo de impresión se coloca y se genera al controlador de impresora por el sistema operativo en el fondo. WebBrowser no le dice cuándo está terminado. ExecWB () sale una vez que el trabajo de impresión se ha colocado en cola. Tendría que monitorear la cola de la impresora directamente para saber qué está haciendo.
El siguiente código hace que el cuadro de diálogo de modelo impreso sea un cuadro de diálogo Modelo, de modo que solo cuando se use con el cuadro de diálogo Imprimir, volverá a la aplicación.
WebBrowser1.ExecWB OLECMDID_PRINT, OLECMDEXECOPT_DODEFAULT, 2, 0