Come rilevare il comando di stampa è finito in TWEBBROWSER?
-
28-10-2019 - |
Domanda
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 stesso vale per l'anteprima:WebBrowser1.ExecWB(OLECMDID_PRINTPREVIEW, OLECMDEXECOPT_DODEFAULT, vaIn, vaOut);
Devo aspettare (o innescare un evento) fino al Print
/ Print Preview
Le finestre di dialogo vengono eseguite e l'utente ha selezionato o annullare.
Aggiornamento (1)
Basato su questa domanda Ho testato il OnCommandStateChange
. È licenziato dopo Stampa o annulla nella finestra di dialogo Stampa. ma può essere sparato 1 o 2 volte prima La finestra di dialogo si apre.
Aggiornamento (2)Ho trovato una soluzione alternativa che potrebbe fare il trucco (è un'idea di base):
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!');
funziona entrambi per OLECMDID_PRINT
e OLECMDID_PRINTPREVIEW
Per favore dimmi cosa ne pensi ...
Soluzione
Quando ho cercato una soluzione ho trovato il PRINT_WAITFORCOMPLETION
Flag pochi giorni fa ma non riesco a farlo funzionare. E il trucco è stato abbastanza facile (vedi Nota nr. 4). Ho sbagliato a passare il terzo parametro di ExecWB
metodo per il OLECMDID_PRINT
comando come tipo di variante VT_I4
ma è sovraccarico e per PRINT_WAITFORCOMPLETION
deve essere convertito nel tipo esatto VT_I2
, cosa è in Delphi rappresentato come a smallint
.
Ecco come rendere la finestra di dialogo di stampa modale (rispondi anche a questo per errore :)
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;
Sfortunatamente non è possibile ottenere alcun feedback se l'utente ha inviato il documento alla coda della stampante o annullato la finestra di dialogo. Il IDM_PRINT
non ha valore di output, il che restituirebbe questo. Un'altra cosa è che anche se l'utente accetta la finestra di dialogo di stampa, non significa che il documento verrà stampato fisicamente. Per questo dovresti, come ha detto Remy, monitorare la coda della stampante.
Altri suggerimenti
Il lavoro di stampa viene bobino e emesso sul driver della stampante dal sistema operativo sullo sfondo. Il Webbrowser non ti dice quando è finito. Execwb () esce una volta che il lavoro di stampa è stato messo in coda. Dovresti monitorare direttamente la coda della stampante per sapere cosa sta facendo.
Il seguente codice rende la finestra di dialogo di stampa una finestra di dialogo Modello, in modo che solo quando l'uso eseguito con la finestra di dialogo di stampa tornerà all'applicazione.
WebBrowser1.ExecWB OLECMDID_PRINT, OLECMDEXECOPT_DODEFAULT, 2, 0