从TWebBrowser打印 [英] Printing from TWebBrowser

查看:57
本文介绍了从TWebBrowser打印的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using the following unit to display - and print - HTML code via a TWebBrowser which is displayed in a non-modal dialog. In my production program, the following code works under Windows-XP but fails with Windows-7 (the error message is always External exception C015D00F). In order to isolate the problem, I wrote a simple test program which also has a non-modal dialog containing a TWebBrowser; on its own, this test program works correctly with Windows-7, but when I plug the non-modal dialog from the test program into the production program, I get the external exception.

这大概表明调用程序存在问题,而不是被调用单元存在问题,但是我看不出是什么问题.HTML代码是手工制作的,但可以正确显示.

This presumably indicates that there is a problem with the calling program and not the called unit, but I can't see what that problem is. The HTML code is hand crafted but displays correctly.

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

What could be the problem? The printing code comes from the 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)会给出相同的错误.

Using the statement Web.ControlInterface.ExecWB (OLECMDID_PRINT, OLECMDEXECOPT_PROMPTUSER, vaIn, vaOut) gives the same error.

几天后

我尝试了一种完全不同的方法来解决该问题.在HTML代码中,我添加了一个JavaScript代码段,该代码段显示了打印"按钮并添加了"onprint"事件.再次,这在我的开发计算机(XP)上不能正常工作,但在我的客户的计算机(Win7)上却无法正常工作,在该计算机上,程序因公告外部异常C015D00F(与以前的地址相同)而冻结.

I tried a completely different approach to the problem. In the HTML code I added a javascript snippet which displays a 'print' button and adds an 'onprint' event. Once again, this works fine on my development machine (XP) but not on my client's machines (Win7), where the program freezes with the announcement External exception C015D00F (same address as previously).

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

After no small amount of googling, I discovered that Exception code C015000F is caused by "the activation context being deactivated is not the most recently activated one." What does this mean to a poor Delphi programmer?

推荐答案

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

If I remember correctly, the IHTMLWindow3.print method pops up the default 'sent to printer' system dialog. Do you want this? For an application I once searched for a way to avoid this, and then found this code.

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".

The SetWindowExtEx and SetViewportExtEx set the scaling correct so you can use the unit "mm" in the HTML/CSS.

这篇关于从TWebBrowser打印的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆