印刷コマンドを検出する方法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
数日前にフラグがありますが、それを機能させることはできません。そして、トリックは非常に簡単でした(参照してください ノート nr。 4)。 3番目のパラメーターを渡すことが間違っていました ExecWB
の方法 OLECMDID_PRINT
バリアントタイプとしてコマンド VT_I4
しかし、それは過負荷であり、 PRINT_WAITFORCOMPLETION
正確なタイプに変換する必要があります VT_I2
, 、デルファイにあるものはaとして表されます 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
出力値はありません。これはこれを返します。別のことは、ユーザーが印刷ダイアログを受け入れたとしても、ドキュメントが物理的に印刷されるという意味ではないということです。このために、レミーが言ったように、プリンターキューを監視する必要があります。
他のヒント
印刷ジョブは、バックグラウンドのOSによってプリンタードライバーにスプールされ、出力されます。 Webbrowserは、いつ完成したかを教えてくれません。 execwb()は、印刷ジョブがキューになったら終了します。プリンターキューを直接監視して、それが何をしているのかを知る必要があります。
次のコードは、印刷ダイアログボックスをモデルダイアログボックスにするため、印刷ダイアログで使用された場合にのみ、アプリケーションに戻ります。
WebBrowser1.ExecWB OLECMDID_PRINT, OLECMDEXECOPT_DODEFAULT, 2, 0