Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

LoadBitmap won't load bitmap

0 views
Skip to first unread message

Jef Charlier

unread,
Oct 29, 1999, 3:00:00 AM10/29/99
to
On the Delphi5 Pro companion disk I found in the Delphi Super Recall
database (FAQs attention might be old solutions for D1, D2, D3) :

=FAQ1=======

Bitmaps and cursors can be stored in a resource (RES) files and
linked into your application's EXE file. RES files can be created
with Delphi's Image Editor or Borland's Resource Workshop that comes
with the Delphi RAD Pack. Bitmaps and cursors stored in RES files
(after being bound into an EXE or DLL) can be retrieved by using the
API functions LoadBitmap and LoadCursor, respectively.


Loading Bitmaps
---------------
The LoadBitmap API call is defined as follows:

function LoadBitmap(Instance: THandle;
BitmapName: PChar): HBitmap;

The first parameter is the instance handle of the module (EXE or DLL)
that contains the RES file you wish to get a resource from. Delphi
provides the instance handle of the EXE running in the global variable
called Hinstance. For this example it is assumed that the module that
you are trying to load the bitmap from is your application. However,
the module could be another EXE or DLL file. The following example
loads a bitmap called BITMAP_1 from a RES file linked into the
application's EXE:

procedure TForm1.Button1Click(Sender: TObject);
var
Bmp: TBitmap;
begin
Bmp := TBitmap.Create;
Bmp.Handle := LoadBitmap(HInstance,'BITMAP_1');
Canvas.Draw(0, 0, Bmp);
Bmp.Free;
end;

There is one drawback to using the LoadBitmap API call though
LoadBitmap is a Windows 3.0 API call and loads in bitmaps only as
DDBs (Device Dependent Bitmaps). This can cause color palette
problems when retrieving DIBs (Device Independent Bitmaps) from
RES files. The code listed below can be used to retrieve DIBs from
RES files. This code loads the bitmap as a generic resource, puts
it into a stream, and then does a LoadFromStream call which causes
Delphi to realize the color palette automatically.

procedure TForm1.Button1Click(Sender: TObject);
const
BM = $4D42; {Bitmap type identifier}
var
Bmp: TBitmap;
BMF: TBitmapFileHeader;
HResInfo: THandle;
MemHandle: THandle;
Stream: TMemoryStream;
ResPtr: PByte;
ResSize: Longint;
begin
BMF.bfType := BM;
{Find, Load, and Lock the Resource containing BITMAP_1}
HResInfo := FindResource(HInstance, 'BITMAP_1', RT_Bitmap);
MemHandle := LoadResource(HInstance, HResInfo);
ResPtr := LockResource(MemHandle);

{Create a Memory stream, set its size, write out the bitmap
header, and finally write out the Bitmap }
Stream := TMemoryStream.Create;
ResSize := SizeofResource(HInstance, HResInfo);
Stream.SetSize(ResSize + SizeOf(BMF));
Stream.Write(BMF, SizeOf(BMF));
Stream.Write(ResPtr^, ResSize);

{Free the resource and reset the stream to offset 0}
FreeResource(MemHandle);
Stream.Seek(0, 0);

{Create the TBitmap and load the image from the MemoryStream}
Bmp := TBitmap.Create;
Bmp.LoadFromStream(Stream);
Canvas.Draw(0, 0, Bmp);
Bmp.Free;
Stream.Free;
end;


Loading Cursors
-------------
The LoadCursor API call is defined as follows:

function LoadCursor(Instance: THandle;
CursorName: PChar): HCursor;

The first parameter is the Instance variable of the module that
contains the RES file. As above, this example assumes that the
module that you are trying to load the cursor from is your
application. The second parameter is the name of the cursor.

Under the interface section declare:

const
crMyCursor = 5; {Other units can use this constant}

Next, add the following two lines of code to the form's OnCreate
event as follows:

procedure TForm1.FormCreate(Sender: TObject);
begin
Screen.Cursors[crMyCursor] := LoadCursor(HInstance, 'CURSOR_1');
Cursor := crMyCursor;
end;

or you may want to change one of the standard Delphi cursors as
follows (the Cursor constants can be found in the On-line Help
under Cursors Property):


procedure TForm1.FormCreate(Sender: TObject);
begin
{This example changes the SQL Hourglass cursor}
Screen.Cursors[crSQLWait] := LoadCursor(HInstance, 'CURSOR_1');
end;

Note: Normally it is necessary to delete any cursor resources with
the DeleteCursor, however, in Delphi this is not necessary because
Delphi will delete the all cursors in the Cursors array.


=FAQ2=======
Q: When I paste a glyph/BMP with white in it into a button, the white
disappears. The glyph/BMP appears just fine if I paste into into a button
in Paradox. What gives?

A: Delphi selects whatever color is in the lower left corner of your bitmap
as the transparent color for the button as it rests on the button. If the
problem is that you _want_ the white to appear in the BitBtns in Delphi,
then edit the bitmaps so that the lower left corner bit is a color that
appears nowhere else in the bitmap. (That yucky olive color works -- who
uses that? <g>)


=FAQ3=======
Keep in mind that when a property is an object, it has memory associated
with it.When you are changing the value of a bitmap property, somehow the
memory associated with the old value has to be freed, and new memory
allocated. By convention in Delphi, that's what an "Assign" method does. The
code below works.

implementation

{$R *.DFM}

var n: integer; // It'll be zero when the program starts

procedure TForm1.Button1Click(Sender: TObject);
var Image: TBitmap;
begin // Changes the bitmap in BitBtn1
Image:= TBitmap.Create;
if n < ImageList1.Count then
ImageList1.GetBitmap(n, Image);
{end if}

BitBtn1.Glyph.Assign(Image) // NOTE: Assign is used to change an object
property

inc(n,2); // Button Bitmaps hold two images!
if n > ImageList1.Count then
n:= 0;
{end if}
Image.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin // adds a new button bitmap to ImageList1
if OpenDialog1.Execute then
ImageList1.FileLoad(rtBitMap,OpenDialog1.FileName,clBtnFace);
label1.Caption:= 'ImageCount = ' + IntToStr(ImageList1.Count);
end;
============

----- Original Message -----
From: Dietrich Delekat <del...@zedat.fu-berlin.de>
Newsgroups: comp.lang.pascal.delphi.misc
Sent: Saturday, October 30, 1999 3:05 PM
Subject: LoadBitmap won't load bitmap


> I want to load the glyphs for some speed buttons from a resource file.
> So I
> - created a resource file with the Borland ImageEditor (D4), adding
> 18x18 pixel 16-color bitmaps that were automatically named "Bitmap1"
> and so on
> - opened a new application
> - added {$R MyGlyphs.res}
> - directly assigned one of the bitmaps to a Speed Button to make sure
> nothing was wrong with the bitmaps
> - added
> SpeedButton1.Glyph.Handle := LoadBitmap(HInstance, 'Bitmap1')
> to the OnClick event
>
> Nothing happens. What's wrong?
>
> Dietrich Delekat
>
> P.S. Please email me directly besides posting here. Thank you!
>
Dietrich Delekat <del...@zedat.fu-berlin.de> wrote in message
news:381aea40...@news.fu-berlin.de...
> I want to load the glyphs for some speed buttons from a resource file.
> So I
> - created a resource file with the Borland ImageEditor (D4), adding
> 18x18 pixel 16-color bitmaps that were automatically named "Bitmap1"
> and so on
> - opened a new application
> - added {$R MyGlyphs.res}
> - directly assigned one of the bitmaps to a Speed Button to make sure
> nothing was wrong with the bitmaps
> - added
> SpeedButton1.Glyph.Handle := LoadBitmap(HInstance, 'Bitmap1')
> to the OnClick event
>
> Nothing happens. What's wrong?
>
> Dietrich Delekat
>
> P.S. Please email me directly besides posting here. Thank you!
>

Dietrich Delekat

unread,
Oct 30, 1999, 3:00:00 AM10/30/99
to

Ales Hotko

unread,
Oct 30, 1999, 3:00:00 AM10/30/99
to
try to use uppercase names like BITMAP1... in .res file and in
LoadBitmap(hInstance,'BITMAP1');

Ales Hotko

unread,
Oct 30, 1999, 3:00:00 AM10/30/99
to

Jeremy Collins

unread,
Nov 1, 1999, 3:00:00 AM11/1/99
to

Dietrich Delekat <del...@zedat.fu-berlin.de> wrote in message
news:38201e0...@news.fu-berlin.de...
> That DID the trick! Thanks a lot.
> '1' doesn't work, but 'B1' does. Does anybody know, why?
> Stupid thing.

Resources can be numbered or named. If the resource is
numbered, you need
LoadBitmap(hInstance, MAKEINTRESOURCE(1));

--
Jeremy Collins
Kansai Business Systems
http://www.kansai.co.uk/


Dietrich Delekat

unread,
Nov 2, 1999, 3:00:00 AM11/2/99
to
That DID the trick! Thanks a lot.
'1' doesn't work, but 'B1' does. Does anybody know, why?
Stupid thing.

Dietrich Delekat

0 new messages