Link to home
Start Free TrialLog in
Avatar of sshirey
sshireyFlag for Afghanistan

asked on

Print a HTML CSS document from TWebbrowser object in DELPHI5

I am displaying a HTML CSS document in a TWebBrowser window.  I need to print the document
to the printer with "backgrounds" and "colors" addressed by "urls" in the HTML document.

I've tried various solutions from other users and find -
1)  Using the OLECMDID_PRINT, I lose the background and colors in the document that are pulled by
using an "url" address [same as if printed directly from Internet Explorer]
2)  If a take an image snapshot - I get the blank area around the document along with the scrollbars displayed
in my image.  Also, trying to print this image does not not display as a full page size.

So - I need to be able to print a document displayed within the TWebBrower window and have the page
look exactly as the screen looks in Delph5.  Any ideas?
SOLUTION
Avatar of Ephraim Wangoya
Ephraim Wangoya
Flag of United States of America 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
SOLUTION
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 sshirey

ASKER

I tried the code above - but the bitmap being created still has the additional space surrounding the document as part of the image.  My workscreen is 24" so I have alot of blank side space since the document is centered on the screen.  Does it make a difference to the routines above that I am loading the HTML document as  IPersistStreamInit.

Also - when using the printbitmap routine, I'm just getting a blank page printed.  I was receiving an error of PixelsPerInch not being defined - so I used 96 which is what most images are stored at.  I even changed it to not scale the bitmap and get a blank page printed??.

PixelsPerInch is property of form
 
you can change the procedure to be a private form method

procedure TForm1.PrintBitmap(ABitMap: TBitmap);
var
  ScaleX, ScaleY: Integer;
  RR: TRect;
begin
  with Printer do
  begin
    BeginDoc;
    try
      ScaleX := GetDeviceCaps(Handle, logPixelsX) div PixelsPerInch;
      ScaleY := GetDeviceCaps(Handle, logPixelsY) div PixelsPerInch;
      RR := Rect(0, 0, ABitmap.Width * scaleX, ABitmap.Height * ScaleY);
      Canvas.StretchDraw(RR, ABitmap);
    finally
      EndDoc;   //Methode EndDoc beendet den aktuellen Druckauftrag und schließt die
    end;
  end;
end;
Avatar of sshirey

ASKER

Unfortunately - I am using a TFrame for display and do not have a PixelsPerInch Property.

Also - is there any way of removing the excess space around the document when creating the bitmap.  Do not need the extra blank space when trying to print.
Thanks

I tested this and did not get any extra spaces. I'll take a look at the PrintBitmap procedure again.
for PixelsPerInch
If you are not using forms, use Screen.PixelsPerInch
....
ScaleX := GetDeviceCaps(Handle, logPixelsX) div Scree.PixelsPerInch
....
I have attached routines to crop the bitmap from
http://delphi-snippets.blogspot.com/2005/08/automatic-cropping-of-bitmap_18.html

In the button print click do

procedure TForm3.btnPrintClick(Sender: TObject);
var
  pDoc: IHTMLDocument2;
  pElement: IHTMLElement2;
  x, y: Integer;
  Bitmap: TBitmap;
  Color: TColor;
begin
  pDoc := WebBrowser1.Document as IHTMLDocument2;
  pElement := pDoc.body as IHTMLElement2;
  y := pElement.scrollHeight;
  x := pElement.scrollWidth;

  Bitmap := CreateThumbnailImage(WebBrowser1, Point(x, y));
  try
    //remove back color
    Color := Bitmap.Canvas.Pixels[Bitmap.Width, Bitmap.Height];
    AutoCropBitmap(Bitmap, 0, Color);
    Color := Bitmap.Canvas.Pixels[0, 0];
    AutoCropBitmap(Bitmap, 0, Color);
 
    //This wont have a gray background anymore
    Bitmap.SaveToFile(IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))) + 'test1.bmp');
  finally
    FreeAndNil(Bitmap);
  end;
end;
unit unBitmapCropping;

interface

uses
  Windows, Graphics, Dialogs, SysUtils, Math, Classes;

const
  PixelCountMax = 32768;

type
  pRGBArray = ^TRGBArray;
  TRGBArray = array[0..PixelCountMax-1] of TRGBTriple;

procedure AutoCropBitmap(InputBitmap, OutputBitmap: TBitmap; iBleeding : Integer); overload;
procedure AutoCropBitmap(InputBitmap, OutputBitmap: TBitmap; iBleeding : Integer; BackColor: TColor); overload;
procedure AutoCropBitmap(BitMapToCrop: TBitmap; iBleeding : Integer); overload;
procedure AutoCropBitmap(BitMapToCrop: TBitmap; iBleeding : Integer; BackColor: TColor); overload;
procedure AutoCropBmp(const sFileName : String; iBleeding : Integer); overload;
procedure AutoCropBmp(const sFileName : String; iBleeding : Integer; BackColor: TColor); overload;

implementation

procedure AutoCropBitmap(BitMapToCrop: TBitmap; iBleeding : Integer);
var
  bmpTmp : TBitmap;
begin
  bmpTmp := TBitmap.Create;
  try
    AutoCropBitmap(BitMapToCrop,bmpTmp,iBleeding);
    BitMapToCrop.Assign(bmpTmp);
  finally
    bmpTmp.Free;
  end;
end;

procedure AutoCropBitmap(BitMapToCrop: TBitmap; iBleeding : Integer; BackColor: TColor);
var
  bmpTmp : TBitmap;
begin
  bmpTmp := TBitmap.Create;
  try
    AutoCropBitmap(BitMapToCrop,bmpTmp,iBleeding, BackColor);
    BitMapToCrop.Assign(bmpTmp);
  finally
    bmpTmp.Free;
  end;
end;

procedure AutoCropBitmap(InputBitmap, OutputBitmap: TBitmap; iBleeding : Integer);
begin
  AutoCropBitmap(InputBitmap,OutputBitmap, iBleeding, InputBitmap.Canvas.Pixels[0,0]);
end;

procedure AutoCropBitmap(InputBitmap, OutputBitmap: TBitmap; iBleeding : Integer; BackColor: TColor);
var
  Row: pRGBArray;
  MyTop, MyBottom, MyLeft, i, j, MyRight: Integer;
begin
  MyTop := InputBitmap.Height;
  MyLeft := InputBitmap.Width;
  MyBottom := 0;
  MyRight := 0;
  InputBitmap.PixelFormat := pf24bit;
  OutputBitmap.PixelFormat := pf24Bit;
  { Find Top }
  for j := 0 to InputBitmap.Height-1 do
  begin
    if j > MyTop then
      Break;
    Row := pRGBArray(InputBitmap.Scanline[j]);
    for i:= InputBitmap.Width - 1 downto 0 do
      if ((Row[i].rgbtRed   <> GetRvalue(BackColor)) or (Row[i].rgbtGreen <> GetGvalue(BackColor)) or (Row[i].rgbtBlue  <> GetBvalue(BackColor))) then
      begin
        MyTop := j;
        Break;
      end;
  end;
  if MyTop = InputBitmap.Height then{ Empty Bitmap }
    MyTop := 0;
  { Find Bottom }
  for j := InputBitmap.Height-1 Downto MyTop do
  begin
    if (j + 1) < MyBottom then
      Break;

    Row := pRGBArray(InputBitmap.Scanline[j]);
    for i:= InputBitmap.Width - 1 downto 0  do
      if ((Row[i].rgbtRed   <> GetRvalue(BackColor)) or (Row[i].rgbtGreen <> GetGvalue(BackColor)) or (Row[i].rgbtBlue  <> GetBvalue(BackColor))) then
      begin
        MyBottom := j+1;
        Break;
      end;
  end;
  { Find Left }
  for j := MyTop to MyBottom-1 do
  begin
    Row := pRGBArray(InputBitmap.Scanline[j]);
    for i:= 0 to MyLeft-1 do
      if ((Row[i].rgbtRed <> GetRvalue(BackColor)) or (Row[i].rgbtGreen <> GetGvalue(BackColor)) or(Row[i].rgbtBlue  <> GetBvalue(BackColor))) then
      begin
        MyLeft := i;
        Break;
      end;
  end;
  if MyLeft = InputBitmap.Width then   { Empty Bitmap }
    MyLeft := 0;     { Find Right }

  for j := MyTop to MyBottom -1 do
  begin
    Row := pRGBArray(InputBitmap.Scanline[j]);
    for i:= InputBitmap.Width-1 downto MyRight do
      if ((Row[i].rgbtRed <> GetRvalue(BackColor)) or (Row[i].rgbtGreen <> GetGvalue(BackColor)) or (Row[i].rgbtBlue  <> GetBvalue(BackColor))) then
      begin
        MyRight := i+1;
        Break;
      end;
  end;

  if (MyRight = 0) or (MyBottom = 0) then   { Empty Bitmap }
    iBleeding := 0;

  OutputBitmap.Width  := MyRight - MyLeft + (iBleeding * 2);
  OutputBitmap.Height := MyBottom - MyTop + (iBleeding * 2);
  OutputBitmap.Canvas.Brush.Color := BackColor;
  OutputBitmap.Canvas.FillRect(Rect(0,0,OutputBitmap.Width,OutputBitmap.Height));
  BitBlt(OutputBitmap.canvas.Handle, -MyLeft + iBleeding, -MyTop + iBleeding,MyLeft + MyRight,MyTop + MyBottom, InputBitmap.Canvas.Handle, 0, 0, SRCCOPY);
end;

procedure AutoCropBmp(const sFileName : String; iBleeding : Integer);
var
  InputBitmap, OutputBitmap : TBitmap;
begin
  if not FileExists(sFileName) then
    raise Exception.Create('File doesn''s exists.');
  InputBitmap   := TBitmap.Create;
  OutputBitmap  := TBitmap.Create;
  try
    InputBitmap.LoadFromFile(sFileName);
    OutputBitmap.PixelFormat := InputBitmap.PixelFormat;
    AutoCropBitmap(InputBitmap, OutputBitmap,iBleeding);
    OutputBitmap.SaveToFile(sFileName);
  finally
    OutputBitmap.Free;
    InputBitmap.Free;
  end;
end;

procedure AutoCropBmp(const sFileName : String; iBleeding : Integer; BackColor: TColor);
var
  InputBitmap, OutputBitmap : TBitmap;
begin
  if not FileExists(sFileName) then
    raise Exception.Create('File doesn''s exists.');

  InputBitmap   := TBitmap.Create;
  OutputBitmap  := TBitmap.Create;
  try
    InputBitmap.LoadFromFile(sFileName);
    OutputBitmap.PixelFormat := InputBitmap.PixelFormat;
    AutoCropBitmap(InputBitmap, OutputBitmap,iBleeding, BackColor);
    OutputBitmap.SaveToFile(sFileName);
  finally
    OutputBitmap.Free;
    InputBitmap.Free;
  end;
end;

end.

Open in new window

ASKER CERTIFIED SOLUTION
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 sshirey

ASKER

Part of my problem I think is the HTML document I'm working with and how I am loading it into the TWebBrowser.  
Some items suggested didn't work for me - but probably would for other HTML documents and users.

I could not of gotten as far on my project as where I stand today without ewangoya's assistance.