Passing a bitmap to DLL using handle to it

Hello experts :-)

I need to pass a bitmap to a dll, edit it there and then send to back.

I know (thank you ziolko :-) ) how to do it using (Buffer : Pointer; StreamLength : Int64).

However, I was told that it is possible to pass a handle to bitmap to DLL and make it this way.

Question: how can I do it?

Polon
panJamesAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

MerijnBSr. Software EngineerCommented:
do you write the dll yourself?
0
developmentguruPresidentCommented:
The TBitmap has a handle property and this is the handle that Windows recognizes as the bitmap.  Passing this hanlde should be what you are looking for.  If you are writing the DLL yourself then you can create a TBitmap object and assign the handle to it.  You should then be able to edit it via the bitmap object's canvas property as usual.  The attached code shows an example (without the dll).  Place 2 paint boxes and a button on a form.  Paste in the code and attach the paint boxes OnPaint methods, form create and destroy methods, and the button click method.  The form creates a bitmap and draws to it.  When you click the button it copies the handle from the drawn bitmap to the as yet untouched bitmap then invalidates the second paint box to show you the result.

unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;
 
type
  TForm1 = class(TForm)
    PaintBox1: TPaintBox;
    PaintBox2: TPaintBox;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure PaintBox1Paint(Sender: TObject);
    procedure PaintBox2Paint(Sender: TObject);
  private
    { Private declarations }
    Bitmap1, Bitmap2 : TBitmap;
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  Bitmap2.Handle := Bitmap1.Handle;
  PaintBox2.Invalidate;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  Bitmap1 := TBitmap.Create;
  with Bitmap1, Canvas do
    begin
      Width := 100;
      Height := 100;
      Brush.Color := clBlue;
      FillRect(Rect(0, 0, 99, 99));
    end;
  Bitmap2 := TBitmap.Create;
end;
 
procedure TForm1.FormDestroy(Sender: TObject);
begin
  Bitmap1.Free;
  Bitmap2.Free;
end;
 
procedure TForm1.PaintBox1Paint(Sender: TObject);
var
  R : TRect;
 
begin
  R := Rect(0, 0, 99, 99);
  PaintBox1.Canvas.CopyRect(R, Bitmap1.Canvas, R);
end;
 
procedure TForm1.PaintBox2Paint(Sender: TObject);
var
  R : TRect;
 
begin
  R := Rect(0, 0, 99, 99);
  PaintBox2.Canvas.CopyRect(R, Bitmap2.Canvas, R);
end;
 
end.

Open in new window

0
developmentguruPresidentCommented:
I modified the contents of the button click event to draw to the second bitmap and show that both update...
procedure TForm1.Button1Click(Sender: TObject);
begin
  Bitmap2.Handle := Bitmap1.Handle;
  with Bitmap2, Canvas do
    begin
      MoveTo(0, 0);
      LineTo(99, 99);
    end;
  PaintBox1.Invalidate;
  PaintBox2.Invalidate;
end;

Open in new window

0
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

ziolkoCommented:
I'm afraid that's not what you looking for but that's best solution I've come up with

library BMPDLL;

uses
  SysUtils,
  Classes,
  Windows,
  Graphics;

{$R *.res}

procedure MakeColorAnalysis3(var Bitmap: HBITMAP);stdcall;
var bmp: TBitmap;
begin
  bmp := TBitmap.Create;
  try
    bmp.Handle := Bitmap;
    with TBitmap.Create do begin
      Assign(bmp);
      Canvas.MoveTo(0, 0);
      Canvas.LineTo(256, 256);
      Bitmap := Handle;
    end;
  finally
    bmp.Free;
  end;  
end;

exports
  MakeColorAnalysis3;

begin
end.

EXE:
interface
procedure MakeColorAnalysis3(var Bitmap: HBITMAP);stdcall;
implementation
procedure MakeColorAnalysis3;external 'bmpdll.dll' name 'MakeColorAnalysis3';

procedure TForm1.Button6Click(Sender: TObject);
var h: HBITMAP;
begin
  h := Image1.Picture.Bitmap.Handle;
  MakeColorAnalysis3(h);
  Image1.Picture.Bitmap.Handle := h;
end;

ziolko.
0
ziolkoCommented:
I've also found some C++ code that supposedly lets you access raw bmp bits represented by HBITMAP (so there's no need to create additional bmp in DLL and re-assign Handle on EXE side) but can't make it work all I got is scrambled image.

ziolko.
0
ziolkoCommented:
slightly changed DLL so there's no memory leak:

library BMPDLL;

uses
  SysUtils,
  Classes,
  Windows,
  Graphics;

{$R *.res}

var TmpBMP: TBitmap;

procedure MakeColorAnalysis3(var Bitmap: HBITMAP);stdcall;
var bmp: TBitmap;
begin
  bmp := TBitmap.Create;
  try
    bmp.Handle := Bitmap;
    with TmpBMP do begin
      Assign(bmp);
      Canvas.MoveTo(0, 0);
      Canvas.LineTo(256, 256);
      Bitmap := Handle;
    end;
  finally
    bmp.Free;
  end;  
end;

procedure OnDLLLoad;
begin
  TmpBMP := TBitmap.Create;  
end;

procedure OnDLLUnLoad;
begin
  FreeAndNil(TmpBMP);
end;

procedure MyDLLProc(dwReason: Integer);
begin
  case dwReason of
    DLL_PROCESS_ATTACH:   OnDLLLoad;
    DLL_PROCESS_DETACH:   OnDLLUnLoad;
  end;
end;

exports
  MakeColorAnalysis3;

begin
  DllProc := MyDLLProc;
  DllProc(DLL_PROCESS_ATTACH);
end.

ziolko.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ziolkoCommented:
 with TmpBMP do begin
      ReleaseHandle;    
      Assign(bmp);
      Canvas.MoveTo(0, 0);

ziolko.
0
ziolkoCommented:
any progress on this one?


ziolko.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.