Links are not active on this page.
 LOADPICTURE( ) Function

This topic was completely updated by the VFPX community.

Creates an object reference for a bitmap, icon, or Windows meta file.

LOADPICTURE([cFileName])

Parameters

cFileName

Specifies the image file on disk for which an object is created.

The following image types are supported:


Supported Image Types
Image Type Groups Filename Extensions

bitmaps

.bmp, .jpg, .jpeg, .jpe, .jfif, .gif, .giff, .gfa

icons

.ico

windows metafiles

.wmf

windows enhanced metafiles

.emf

cursor

.cur


The following restrictions (tested with VFP 9 SP2 and OlePro32.dll Version 6.0.6002.18005) exist:


Known Limitations
Image Type Groups Restrictions & Issues

bitmaps

Loading these .tif and .png formats will cause an OLE error.

icons

Icons are allowed with sizes up to 128x128 and must not have more than 256 colors. Even if there is more than one icon stored in the icon file, always only the smallest icon gets displayed. The icon file may contain much more icons - even with more colors and larger sizes - as long as there is at least one that complies with the rules above, then no exception is thrown.

cursor

Cursor files must not have more than 1K of file size, otherwise an OLE error is generated. Cursor files containing 16 color cursors can be loaded flawlessly, but only monochrome output is supported. Loading an animated cursor (.ani) causes an OLE error to be raised.


Null Picture Support

If cFileName is omitted, the "null picture" is returned.
You can include GETPICT( ) as cFileName to display the Open dialog from which you can choose a bitmap file.

Expand imageReturn Value

Object

LOADPICTURE() function returns a Picture type COM object reference that can be assigned to ActiveX controls and VFP’s Image object’s PictureVal property. However, the real primary interface iPicture only can be retrieved using code like this:

 CopyCode imageCopy Code
oIPicture = GETINTERFACE(LOADPICTURE(GETPICT()), "iPicture")

Expand imageRemarks

Picture objects provide a language-neutral abstraction for bitmaps, icons, and metafiles. As with the standard font object, the system provides a standard implementation of the picture object. Its primary interfaces are iPicture and iPictureDisp. A picture object is created with OleCreatePictureIndirect and supports both the iPicture and the iPictureDisp interfaces. The OLE-provided picture object implements the complete semantics of the iPicture and iPictureDisp interfaces. In other words, there’s no need to use another interface than iPicture!

LOADPICTURE( ) Function internally wraps the OleCreatePictureIndirect() function implemented in OleAut32.dll. Thus, all you can read about that function (above and online) is also true for VFP’s LOADPICTURE() function. LOADPICTURE( ) Function was added to VFP’s vocabulary to make it easier to load images with COM interfaces that many presentation properties of ActiveX controls require for their settings. For example, the ActiveX Outline control has a PictureOpen property that requires a COM object image reference for its setting.

The COM object returned by LOADPICTURE( ) Function hides its primary interface iPicture. In contrast to the reference returnd by LOADPICTURE( ) Function, the OLE-image’s primary iPicture interface is the only fully functional one. In other words, only iPitcure can be used in VFP programms without generating any OLE errors. Because iPicture is a superset of Picture it may be, better, it should be used everywhere instead of the one returnd by LOADPICTURE( ) Function!
Example #1 in the examples section below proves that it makes no difference which OLE image interface gets assigned to a oIMAGE.PICTUREVAL property.

The IID of the iPicture interface is defined as “{7BF80980-BF32-101A-8BBB-00AA00300CAB}”.

The following two lines of code both create a null picture OLE image object:CopyCode imageCopy Code
oIPicture1 = GETINTERFACE(LOADPICTURE(), "iPicture") 
oIPicture2 = CREATEOBJECTEX("StdPicture","","{7BF80980-BF32-101A-8BBB-00AA00300CAB}")


Expand imageInterface Members

The following table summarizes the PEMs iPicture interface.


iPicture Interface Members
PEM Name Used for ValueType Read/Writable

property

Attributes

The current set of the picture's bit attributes.

DWORD (int)

readonly

property

CurDC

The current device context into which this picture is selected.

HDC (long)

readonly

property

Handle

Handle to the picture managed within this picture object.

OLE_Handle (int)

readonly

property

Height

The current height of the picture in the picture object.

OLE_XSIZE_HIMETRIC (long)

readonly

property

hPal

The current palette of the picture (if any).

OLE_Handle (int)

read/writable

property

KeepOriginalFormat

The current value of the picture object's KeepOriginalFormat property.

Bool

read/writable

property

Type

The current type of the picture.

Short (int)

readonly

property

Width

The current width of the picture in the picture object.

OLE_XSIZE_HIMETRIC (long)

readonly

method

PictureChanged()

Notifies the picture object that its picture resource changed.

   

method

Render()

Draws the specified portion of the picture onto the specified device context, positioned at the specified location.

   

method

SaveAsFile()

Saves the picture's data into a stream in the same format that it would save itself into a file.

   

method

SelectPicture()

Selects a bitmap picture into a given device context, returning the device context in which the picture was previously selected as well as the picture's handle.

   

The Attributes property is said to hold the picture’s bit attributes. Actually, there are only two, which can be set alone, or additive. The following table lists both possible values:


iPicture.Attributes Enumeration
Constant Description Value

PICTURE_SCALABLE

The picture object is scalable, such that it can be redrawn with a different size than was used to create the picture originally. Metafile-based pictures are considered scalable; icon and bitmap pictures, while they can be scaled, do not express this attribute because both involve bitmap stretching instead of true scaling.

1

PICTURE_TRANSPARENT

The picture object contains an image that has transparent areas, such that drawing the picture will not necessarily fill in all the spaces in the rectangle it occupies. Metafile and icon pictures have this attribute; bitmap pictures do not.

2


The following table lists all possible values of the iPicture.Type property:


iPicture.Type Property Values
Constant Description Value

PICTYPE_UNINITIALIZED

The picture object is currently uninitialized. This value is never be returned within VFP.

-1

PICTYPE_NONE

A new picture object is to be created without an initialized state. This value is returned from VFP if LoadPicture() is used without a parameter.

0

PICTYPE_BITMAP

The picture type is a bitmap.

1

PICTYPE_METAFILE

The picture type is a metafile.

2

PICTYPE_ICON

The picture type is an icon.

3

PICTYPE_ENHMETAFILE

The picture type is an enhanced metafile.

4


The most interesting method of the COM image object’s iPicture interface is render() which also works flawlessly only when called on the iPicture interface. The following table summarises the parameters of the render() method:


Render() Parameter Galore
Parameter Used for Scale Unit

hdc

A handle of the device context on which to render the image.

x

The horizontal coordinate in hdc at which to place the rendered image (X-position of upper left corner of output rectangle).

pixel

y

The vertical coordinate in hdc at which to place the rendered image (X-position of upper left corner of output rectangle).

pixel

cx

The horizontal dimension (width) of the destination rectangle (with of output rectangle).

pixel

cy

The vertical dimension (height) of the destination rectangle (height of output rectangle).

pixel

xSrc

The horizontal offset in the source picture from which to start copying.

HiMetric

ySrc

The vertical offset in the source picture from which to start copying.

HiMetric

cxSrc

The horizontal extent to copy from the source picture (width of image source’s clipping region AND direction of readout).

HiMetric

cySrc

The vertical extent to copy from the source picture (height of image source’s clipping region AND direction of readout).

HiMetric

lprcWBounds

If hdc is a metafile device context, the lprcWBounds parameter points to a RECTL structure specifying the bounding rectangle in the underlying metafile. The rectangle structure contains the window extent and window origin. These values are useful for drawing metafiles. The rectangle indicated by lprcBounds is nested inside this lprcWBounds rectangle; they are in the same coordinate space. If hdcDraw is not a metafile device context, lprcWBounds will be NULL. If hdcDraw is a metafile device context, lprcWBounds cannot be NULL!

The method returns standard values like E_FAIL, E_INVALIDARG and E_OUTOFMEMORY, as well as S_OK, E_POINTER and CTL_E_INVALIDPROPERTYVALUE. These values are described on MSDN.

Expand imageApplications

The render function has plenty of parameters. Some of them passing in pixel values, others HiMetric values.
Example #3 has some useful conversions as well as other supporting functions and definitions.
To figure out how render() works try the VFP code below; type it in line by line into VFP’s command window:

Direct input into VFP’s command window CopyCode imageCopy Code
* locate an image with round about 100 x 100 pixels
goPic = LOADPICTURE(GETPICT())
gIP = GETINTERFACE(m.goPic, "iPicture")
goForm = CREATEOBJECT("Form")
goForm.Show()
* declare access to the _client_area_ of a window
DECLARE Integer GetDC IN USER32 integer HWnd
* hDC should be <> 0 (otherwise that's an error)!
hDC = GetDC(goForm.HWnd)
* render your image directly onto form's client area
gIP.Render(m.hDC,0,0,100,100,0,gIP.Height,gIP.Width,- gIP.Height,NULL)
* declare release function
DECLARE Integer ReleaseDC IN USER32 integer HWnd, integer hDC
* next line should print 1 on the form's background >> "Okay"
? ReleaseDC(m.goForm.HWnd, m.hDC)
* declare access to the _whole_ window
DECLARE Integer GetWindowDC IN USER32 integer HWnd
* hDC now references form's caption an border areas as well!
hDC = GetWindowDC(goForm.HWnd)
* render out partially overwriting form's border and caption
gIP.Render(m.hDC,0,0,100,100,0,gIP.Height,gIP.Width,- gIP.Height,NULL)
* never forget to free an allocated device context
? ReleaseDC(m.goForm.HWnd, m.hDC)
		

iPicture.Render() qualifies for painting on otherwise unreachable form regions, like the TitleBar or WindowBorders. Another interesting application for direct rendering stems from the fact that no VFP object reference is necessary for painting. The render() method solely uses a common windows handle. Thus, one can render on any known device context.
If one encounters the so-called hourglass problem, working with a COM-based image can be the preferred workaround. The hourglass mouse cursor gets displayed by the operation system during lengthy disk accesses. Sometimes VFP does not reset the hourglass mouse cursor correctly. Thus, the user still sees the “busy working” icon although VFP already is idle, as long she doesn’t touch the mouse. Most often these disk accesses stem from refreshing pictures loaded into native Image-Objects using the Image.Picture property. Storing a COM memory-based object to the Image-Object’s .PictureVal property instead, never causes any disk access. Thus, no more hourglass mouse cursor will appear after a refresh!

Expand imageDrawback

iPicture.Render() does its work outside of - and unnoticed by – the VFP engine itself. That’s why VFP has no idea of what was painted “between the lines”. Each time VFP refreshes the form’s area (we’ve just rendered our picture onto), will clear out our image. To make rendered output persistent measures have to be taken against VFP wiping it out!

There is another BUG one has to be aware of, when employing the hourglass workaround described above!
To see what happens, try the following code:

Direct input into VFP’s command window CopyCode imageCopy Code
LOCAL lnLoop, oComPic1, oComPic2
oComPic1 = LOADPICTURE(GETFILE())
oComPic2 = LOADPICTURE(GETFILE())
TRY
	_Screen.Addobject("oImage","IMAGE")
CATCH
FINALLY
	_Screen.oImage.Visible = .T.
ENDTRY
FOR lnLoop = 1 to 100
	_Screen.oImage.PictureVal = m.oComPic1
	_Screen.oImage.PictureVal = m.oComPic2
NEXT 
*//
*\\ whereas the next loop will break somewhere down the road:
FOR lnLoop = 1 to 100
	_Screen.oImage.PictureVal = m.oComPic1
	_Screen.oImage.PictureVal = m.oComPic1
	_Screen.oImage.PictureVal = m.oComPic1
	_Screen.oImage.PictureVal = m.oComPic2
NEXT	
		

One can see, that the first loop executes flawlessly, the second one breaks after only a few loops with a “Property value is invalid” error message! This bug is hard to track and occurs only in cases when someone tries to assign the same COM-reference more than once in a row! The workaround for this is to keep track which COM-reference is actually assigned to the Image’s PictureVal property. Never ever then reassign the same reference a second time (overwriting the first one with a copy of itself)! BTW: It doesn’t matter what interface you are using. The error seems to stem from VFP’s Image class instance.

Expand imageExamples

The following example shows that both interfaces (Picture and IPicture) of a COM image instance can be assigned to VFP’s Image.PictureVal property:

Example #1CopyCode imageCopy Code
PUBLIC goPic AS Object, goIPic AS Object
goPic = LOADPICTURE(GETPICT())
goIPic = GETINTERFACE(m.goPic, "iPicture")
_SCREEN.AddObject("oPic1","IMAGE")
_SCREEN.AddObject("oPic2","IMAGE")
WITH _SCREEN.oPic1
	.VISIBLE = .T.
	.PICTUREVAL = m.goPic && "Picture"-Interface
ENDWITH
WITH _SCREEN.oPic2
	.LEFT = 110
	.VISIBLE = .T.
	.PICTUREVAL = m.goIPic && "IPicture"-Interface
ENDWITH
HIDE WINDOWS ALL
WAIT WINDOW "Press any key..."
_SCREEN.RemoveObject("oPic1")
_SCREEN.RemoveObject("oPic2")
STORE NULL TO goPic, goIPic
CLEAR
SHOW WINDOWS ALL

The following example shows how to query the iPicture interface of a COM image instance. Intentionally, there are no Try…Catch…Endtry sections in this demo code, so that OLE errors may occur. You have to run the code snippet multiple times with different image types to see them.

Example #2CopyCode imageCopy Code
goPic = LOADPICTURE(GETPICT())
IF VARTYPE(m.goPic) == "O"
	goIPic = GETINTERFACE(m.goPic, "iPicture")
	IF VARTYPE(m.goIPic) == "O"
		CLEAR && just some informal output:
		WITH m.goIPic
			?
			? "Properties of 'IPicture'-Interface:"
			? "Attributes"		,.Attributes
			*\\ next line will fail if an ICOn loaded
			? "CurDC"	,.CurDC
			? "Handle"	,.Handle
			? "Height"	,.Height
			*\\ next line will fail if an ICOn loaded
			? "hPal"	,.hPal
			? "KeepOriginalFormat",.KeepOriginalFormat
			? "Type"	,.Type
			? "Width"	,.Width
			?
		ENDWITH
	ENDIF
ENDIF

The following code is a collection of supporting functions and declarations that come in handy while programming OLE image objects.

Example #3CopyCode imageCopy Code
* Supporting Functions & DEFINEs
#DEFINE INCH2MILLIMETER 25.4 && 1 Inch = 25.4 millimeters
#DEFINE INCH2HIMETRICS (INCH2MILLIMETER * 100) && 1 HIMETRIC = 0.01
FUNCTION PXL2HIME(tnPixel AS Integer) AS Integer
	* Pixel to HiMetric conversion
	LOCAL lnPixelsOnOneHiMetricUnit AS Integer
	lnPixelsOnOneHiMetricUnit = INCH2HIMETRICS / GetDPI()
RETURN ROUND(lnPixelsOnOneHiMetricUnit * m.tnPixel, 0)
ENDFUNC
FUNCTION HIME2PXL(tnHimetric AS Integer) AS Integer
	* HiMetric to Pixel conversion
	LOCAL lnPixelsOnOneHiMetricUnit AS Integer
	lnPixelsOnOneHiMetricUnit = INCH2HIMETRICS / GetDPI()
RETURN ROUND(m.tnHimetric / m.lnPixelsOnOneHiMetricUnit, 0)
ENDFUNC
FUNCTION GetDPI(tnHDC AS Integer) AS Integer
      * retrieve dots per inch resolution 
      * for VFP's _SCREEN device context
	DECLARE Integer GetDeviceCaps IN GDI32 integer hdc, integer nIndex
	DECLARE Integer GetWindowDC IN USER32 integer HWnd
	DECLARE Integer ReleaseDC IN USER32 integer HWnd, integer hDC
	* For simplicity, we assume X- and Y- dimensions 
      * using the same DPI resolution.
	#DEFINE LOGPIXELSX 88 && Logical pixels/inch in X	
      #DEFINE LOGPIXELSY 90 && Logical pixels/inch in Y
	* Get VFP's _Screen-hDC to calculate resolution:
	LOCAL lhDC AS Integer, lnDPI AS Integer
	STORE 0 TO lhDC, lnDPI
	lhDC = GetWindowDC(_Screen.HWnd)
	IF NOT m.lhDC = 0
		lnDPI = GetDeviceCaps(m.lhDC, LOGPIXELSX)
	ELSE
		lnDPI = 96 && default to 96 DPI
	ENDIF
	* Free device context
	= ReleaseDC(_Screen.HWnd, m.lhDC)
RETURN m.lnDPI
ENDFUNC
FUNCTION GetCanvas(tnHWND AS Integer, tlChild AS Boolean) AS Integer
	* Retrieve hDC (handle DeviceContext) of window handle
	* tlChild = TRUE  := Use GetDC()
	* tlChild = FALSE := Use GetWindowDC()
	DECLARE Integer GetDC IN USER32 integer HWnd
	DECLARE Integer GetWindowDC IN USER32 integer HWnd
	LOCAL lnHDC AS Integer
	IF m.tlChild
		lnHDC = GetDC(m.tnHWND)
	ELSE
		lnHDC = GetWindowDC(m.tnHWND)
	ENDIF
RETURN m.lnHDC
ENDFUNC
FUNCTION ReleaseCanvas(tnHWND AS Integer, tnHDC AS Integer) AS Integer
	* Releases a borrowed hDC
	DECLARE Integer ReleaseDC IN USER32 integer HWnd, integer hDC
RETURN ReleaseDC(m.tnHWND, m.tnHDC)
ENDFUNC
* The following function is not bullert-proof, as it fails on forms with scrollbars (oForm.Scrollbars > 0)
FUNCTION GetChildAreaCanvas(tnhWnd AS Integer) AS Integer
	* VFP ‘TopLevelForms’ (oForm.ShowWindow = 2) have
	* a secondary window inside the outer one.
	* This is also true for forms showing scrollbars!
	LOCAL lnVfpHANDLE AS Integer, lnClienthWnd AS Integer, lnHDC AS Integer
	* Convert the given Windows hWnd to an internal VFP WHANDLE
	lnVfpHANDLE = SYS(2326, m.tnhWnd)
	* Retrieve the Windows hWnd for a client window 
	* (WCLIENTWINDOW) of a specified Visual FoxPro parent window
	lnClienthWnd = SYS(2325, m.lnVfpHANDLE)
	* Check if there is a WCLIENTWINDOW
	IF lnClienthWnd = lnVfpHANDLE
		* No such WCLIENTWINDOW, return child’s client area
		lnHDC = GetCanvas(m.tnhWnd, .T.)	
	ELSE
		* There IS a WCLIENTWINDOW!
		* Get the device context handle for the 
		* whole client area of that window:
		lnHDC = GetCanvas(lnClienthWnd)
	ENDIF
RETURN m.lnHDC
ENDFUNC

Expand imageSee Also