Ian*_*oyd 9 delphi winapi rendering delphi-5 internet-explorer-9
我想将网页(即TWebBrowser)呈现给设备上下文.我想使用Internet Explorer的布局引擎将内容呈现给设备上下文(即图元文件,pdf图元文件).
从Internet Explorer 9开始,IHTMLElementRender不再支持该接口:
IHTMLElementRender接口
使用此接口将元素的内容绘制到指定的设备上下文,通常是打印机.
会员
的IHTMLElementRender接口从继承的IUnknown接口,但没有其他成员.
至于他们不再提及DrawToDC方法甚至存在:
IHTMLElementRender :: DrawToDC方法
已过时.将元素的内容绘制到指定的设备上下文.
句法
Run Code Online (Sandbox Code Playgroud)HRESULT DrawToDC( HDC hDC );参数
- hDC
[in] 指定要绘制的设备的HDC,通常是打印机.回报价值
如果成功则返回S_OK,否则返回错误值.
备注
从Windows Internet Explorer 9开始,不推荐使用此方法,不应使用此方法.
对于某些打印机,运行IHTMLElementRender :: DrawToDC可能会导致问题.通过首先运行IHTMLElementRender :: SetDocumentPrinter方法,然后将修改后的设备上下文传递给IHTMLElementRender :: DrawToDC,可以确保IHTMLElementRender :: DrawToDC在所有打印机上正常工作.
注意:我引用了所有文档,以便在Microsoft最终将其从MSDN中完全删除时仍可以找到它.随着接口声明:
IHTMLElementRender = interface(IUnknown)
['{3050F669-98B5-11CF-BB82-00AA00BDCE0B}']
function DrawToDC(hdc: HDC): HResult; stdcall;
function SetDocumentPrinter(const bstrPrinterName: WideString; hdc: HDC): HResult; stdcall;
end;
Run Code Online (Sandbox Code Playgroud)
IViewObject界面我试过转换使用IViewObject(例如如何在不使用Web浏览器的情况下呈现HTML元素?):
procedure RenderWebBrowserToMetafile(Browser: TWebBrowser; Metafilename: string);
var
view: IViewObject;
m: TMetafile;
mc: TMetafileCanvas;
w, h: Integer;
r: TRect;
dpix: Integer;
dpiy: Integer;
dc: HDC;
begin
w := WebBrowserScrollWidth(Browser);
h := WebBrowserScrollHeightStrict(Browser);
//96dpi screen to 300dpi metafile (destined for printer)
dc := GetDC(0);
try
dpix := GetDeviceCaps(GetDC(0), LOGPIXELSX);
dpiy := GetDeviceCaps(GetDC(0), LOGPIXELSY);
finally
ReleaseDC(0, dc);
end;
w := MulDiv(w, 300, dpix);
h := MulDiv(h, 300, dpiy);
view := Browser.Document as IViewObject;
m := TMetafile.Create;
try
m.Width := w;
m.Height := h;
r := Rect(0, 0, w, h);
mc := TMetafileCanvas.Create(m, 0);
try
view.Draw(
DVASPECT_CONTENT, //draw aspect
1, //index
nil, //pAspectInfo
nil, //pDVTargetDevice
0, //Target Device Context
mc.handle, //hdcDraw
@r, //target Bounds
@w, //window bounds (for metafiles)
nil, //continue function
0); //continue value
finally
mc.Free;
end;
m.SaveToFile(Metafilename);
finally
m.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
此代码的问题在于它只呈现浏览器的可见区域(即没有滚动内容):
我需要渲染整个网页(例如用于打印).
我尝试将绘制方面从DVASPECT_CONTENT(如本示例所示)更改为DVASPECT_DOCPRINT:
DVASPECT_DOCPRINT
提供屏幕上对象的表示,就像使用"文件"菜单中的"打印"命令将其打印到打印机一样.所描述的数据可以表示页面序列.
结果相同; 而不是渲染页面,只渲染可见部分:
我怎么能要求IE9渲染引擎渲染?
我也使用不同的尝试指数与一起DVASPECT_DOCPRINT.虽然IViewObject没有记录,但也许这就是你打印不同"页面"的方式:
view.Draw(DVASPECT_DOCPRINT, 1, ...);
view.Draw(DVASPECT_DOCPRINT, 2, ...);
view.Draw(DVASPECT_DOCPRINT, 3, ...);
...
view.Draw(DVASPECT_DOCPRINT, n, ...);
Run Code Online (Sandbox Code Playgroud)
但WebBrowser并不关心索引是什么; 只渲染当前View(我认为使用时有意义IViewObject).
如何将浏览器渲染到设备上下文?
注意:问题标记为delphi,但此问题中没有任何特定于delphi的内容.
更新:我还尝试了方面和索引的其他组合:
view.Draw(DVASPECT_CONTENT, -1, ...);
view.Draw(DVASPECT_DOCPRINT, -1, ...);
view.Draw(DVASPECT_CONTENT, 0, ...);
view.Draw(DVASPECT_DOCPRINT, 0, ...);
Run Code Online (Sandbox Code Playgroud)
使用 IViewObject,您可以创建当前视口的屏幕截图。我使用一个技巧来创建网页(没有任何框架)或框架文档的屏幕截图。
请注意,当文档非常大时,您应该小心执行此操作。