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 [|Displaying GIF and JPEG images]:

code format="bb4w" SYS !(!gpp%+24), gpp%, ^hmw% : REM. IPicture::get_Width SYS !(!gpp%+28), gpp%, ^hmh% : REM. IPicture::get_Height code 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:

code format="bb4w" SYS IPicture.get_Width%, gpp%, ^hmw% SYS IPicture.get_Height%, gpp%, ^hmh% code 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:

code format="bb4w" 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%} code To complete the process we must point the structure at the object's dispatch table:

code format="bb4w" !(^IPicture{}+4) = !gpp% code 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:

code format="bb4w" 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" !(^IPicture{}+4) = !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 code