3
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_PRINTOLECMDID_PRINTPREVIEW ください...

4

3 に答える 3

3

解決策を探していたときに、PRINT_WAITFORCOMPLETION数日前にフラグを見つけましたが、それを機能させることができません。このトリックは非常に簡単でした (4 を参照)。コマンドのExecWBmethodの 3 番目のパラメータをバリアント型として渡すのは間違っていましたが、それはオーバーロードされており、正確な型に変換する必要があります。Delphi では.OLECMDID_PRINTVT_I4PRINT_WAITFORCOMPLETIONVT_I2smallint

印刷ダイアログをモーダルにする方法は次のとおりです(これにも偶然答えてください:)

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、これを返す出力値がありません。もう 1 つのことは、ユーザーが印刷ダイアログを受け入れたとしても、ドキュメントが物理的に印刷されるという意味ではないということです。そのためには、Remy が言ったように、プリンター キューを監視する必要があります。

于 2011-12-08T23:02:30.153 に答える
2

印刷ジョブはスプールされ、バックグラウンドのOSによってプリンタドライバに出力されます。WebBrowserは、いつ終了したかを通知しません。印刷ジョブがキューに入れられると、ExecWB()は終了します。プリンタキューが何をしているのかを知るには、プリンタキューを直接監視する必要があります。

于 2011-12-05T04:08:18.597 に答える