¿Cómo renderizar WebBrowser al contexto del dispositivo?
Quiero hacer una página web (es decir,TWebBrowser
) a un contexto de dispositivo. Quiero usar el motor de diseño de Internet Explorer para representar contenido en un contexto de dispositivo (es decir, metarchivo, metarchivo pdf).
A partir de Internet Explorer 9 elIHTMLElementRender
la interfaz ya no essoportado:
Use esta interfaz para dibujar el contenido de un elemento en un contexto de dispositivo específico, normalmente una impresora.
Miembros
losIHTMLElementRender interfaz hereda de laI Desconocido interfaz pero no tiene miembros adicionales.
Al punto que ya no mencionan que laMétodo DrawToDC incluso existe:
IHTMLElementRender :: Método DrawToDCObsoleto. Dibuja el contenido del elemento en el contexto del dispositivo especificado.
Sintaxis
HRESULT DrawToDC(
HDC hDC
);
Parámetros
hDC[en] unaHDC especificando el dispositivo que se va a dibujar, normalmente una impresora.
Valor de retorno
Devuelve S_OK si tiene éxito, o un valor de error en caso contrario.
Observaciones
A partir de Windows Internet Explorer 9, este método está en desuso y no debe utilizarse.
Con algunas impresoras, funcionando.IHTMLElementRender :: DrawToDC Puede causar problemas. Usted puede asegurarse de queIHTMLElementRender :: DrawToDC Funciona correctamente en todas las impresoras ejecutandoIHTMLElementRender :: SetDocumentPrinter Método primero, y luego pasar el contexto del dispositivo modificado aIHTMLElementRender :: DrawToDC.
Nota: Estoy citando toda la documentación para que aún se pueda encontrar cuando Microsoft finalmente la elimine por completo de MSDN. Junto con la declaración de interfaz:
IHTMLElementRender = interface(IUnknown)
['{3050F669-98B5-11CF-BB82-00AA00BDCE0B}']
function DrawToDC(hdc: HDC): HResult; stdcall;
function SetDocumentPrinter(const bstrPrinterName: WideString; hdc: HDC): HResult; stdcall;
end;
Utilizar elIViewObject
interfazHe intentado convertir para usar elIViewObject
(p.ej.¿Cómo renderizar elemento HTML sin usar navegador web?):
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;
El problema con este código es que solo representa lavisible área del navegador (es decir, sin contenido desplazado):
necesito hacer eltodo página web (por ejemplo, para imprimir).
Intenté cambiar eldibujar aspecto desdeDVASPECT_CONTENT
(comoeste ejemplo hace), aDVASPECT_DOCPRINT
:
DVASPECT_DOCPRINT
Proporciona una representación del objeto en la pantalla como si se imprimiera en una impresora usando el comando Imprimir del menú Archivo. Los datos descritos pueden representar una secuencia de páginas.
Con el mismo resultado; En lugar de representar la página, solo se representa la parte visible:
¿Cómo puedo pedir al motor de renderizado IE9 que renderice?
También traté de usar diferentesíndices junto conDVASPECT_DOCPRINT
. A pesar de queIViewObject
No está documentado, tal vez así es como se imprime diferente."páginas":
view.Draw(DVASPECT_DOCPRINT, 1, ...);
view.Draw(DVASPECT_DOCPRINT, 2, ...);
view.Draw(DVASPECT_DOCPRINT, 3, ...);
...
view.Draw(DVASPECT_DOCPRINT, n, ...);
Pero al WebBrowser no le importa lo que es el índice; solo renderizando la corrienteView
(que supongo que tiene sentido cuando se usaIViewObject
).
¿Cómo renderizo un navegador a un contexto de dispositivo?
Nota: La pregunta está etiquetada condelphi
, pero no hay nada en esta pregunta que seaDelphi específico.
Actualizar: También probé otras combinaciones deaspecto yíndice:
view.Draw(DVASPECT_CONTENT, -1, ...);
view.Draw(DVASPECT_DOCPRINT, -1, ...);
view.Draw(DVASPECT_CONTENT, 0, ...);
view.Draw(DVASPECT_DOCPRINT, 0, ...);