delphi - 从 TWebBrowser 打印

标签 delphi twebbrowser

我正在使用以下单元通过 TWebBrowser 显示和打印 HTML 代码,该代码显示在非模式对话框中。在我的生产程序中,以下代码在 Windows-XP 下工作,但在 Windows-7 下失败(错误消息始终为外部异常 C015D00F)。为了隔离问题,我编写了一个简单的测试程序,其中也有一个包含 TWebBrowser 的非模式对话框;就其本身而言,该测试程序可以在 Windows-7 上正常运行,但是当我将测试程序中的非模式对话框插入到生产程序中时,我收到了外部异常。

这可能表明调用程序有问题,而不是被调用单元有问题,但我看不出问题是什么。 HTML 代码是手工编写的,但显示正确。

可能是什么问题?打印代码来自Embarcadero site

unit Test4;

interface
uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, OleCtrls, SHDocVw, MSHTML;

type
 THTMLPreview = class(TForm)
  web: TWebBrowser;
  procedure FormClose(Sender: TObject; var Action: TCloseAction);
  procedure webDocumentComplete(Sender: TObject; const pDisp: IDispatch;
                                var URL: OleVariant);
  private
   options: word;
   fn: string;
   procedure DoPrint;
  public
   Constructor Create (const afn, acapt: string; opts: word);
  end;

implementation

{$R *.dfm}

constructor THTMLPreview.Create (const afn, acapt: string; opts: word);                
begin
 inherited create (nil);
 caption:= acapt;
 fn:= afn;
 options:= opts;
 web.Navigate (fn);
end;

procedure THTMLPreview.webDocumentComplete(Sender: TObject;
                 const pDisp: IDispatch; var URL: OleVariant);
begin
 DoPrint
end;

procedure THTMLPreview.DoPrint;
var
 HTMLDoc: IHTMLDocument2;
 HTMLWnd: IHTMLWindow2;
 HTMLWindow3: IHTMLWindow3;

begin
 if options and 4 = 4 then
  begin
   HTMLDoc:= web.Document as IHTMLDocument2;
   if HTMLDoc <> nil then
    begin
     HTMLWnd:= HTMLDoc.parentWindow;
     HTMLWindow3:= HTMLWnd as IHTMLWindow3;
     HTMLWindow3.print;
    end
  end
end;

procedure THTMLPreview.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 if options and 1 = 1 then deletefile (fn);
 action:= caFree
end;

end.

使用语句Web.ControlInterface.ExecWB (OLECMDID_PRINT, OLECMDEXECOPT_PROMPTUSER, vaIn, vaOut) 给出相同的错误。


几天后编辑:

我尝试了一种完全不同的方法来解决这个问题。在 HTML 代码中,我添加了一个 JavaScript 片段,它显示“打印”按钮并添加“onprint”事件。再次,这在我的开发计算机(XP)上运行良好,但在我的客户端计算机(Win7)上运行不佳,程序卡住并显示外部异常 C015D00F(与之前的地址相同)。


经过大量谷歌搜索后,我发现异常代码C015000F是由 “被停用的激活上下文不是最近激活的。”这对于一个贫穷的 Delphi 程序员意味着什么?

最佳答案

如果我没记错的话,IHTMLWindow3.print 方法会弹出默认的“发送到打印机”系统对话框。你想要这个吗?对于一个应用程序,我曾经寻找一种方法来避免这种情况,然后找到了这段代码。

var
  r:TRect;
  sh,ph:HDC;
begin
  OleInitialize(nil);
  WebBrowser1.Navigate('file://'+HtmlFilePath);
  while WebBrowser1.ReadyState<>READYSTATE_COMPLETE do Application.HandleMessage;

  //Printer.PrinterIndex:=//set selected printer here
  Printer.BeginDoc;
  try
    Printer.Canvas.Lock;
    try
      sh:=GetDC(0);
      ph:=Printer.Canvas.Handle;

      //TODO: make rect a bit smaller for a page margin
      //TODO: get page size from printer settings, assume A4 here (210x297mm)
      r.Left:=0;
      r.Top:=0;
      r.Right:=2100 * GetDeviceCaps(sh,LOGPIXELSX) div 254;
      r.Bottom:=2970 * GetDeviceCaps(sh,LOGPIXELSY) div 254;
      WebBrowser1.BoundsRect:=r;

      SetMapMode(ph,MM_ISOTROPIC);
      SetWindowExtEx(ph,r.Right,r.Bottom,nil);
      SetViewportExtEx(ph,r.Right,r.Bottom,nil);
      r.Right:=GetDeviceCaps(ph,HORZRES)-1;
      r.Bottom:=GetDeviceCaps(ph,VERTRES)-1;

      (WebBrowser1.ControlInterface as IViewObject).Draw(
        DVASPECT_CONTENT,
        1,
        nil,nil,0,ph,@r,nil,nil,0);
    finally
      Printer.Canvas.Unlock;
    end;
    Printer.EndDoc;
  except
    Printer.Abort;
    raise;
  end;

SetWindowExtEx 和 SetViewportExtEx 设置正确的缩放比例,以便您可以在 HTML/CSS 中使用单位“mm”。

关于delphi - 从 TWebBrowser 打印,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15702976/

相关文章:

delphi - 如何设置结果值?

delphi:icontent的目的是什么?

delphi - 从 TWebBrowser 获取 Cookie

html - 使用 Delphi 中的 TWebbrowser 组件向网站发送数据和从网站接收数据

Delphi TGIFImage 动画问题与某些 GIF 查看器有关

delphi - 如何捕捉父控件调整大小的时刻?

json - Delphi Superobject,通用列表到 json

delphi - 如何触发 HTML 表单的 onsubmit 事件?

ajax - 如何检查WebBrowser是否已完全完成?

delphi - 阻止 TWebBrowser 刷新的错误消息