Link to home
Start Free TrialLog in
Avatar of Bart_Michael
Bart_Michael

asked on

Web Page Snapshot (BITMAP) in WebBrowser / Internet Explorer - FIX A BUG

Hello!
To "convert" a web page to a bitmap I have used excellent rllibby's code from
https://www.experts-exchange.com/questions/21608891/Web-Page-Snapshots-good-solution-but-help-needed.html
for example: CreateScaledImage(WebBrowser1,1).SaveToFile('C:\test.bmp');
It worked very well, but now...

In Internet Explorer 8 it does not work on MANY PAGES - for example
http://www.ableget.com
http://www.cnet.com
I spent lot of time trying to figure, what is wrong but I did not found the solution.

Does anybody has an idea, what is wrong? Did Microsoft changed something?

On simple pages this code works correctly - for example
http://www.google.com

I would be VERY GRATEFUL for suggestions.
Best regards
Bart

unit WebUtils;
////////////////////////////////////////////////////////////////////////////////
//
// Ā  Unit Ā  Ā  Ā  Ā : Ā WebUtils
// Ā  Date Ā  Ā  Ā  Ā : Ā 10.27.2005 (updated 10.28.2005)
// Ā  Description : Ā Utility functions based on the TWebBrowser object
//
//
// Ā  function GetDocumentSize(Browser: TWebBrowser): TPoint;
//
// Ā  Ā  Ā Returns the document's body size as a TPoint, where X = width and Y = height
//
// Ā  function GetBrowserElement(Browser: TWebBrowser; out Element: IHTMLElement2): HResult;
//
// Ā  Ā  Ā Returns the actual element required to perform the rendering to a canvas handle.
// Ā  Ā  Ā For most pages, this will be the body element. But for some, eg:
//
// Ā  Ā  Ā  Ā  https://www.experts-exchange.com
// Ā  Ā  Ā  Ā  http://www.msn.com
//
// Ā  Ā  Ā the parent element will need to be used. The element to use is based on
// Ā  Ā  Ā getting the parent and checking it for a clientwidth/height of zero. If zero,
// Ā  Ā  Ā then the body element can be used. If not zero, then the parent must be used.
//
// Ā  function CreateThumbnailImage(Browser: TWebBrowser; OutputSize: TPoint): TBitmap;
//
// Ā  Ā  Ā Returns a bitmap object of the document page where the width and height is
// Ā  Ā  Ā determined by the point (x = width, y=height) passed in OutputSize.
//
// Ā  function CreateScaledImage(Browser: TWebBrowser; Scale: Double): TBitmap;
//
// Ā  Ā  Ā Returns a scaled bitmap object of the document page. A scaling of 1.0 will
// Ā  Ā  Ā return the page at its actual size. To return a 1/10 scaled image of the
// Ā  Ā  Ā document for example, 0.1 would be passed to Scale.
//
////////////////////////////////////////////////////////////////////////////////
interface

////////////////////////////////////////////////////////////////////////////////
// Ā  Include units
////////////////////////////////////////////////////////////////////////////////
uses
Ā  Windows, SysUtils, Classes, Graphics, ShdocVW, ActiveX, MSHTML;

////////////////////////////////////////////////////////////////////////////////
// Ā  Constants
////////////////////////////////////////////////////////////////////////////////
const
Ā  IID_IHTMLElementRender: TGUID = Ā '{3050F669-98B5-11CF-BB82-00AA00BDCE0B}';

////////////////////////////////////////////////////////////////////////////////
// Ā  Interfaces
////////////////////////////////////////////////////////////////////////////////
type
Ā  IHTMLElementRender Ā  = Ā interface(IUnknown)
Ā  Ā  Ā ['{3050F669-98B5-11CF-BB82-00AA00BDCE0B}']
Ā  Ā  Ā function Ā  Ā  Ā  Ā  Ā DrawToDC(_hDC: HDC): HResult; stdcall;
Ā  Ā  Ā function Ā  Ā  Ā  Ā  Ā SetDocumentPrinter(bstrPrinterName: WideString; _hDC: HDC): HResult; stdcall;
Ā  end;

////////////////////////////////////////////////////////////////////////////////
// Ā  Utility functions
////////////////////////////////////////////////////////////////////////////////
function Ā  GetDocumentSize(Browser: TWebBrowser): TPoint;
function Ā  GetBrowserElement(Browser: TWebBrowser; out Element: IHTMLElement2): HResult;
function Ā  CreateThumbnailImage(Browser: TWebBrowser; OutputSize: TPoint): TBitmap;
function Ā  CreateScaledImage(Browser: TWebBrowser; Scale: Double): TBitmap;

implementation

function GetBrowserElement(Browser: TWebBrowser; out Element: IHTMLElement2): HResult;
var Ā pDoc: Ā  Ā  Ā  Ā  Ā IHTMLDocument2;
Ā  Ā  Ā pElemParent: Ā  IHTMLElement;
Ā  Ā  Ā pElement: Ā  Ā  Ā IHTMLElement;
Ā  Ā  Ā pElement2: Ā  Ā  IHTMLElement2;
begin

Ā  // Check browser document
Ā  if Assigned(Browser.Document) then
Ā  begin
Ā  Ā  Ā // QI for document 2 interface
Ā  Ā  Ā result:=Browser.Document.QueryInterface(IHTMLDocument2, pDoc);
Ā  Ā  Ā // Check result
Ā  Ā  Ā if Succeeded(result) then
Ā  Ā  Ā begin
Ā  Ā  Ā  Ā  // Resource protection
Ā  Ā  Ā  Ā  try
Ā  Ā  Ā  Ā  Ā  Ā // Check document body
Ā  Ā  Ā  Ā  Ā  Ā if Assigned(pDoc.Body) then
Ā  Ā  Ā  Ā  Ā  Ā begin
Ā  Ā  Ā  Ā  Ā  Ā  Ā  // QI for body element
Ā  Ā  Ā  Ā  Ā  Ā  Ā  result:=pDoc.Body.QueryInterface(IHTMLElement, pElement);
Ā  Ā  Ā  Ā  Ā  Ā  Ā  // Check result
Ā  Ā  Ā  Ā  Ā  Ā  Ā  if Succeeded(result) then
Ā  Ā  Ā  Ā  Ā  Ā  Ā  begin
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā // Resource protection
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā try
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  // Get parent element
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  pElemParent:=pElement.parentElement;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  // Check parent
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  if Assigned(pElemParent) then
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  begin
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā // Resource protection
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā try
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  // Get the element 2 interface
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  if Succeeded(pElemParent.QueryInterface(IHTMLElement2, pElement2)) then
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  begin
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā // Check parent interface for zero client width or height
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā if (pElement2.clientWidth = 0) or (pElement2.clientHeight = 0) then
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  // QI for element 2 interface
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  result:=pElement.QueryInterface(IHTMLElement2, Element)
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā else
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  // We have the element we are after
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Element:=pElement2;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  end
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  else
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā // QI for element 2 interface
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā result:=pElement.QueryInterface(IHTMLElement2, Element);
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā finally
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  // Release the interface
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  pElemParent:=nil;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā end;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  end
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  else
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā // Return nearest COM error
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā result:=E_NOINTERFACE;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā finally
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  // Release the interface
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  pElement:=nil;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā end;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  end;
Ā  Ā  Ā  Ā  Ā  Ā end
Ā  Ā  Ā  Ā  Ā  Ā else
Ā  Ā  Ā  Ā  Ā  Ā  Ā  // Return nearest COM error
Ā  Ā  Ā  Ā  Ā  Ā  Ā  result:=E_NOINTERFACE;
Ā  Ā  Ā  Ā  finally
Ā  Ā  Ā  Ā  Ā  Ā // Release the interface
Ā  Ā  Ā  Ā  Ā  Ā pDoc:=nil;
Ā  Ā  Ā  Ā  end;
Ā  Ā  Ā end;
Ā  end
Ā  else
Ā  Ā  Ā // Return nearest COM error
Ā  Ā  Ā result:=E_NOINTERFACE;

end;

function GetDocumentSize(Browser: TWebBrowser): TPoint;
var Ā pElement: Ā  Ā  Ā IHTMLElement2;
begin

Ā  // Get the browser body element interface
Ā  if Succeeded(GetBrowserElement(Browser, pElement)) then
Ā  begin
Ā  Ā  Ā // Resource protection
Ā  Ā  Ā try
Ā  Ā  Ā  Ā  // Set result size
Ā  Ā  Ā  Ā  result:=Point(pElement.ScrollWidth, pElement.ScrollHeight);
Ā  Ā  Ā finally
Ā  Ā  Ā  Ā  // Release the interface
Ā  Ā  Ā  Ā  pElement:=nil;
Ā  Ā  Ā end;
Ā  end

end;

function CreateScaledImage(Browser: TWebBrowser; Scale: Double): TBitmap;
var Ā ptActual: Ā  Ā  Ā TPoint;
Ā  Ā  Ā ptScale: Ā  Ā  Ā  TPoint;
begin

Ā  // Get actual size
Ā  ptActual:=GetDocumentSize(Browser);

Ā  // Apply the scaling to it
Ā  ptScale.x:=Round(ptActual.x * Scale);
Ā  ptScale.y:=Round(ptActual.y * Scale);

Ā  // Get the image
Ā  result:=CreateThumbnailImage(Browser, ptScale);

end;

function CreateThumbnailImage(Browser: TWebBrowser; OutputSize: TPoint): TBitmap;
var Ā pElement: Ā  Ā  Ā IHTMLElement2;
Ā  Ā  Ā pRender: Ā  Ā  Ā  IHTMLElementRender;
Ā  Ā  Ā bmpRender: Ā  Ā  Array [0..1] of TBitmap;
Ā  Ā  Ā dwClientWidth: Integer;
Ā  Ā  Ā dwClientHeight:Integer;
Ā  Ā  Ā dwIndex: Ā  Ā  Ā  Integer;
Ā  Ā  Ā dwX: Ā  Ā  Ā  Ā  Ā  Integer;
Ā  Ā  Ā dwLastX: Ā  Ā  Ā  Integer;
Ā  Ā  Ā bDoneX: Ā  Ā  Ā  Ā Boolean;
Ā  Ā  Ā dwY: Ā  Ā  Ā  Ā  Ā  Integer;
Ā  Ā  Ā dwLastY: Ā  Ā  Ā  Integer;
Ā  Ā  Ā bDoneY: Ā  Ā  Ā  Ā Boolean;
begin

Ā  // Create resulting image
Ā  result:=TBitmap.Create;

Ā  // Set size
Ā  result.Width:=OutputSize.x;
Ā  result.Height:=OutputSize.y;

Ā  // Lock update
Ā  LockWindowUpdate(Browser.Handle);

Ā  // Resource protection
Ā  try
Ā  Ā  Ā // Get the browser body element interface
Ā  Ā  Ā if Succeeded(GetBrowserElement(Browser, pElement)) then
Ā  Ā  Ā begin
Ā  Ā  Ā  Ā  // Resource protection
Ā  Ā  Ā  Ā  try
Ā  Ā  Ā  Ā  Ā  Ā // Get the renderer
Ā  Ā  Ā  Ā  Ā  Ā if Succeeded(pElement.QueryInterface(IID_IHTMLElementRender, pRender)) then
Ā  Ā  Ā  Ā  Ā  Ā begin
Ā  Ā  Ā  Ā  Ā  Ā  Ā  // Resource protection
Ā  Ā  Ā  Ā  Ā  Ā  Ā  try
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā // Create images to blit the parts to
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā for dwIndex:=0 to 1 do
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā begin
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  bmpRender[dwIndex]:=TBitmap.Create;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  bmpRender[dwIndex].Width:=pElement.scrollWidth;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  bmpRender[dwIndex].Height:=pElement.scrollHeight;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā end;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā // Set render "printer"
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā pRender.SetDocumentPrinter('Bitmap', bmpRender[0].Canvas.Handle);
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā // Get client width and height
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā dwClientWidth:=pElement.clientWidth;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā dwClientHeight:=pElement.clientHeight;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā // Resource protection
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā try
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  // Set starting X variables
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  dwX:=pElement.scrollWidth;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  dwLastX:=(-1);
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  bDoneX:=False;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  // Loop while X not done
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  while not(bDoneX) do
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  begin
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā // Scroll
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā pElement.scrollLeft:=dwX;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā // Get scroll
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā dwX:=pElement.scrollLeft;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā // Check for (-1)
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā if (dwLastX = (-1)) then dwLastX:=dwX + dwClientWidth;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā // Set starting Y variables
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā dwY:=pElement.scrollHeight;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā dwLastY:=(-1);
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā bDoneY:=False;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā // Loop while Y not done
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā while not(bDoneY) do
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā begin
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  // Scroll
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  pElement.scrollTop:=dwY;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  // Get scroll
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  dwY:=pElement.scrollTop;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  // Check for (-1)
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  if (dwLastY = (-1)) then dwLastY:=dwY + dwClientHeight;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  // Draw to bitmap handle
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  if (pRender.DrawToDC(bmpRender[0].Canvas.Handle) = S_OK) then
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  begin
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā // Blit the image
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā BitBlt(bmpRender[1].Canvas.Handle, dwX, dwY, dwLastX-dwX, dwLastY-dwY, bmpRender[0].Canvas.Handle, 2, 2,SRCCOPY);
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  end;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  // Update the Y variables
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  bDoneY:=(dwY = 0);
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  dwLastY:=dwY;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Dec(dwY, (dwClientHeight-4));
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā end;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā // Update the X variables
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā bDoneX:=(dwX = 0);
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā dwLastX:=dwX;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā Dec(dwX, (dwClientWidth-4));
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  end;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  // Stretch draw the image to the resulting bitmap
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  StretchBlt(result.Canvas.Handle, 0, 0, OutputSize.x, OutputSize.y, bmpRender[1].Canvas.Handle, 0, 0, bmpRender[1].Width, bmpRender[1].Height, SRCCOPY);
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā finally
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  // Free the bitmap
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  for dwIndex:=0 to 1 do FreeAndNil(bmpRender[dwIndex]);
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā end;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  finally
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā // Release the interface
Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā  Ā pRender:=nil;
Ā  Ā  Ā  Ā  Ā  Ā  Ā  end;
Ā  Ā  Ā  Ā  Ā  Ā end;
Ā  Ā  Ā  Ā  finally
Ā  Ā  Ā  Ā  Ā  Ā // Release the interfaces
Ā  Ā  Ā  Ā  Ā  Ā pElement:=nil;
Ā  Ā  Ā  Ā  end;
Ā  Ā  Ā end;
Ā  finally
Ā  Ā  Ā // Unlock update
Ā  Ā  Ā LockWindowUpdate(0);
Ā  end;

end;

end.
Avatar of Mahdi78
Mahdi78
Flag of Algeria image

The following code will make jpeg Snapshot


unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    WebBrowser1: TWebBrowser;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses  MSHTML, ComObj, ActiveX, jpeg;

{$R *.dfm}

procedure generateJPEGfromBrowser(browser: iWebBrowser2; jpegFQFilename: string;
  srcHeight: Integer; srcWidth: Integer; tarHeight: Integer; tarWidth: Integer);
var
  sourceDrawRect: TRect;
  targetDrawRect: TRect;
  sourceBitmap: TBitmap;
  targetBitmap: TBitmap;
  jpeg: TJPEGImage;
  viewObject: IViewObject;
begin
  sourceBitmap := TBitmap.Create;
  targetBitmap := TBitmap.Create;
  jpeg := TJPEGImage.Create;
  try
    try
      sourceDrawRect := Rect(0, 0, srcWidth, srcHeight);
      sourceBitmap.Width  := srcWidth;
      sourceBitmap.Height := srcHeight;

      viewObject := browser as IViewObject;

      if viewObject = nil then
        Exit;

      OleCheck(viewObject.Draw(DVASPECT_CONTENT, 1, nil, nil, 0,
        sourceBitmap.Canvas.Handle, @sourceDrawRect, nil, nil, 0));

      // Resize the src bitmap to the target bitmap
      targetDrawRect := Rect(0, 0, tarWidth, tarHeight);
      targetBitmap.Height := tarHeight;
      targetBitmap.Width  := tarWidth;
      targetBitmap.Canvas.StretchDraw(targetDrawRect, sourceBitmap);

      // Create a JPEG from the Bitmap and save it
      jpeg.Assign(targetBitmap);

      jpeg.SaveToFile(jpegFQFilename);
    finally
      jpeg.Free;
      sourceBitmap.Free;
      targetBitmap.Free;
    end;
  except
    // Error Code
  end;
end;

procedure Capture;
var
  IDoc1: IHTMLDocument2;
  Web: ShDocVW.IWebBrowser2;
  tmpX, tmpY: Integer;
  imagefl : string;
begin
imagefl := ExtractFilePath(Application.ExeName)+'\test.jpg' ;
  with Form1.WebBrowser1 do
  begin
    Document.QueryInterface(IHTMLDocument2, iDoc1);
    Web := ControlInterface;
    tmpX := Height;
    tmpY := Width;
    TControl(Form1.WebBrowser1).Visible := Boolean(0);
    Height := OleObject.Document.ParentWindow.Screen.Height;
    Width := OleObject.Document.ParentWindow.Screen.Width;

    generateJPEGfromBrowser(Web, imagefl,Height, Width, Height, Width);
    Height := tmpX;
    Width := tmpY;
    TControl(Form1.WebBrowser1).Visible := Boolean(1);
  end;

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Capture;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
WebBrowser1.Navigate('http://www.google.com');
end;

end.

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Mahdi78
Mahdi78
Flag of Algeria image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Bart_Michael
Bart_Michael

ASKER

Thank You VERY MUCH!
Your code works correctly. I have found on the Internet, that Internet Explorer 8 has bugs in IHTMLElementRender.DrawToDC

Your solution uses IViewObject.Draw, and it works fine (until a new bug will be introduced :-)

Best regards
Bart
the suggested solution however only creates a screenshot of the part of the website visible in the browser, the first code makes a full copy of the website, regardless of the size of the TWebbrowser.