Monday, September 10, 2007

Using VFP Resource File

There are several ways to use the resource file. To load a bitmap from RT_BITMAP resource section, you can use GDI or GDI+ to load directly into a (handle) bitmap
[CODE]
*** Updated: Nov 23, 2007 - 07:45 AM


*** API Declaration
Declare Long LoadLibrary in Kernel32 String cFilename
Declare Long FreeLibrary in Kernel32 Long hModule

Declare Long LoadImage in User32 ;
Long hInstance, String lpszName, Long uType, ;
Integer cxDesired, Integer cyDesired, Long nLoadFlags

Declare Long GdipCreateBitmapFromResource in GdiPlus.dll ;
Long hInstance, String cBitmapName, Long @O_Bitmap

hBitmap = 0
hLibrary = LoadLibrary( 'myResource.LIB' )
If (hLibrary != 0)
** Use GDI
cResName = 'myImage' && Resource name
hBitmap = LoadImage( hLibrary, cResName, 0, 0, 0, 0 )

** Use GDI+
wResName = strconv( strconv( cResName + chr(0), 1 ), 5 )
GdipCreateBitmapFromResource( hLibrary, wResName, @hBitmap )

FreeLibrary( hLibrary )
endif

If (hBitmap != 0)
** We have a bitmap, do what you want to do here
** Don't forget to delete the bitmap,
** DeleteObject() for GDI, GdipDisposeImage() for GDI+
endif
[/CODE]

I also shown you about putting an image (PNG) to custom resource section. Since the image was put as a raw data, you can only load it back as raw data. After you get the raw data, you can save it to a file, or you can also create a stream data to create the bitmap from the stream. GdipCreateBitmapFromResource() doesn't work for this resource type.
[CODE]
*** API Declaration
Declare Long FindResource in Kernel32 as FindResourceStr ;
Long hModule, String lpName, String lpType

Declare Long SizeofResource in Kernel32 Long hModule, Long hResource
Declare Long LoadResource in Kernel32 Long hModule, Long hResource
Declare Long LockResource in Kernel32 Long hResData

cData = ''
hLibrary = LoadLibrary( 'myResource.LIB' )
If (hLibrary != 0)
cResName = 'myPNG'
hResource = FindResourceStr( hLibrary, cResName, 'MYIMAGES' )
If (hResource != 0)
nSize = SizeofResource( hLibrary, hResource )
hData = LoadResource( hLibrary, hResource )
pData = LockResource( hData )
cData = sys( 2600, pData, nSize )
endif
FreeLibrary( hLibrary )

endif

If !empty( cData )
** We got the raw data, do what you want to do here
endif
[/CODE]

In my last tips, I didn't show you all the predefined resources. there are several others actually, such as RT_ICON, RT_CURSOR, etc. It is my intention to not using resource file for other images type. Because those images are usually use only with VFP Image object. So, you can still use your project to put other images. Just consider to use the resource file when you have to distribute files physically that you can't put in your project.

Happy coding!


4 comments:

Anonymous said...

Hi Herman

The first part of creating the library works and I can see the Bitmap in the BITMAP section of the file using a resource editor.

The second part, this article, when I try to extract the bitmap from the resource, both GDI and GDI+ return 0 in hBitmap.

What could be the problem?

Herman Tan said...

Hi Bernard,

My apologies for posting the wrong code. There are several incorrect code in both parts.

The first part: both Resource Section Group Name & Resource Name must be in uppercase

The second part: no need to put extension in the Resource Name.

I had corrected the code for both parts. Please take a look and try again.

Thanks

Anonymous said...

Still does not work. My image is being loaded into the ,LIB I can see it as a bitmap resource in my resource viewer. It is the extraction code as below that always returns hBitmao as 0:
cLib = FULLPATH to my .LIB file
If Not Empty(cLib)
Declare Long LoadLibrary In Kernel32 String cFilename
Declare Long FreeLibrary In Kernel32 Long hModule
Declare Long LoadImage In User32 ;
Long hInstance, String lpszName, Long uType, ;
Integer cxDesired, Integer cyDesired, Long nLoadFlags
Declare Long GdipCreateBitmapFromResource In GDIPlus.Dll ;
Long hInstance, String cBitmapName, Long @O_Bitmap

DECLARE INTEGER DeleteObject IN gdi32;
INTEGER hObject
DECLARE INTEGER GdipDisposeImage IN gdiplus;
INTEGER img
hBitmap = 0
hLibrary = LoadLibrary( cLib )
If (hLibrary != 0)
cResName = 'myImage'
** Use GDI - hBitmap returns 0????
hBitmap = LoadImage( hLibrary, cResName, 0, 0, 0, 0 )

** Use GDI+
wResName = Strconv( Strconv( cResName + Chr(0), 1 ), 5 )
GdipCreateBitmapFromResource( hLibrary, wResName, @hBitmap )
FreeLibrary( hLibrary )
Endif

Something else is wrong here.

Herman Tan said...

It works fine in my PC. Maybe the LIB file already corrupted, because the last code contained incorrect code. Try to re-build the LIB file first then reinsert the images again.