Displaying a JPEG or GIF in a picture box
by Richard Russell, November 2006
The main BBC BASIC for Windows documentation explains how to display a BMP image in a picture box (i.e. a static control having the SS_BITMAP style). The code it lists is as follows:
LR_LOADFROMFILE = 16 STM_SETIMAGE = &172 SYS "LoadImage", 0, bmpfile$, 0, cx%, cy%, LR_LOADFROMFILE TO hbitmap% SYS "SendDlgItemMessage", !dlg%, id%, STM_SETIMAGE, 0, hbitmap%
for a static control in a dialogue box, or:
LR_LOADFROMFILE = 16 STM_SETIMAGE = &172 SYS "LoadImage", 0, bmpfile$, 0, cx%, cy%, LR_LOADFROMFILE TO hbitmap% SYS "SendMessage", hbox%, STM_SETIMAGE, 0, hbitmap%
for a static box on the main window.
This technique does not work for JPEG or GIF images, because LoadImage can't load files of those types. The solution is to use the following function (or the one described here, which gives more control of the image size) instead of LoadImage:
DEF FNloadimage(file$, cx%, cy%) LOCAL iid{}, hbm%, hcopy%, pic%, ole%, olpp%, text% DIM iid{a%,b%,c%,d%}, text% LOCAL 513 iid.a% = &7BF80980 : REM. 128-bit iid iid.b% = &101ABF32 iid.c% = &AA00BB8B iid.d% = &AB0C3000 SYS "MultiByteToWideChar", 0, 0, file$, -1, text%, 256 SYS "LoadLibrary", "OLEAUT32.DLL" TO ole% SYS "GetProcAddress", ole%, "OleLoadPicturePath" TO olpp% IF olpp%=0 THEN = 0 SYS olpp%, text%, 0, 0, 0, iid{}, ^pic% : REM. OleLoadPicturePath IF pic%=0 THEN = 0 SYS !(!pic%+12), pic%, ^hbm% : REM. IPicture::get_Handle IF hbm%=0 THEN = 0 SYS "CopyImage", hbm%, 0, cx%, cy%, 0 TO hcopy% SYS "DeleteObject", hbm% SYS !(!pic%+8), pic% : REM. IPicture::Release = hcopy%
Using this function you can display a JPEG, GIF, BMP, ICO, EMF or WMF image in a picture box as follows:
STM_SETIMAGE = &172 hbitmap% = FNloadimage(imgfile$, cx%, cy%) SYS "SendDlgItemMessage", !dlg%, id%, STM_SETIMAGE, 0, hbitmap%
for a static control in a dialogue box, or:
STM_SETIMAGE = &172 hbitmap% = FNloadimage(imgfile$, cx%, cy%) SYS "SendMessage", hbox%, STM_SETIMAGE, 0, hbitmap%
for a static box on the main window.
Note that the filename imgfile$ must include the drive letter, to distinguish it from an internet URL. As always, you must send a message to a dialogue box only after the PROC_showdialog, because until then the dialogue box does not exist.
When you have finished with it (e.g. on closing the static control or exiting your program) delete the bitmap handle as follows:
SYS "DeleteObject", hbitmap%
When displaying an image in a dialogue box be aware of the issues discussed here: Supporting different DPI values.