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_PRINTPREVIEWPor favor, dígame lo que usted piensa...

¿Fue útil?

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top