=====Calling object methods using structures=====
//by Richard Russell, March 2007//\\ \\ Calling **COM**, **OLE** or **ActiveX** object //methods// generally involves the use of a rather arcane syntax, such as this example taken from the BB4W manual under [[http://www.bbcbasic.co.uk/bbcwin/manual/bbcwine.html#gifjpeg|Displaying GIF and JPEG images]]:
SYS !(!gpp%+24), gpp%, ^hmw% : REM. IPicture::get_Width
SYS !(!gpp%+28), gpp%, ^hmh% : REM. IPicture::get_Height
Here it is not at all clear what methods are being called, and how, hence the need for comments.\\ \\ It is possible to improve the clarity considerably by using a **structure** to represent the object. You can then call the object's methods as follows:
SYS IPicture.get_Width%, gpp%, ^hmw%
SYS IPicture.get_Height%, gpp%, ^hmh%
To make this work you need to declare a structure containing all the object's methods in the correct order. In the case of the **IPicture** interface the structure needs to be declared as follows:
DIM IPicture{QueryInterface%, AddRef%, Release%, get_Handle%, get_hPal%, \
\ get_Type%, get_Width%, get_Height%, Render%, set_hPal%, get_CurDC%, \
\ SelectPicture%, get_KeepOriginalFormat%, put_KeepOriginalFormat%, \
\ PictureChanged%, SaveAsFile%, get_Attributes%}
To complete the process we must point the structure at the object's dispatch table:
PTR(IPicture{}) = !gpp%
The memory originally allocated when the structure was created is wasted, but this isn't a problem if it is declared as a **LOCAL** structure.\\ \\ As a practical illustration of the use of this technique here is a replacement for the **PROCdisplay** routine listed in the BB4W manual:
DEF PROCdisplay(picture$, xpos%, ypos%, xsize%, ysize%)
LOCAL iid{}, IPicture{}, oleaut32%, olpp%, gpp%, hmw%, hmh%, picture%, res%
DIM iid{a%,b%,c%,d%}, picture% LOCAL 513
DIM IPicture{QueryInterface%, AddRef%, Release%, get_Handle%, get_hPal%, \
\ get_Type%, get_Width%, get_Height%, Render%, set_hPal%, get_CurDC%, \
\ SelectPicture%, get_KeepOriginalFormat%, put_KeepOriginalFormat%, \
\ PictureChanged%, SaveAsFile%, get_Attributes%}
SYS "LoadLibrary", "OLEAUT32.DLL" TO oleaut32%
SYS "GetProcAddress", oleaut32%, "OleLoadPicturePath" TO olpp%
IF olpp%=0 ERROR 100, "Could not get address of OleLoadPicturePath"
SYS "MultiByteToWideChar", 0, 0, picture$, -1, picture%, 256
iid.a% = &7BF80980
iid.b% = &101ABF32
iid.c% = &AA00BB8B
iid.d% = &AB0C3000
SYS olpp%, picture%, 0, 0, 0, iid{}, ^gpp%
IF gpp% = 0 ERROR 100, "OleLoadPicturePath failed"
PTR(IPicture{}) = !gpp%
SYS IPicture.get_Width%, gpp%, ^hmw%
SYS IPicture.get_Height%, gpp%, ^hmh%
SYS IPicture.Render%, gpp%, @memhdc%, xpos%, ypos%, xsize%, ysize%, 0, \
\ hmh%, hmw%, -hmh%, 0 TO res%
IF res% ERROR 100, "IPicture::Render failed"
SYS IPicture.Release%, gpp%
SYS "InvalidateRect", @hwnd%, 0, 0
SYS "UpdateWindow", @hwnd%
ENDPROC