April 26, 2024, 09:19:26 PM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


Undocumented feature: disphelper integration

Started by sapero, March 15, 2011, 02:13:33 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

sapero

March 15, 2011, 02:13:33 AM Last Edit: March 15, 2011, 01:34:03 PM by sapero
The disphelper library is now integrated to the 2.0 compiler. The integration is in beta stage, and is not documented in the help files.

Creating an object
IDispatch object = CreateComObject(string_prog_id, optional string_machine)
IDispatch object = GetComObject(optional string_progid, optional string_name)


Releasing an object
Warning: be sure that the object is not NULL
object->Release()

Calling a method
typedef HRESULT int
HRESULT hr = object.method(optional parameters)
HRESULT hr = object.subobject.method(optional parameters)
HRESULT hr = object.subobject1.subobject2{.subobject3 }.method(optional parameters)

The HRESULT type is a generic type used in COM. A value of zero means success, positive value (status) means success too,
but the result may be truncated (example: you requested 100 items, but the method returned only 3 - hresult will be S_FALSE).
Negative values are returned for errors - E_FAIL, E_OUTOFMEMORY, E_INVALIDARG ... (see winerror.inc for a common list)

Property-Set
object{.subobject}.property = value

Property-Get
Note: auto-define is not supported here. The 'value' variable must be defined previously, because its type is required to format a string for disphelper.
def value as ...
value = object{.subobject}.property
value = object{.subobject}.property(optional parameters)


Not handled yet:
object{.subobject}.method(optional parameters).property
object{.subobject}.method(optional parameters).method(optional parameters)

You'll need to split it into two or more objects:
IDispatch child = object{.subobject}.method(optional parameters)
value = child.property
child->Release()


Enumerations:
   Use ComEnumBegin and ComEnumNext, or ComEnumBegin and FOR-EACH
   Note: ComEnumBegin returns an IEnumVARIANT interface, but for our needs, we will use IDispatch type instead.
IDispatch collection = object.property ' or object.method()
if (collection)
' here enumerator should be defined as IEnumVARIANT, but until we call AddRef,Release,QueryInterface it can be any other type.
IDispatch enumerator = ComEnumBegin(collection, NULL)
if (enumerator)
IDispatch item
for item = each enumerator
' todo: query/set properties, call methods
' note: the life-time of <item> is controlled automatically. Release() will be called at NEXT.
next
enumerator->Release()
endif
collection->Release()
endif



Value/parameter types:
1. booleans
   constants TRUE,FALSE, type BOOL - will use the %b token in disphelper format string
typedef BOOL int
BOOL value = object.Visible
object.Visible = TRUE ' do not use normal numbers for boolean properties
object.Visible = FALSE
BOOL v = TRUE
object.Visible = v
v = object.Visible
' int t = object.Visible may fail if the property Visible returns an BOOL


2. unsigned numbers (UINT) - will use the %u token
object.property = 5u
UINT x = 5
object.property = x
x = object.property

The same apply to methods.

3. signed numbers (INT) - will use the %d token
object.property = 5
INT x = 5
object.property = x
x = object.property

The same apply to methods.

4. strings
object.property = "hello"   - will use the %s token
object.property = L"hello"  - will use the %S token

string s = "hello"
object.property = s

wstring w = L"hello"
object.property = w

typedef LPSTR POINTER
LPSTR ps = "hello"
object.property = ps ' %s token

typedef LPWSTR POINTER
LPWSTR pw = L"hello"
object.property = pw ' %S token

typedef BSTR POINTER
BSTR v = object.property ' use always BSTR to query a string. BSTR will use the %B token
if (v)
print *<WSTRING>v
FreeComString(v)
endif

The same apply to methods.

5. doubles - uses the %e token
object.property = 5.0
DOUBLE x = 5.0
object.property = x
x = object.property

The same apply to methods.

6. special structures
time_t t
object.property = t    uses the %t token
t = object.property

DATE d
object.property = d    uses the %D token
d = object.property

VARIANT v
object.property = v    uses the %v token
v = object.property


7. special pointers
SYSTEMTIME st
FILETIME   ft
POINTER   pst = &st
POINTER   pft = &ft

settype pst,SYSTEMTIME
object.property = pst

settype pft,FILETIME
object.property = pft
TODO: object.property=&st
TODO: object.property=&ft
TODO: st=object.property
TODO: ft=object.property


8. general pointers - use POINTER variables. Uses %p token.
   
QuoteUse for HANDLEs, HWNDs

9. objects
   use the IDispatch build-in type (%o token) or IUnknown interface (%O token - first three methods from IDispatch)

10. Optional (or skipped) parameters
   A special VOID keyword can be used to pass an "empty" argument. For example if an object has CallMe method with two
   parameters, the first parameter is optional and you don't want to specify it, use:
object.CallMe(VOID, second_argument)
   If you don't want to pass the second argument, pass VOID, or do not pass anything at all:
object.CallMe(first_argument, VOID)
object.CallMe(first_argument)


11. For a list of tokens %d %s ... see CallObjectMethod documentation in the help file.

New/modified library functions:
$command CreateComObject(name as STRING,opt machine as pointer),COMREF
$command GetComObject(pointer string_progid, pointer string_name),COMREF




I have three console examples so far - wmi, ajax, MS-Word:

1. WMI - enumerate disk drives
typedef HRESULT int
interface IEnumVARIANT
STDMETHOD QueryInterface(riid as POINTER, ppvObj as POINTER),HRESULT
STDMETHOD AddRef(),UINT
STDMETHOD Release(),UINT
stdmethod _Next(UINT celt,pointer rgVar,pointer pCeltFetched),HRESULT
stdmethod Skip(UINT celt),HRESULT
stdmethod Reset(),HRESULT
stdmethod Clone(pointer ppEnum),HRESULT
endinterface

typedef BSTR POINTER
IDispatch wmiSvc, colQuickFixes, item
IEnumVARIANT pEnum
BSTR devID
BSTR DiskSize

wmiSvc = GetComObject(0, "winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\cimv2")

if (!wmiSvc)
print "CreateComObject (wmiSvc) failed"
else
print "CreateComObject (wmiSvc) ok"

' property-get
colQuickFixes = wmiSvc.ExecQuery("SELECT * FROM Win32_DiskPartition")

if (!colQuickFixes)
print "ExecQuery failed"
else
print "ExecQuery ok"

pEnum = ComEnumBegin(colQuickFixes, NULL)
if (pEnum)
print "enum ok "

for item = each pEnum

devID    = item.DeviceID
DiskSize = item.size
print *<WSTRING>devID," ", *<WSTRING>DiskSize, " bytes"

FreeComString(devID)
FreeComString(DiskSize)

next
pEnum->Release()
else
print "enum failed"

endif
endif
wmiSvc->Release()
endif


2. Ajax - download and print RSS channel
IDispatch Connection
typedef BSTR POINTER
BSTR szResponse
INT status


Connection = CreateComObject("Msxml2.XMLHTTP.6.0", NULL)

if (!Connection)
print "CreateComObject (ajax) failed"
else

print "downloading RSS ..."

if (check("Open", Connection.Open("GET", "http://www.ionicwind.com/forums/index.php?type=rss;action=.xml&limit=5", FALSE)))

if (check("Send", Connection.Send()))
status = Connection.status

if (status != 200) ' HTTP_STATUS_OK
print "invalid status: ", status
else
szResponse = Connection.ResponseXML.xml
PRINT *<wstring>szResponse
FreeComString(szResponse)

endif
endif
endif
Connection->Release()
endif


sub check(string txt, int hr),int
if (hr < 0)
print txt," failed with error 0x", HEX$(uint(hr))
endif
return hr>=0
endsub


3. Open a file in MS-Word (uses hardcoded file name "EULA.Microsoft.Application.Verifier.rtf")
IDispatch wordapp, doc

wordapp = CreateComObject("Word.Application")
if (!wordapp)
print "CreateComObject (Word) failed"
else
wordapp.Visible = TRUE

doc = wordapp.Documents.Open("EULA.Microsoft.Application.Verifier.rtf")

if (!doc)
print "failed to open the file"
wordapp.Quit()
else
doc->Release()
endif
wordapp->Release()
endif


See also precompiled headers

billhsln

Sapero, could you come up with an example that reads and writes to cells in an Excel spread sheet?

Thanks,
Bill
When all else fails, get a bigger hammer.

LarryMc

Quote from: billhsln on July 09, 2012, 08:03:48 PM
Sapero, could you come up with an example that reads and writes to cells in an Excel spread sheet?

Thanks,
Bill
Sapero disappeared almost a year ago.  One day he was there and we were in the middle of working on something and the next day he was gone and hasn't been back.  All his off-site storage locations have expired, etc.
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

pistol350

Regards,

Peter B.

billhsln

I tried using that method, it worked some times and some times came up with the wrong results.

Thanks,
Bill
When all else fails, get a bigger hammer.

fasecero

QuoteSapero disappeared almost a year ago.

I got really sad when I read that. He was fantastic and helped me a lot.

LarryMc

Quote from: fasecero on July 11, 2012, 04:32:37 PM
I got really sad when I read that. He was fantastic and helped me a lot.
You.  Ya'll have no idea how much he helped me off-forum on various things.
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

billhsln

If I am reading things correctly, he lived in Poland.  There is no indication of his real name, so it might be hard to find news articles with his name in it, to maybe see if we could figure out what happened.  The bio says he was 37, so hopefully it was not something serious.
Bill
When all else fails, get a bigger hammer.

LarryMc

Quote from: billhsln on July 11, 2012, 07:57:07 PM
If I am reading things correctly, he lived in Poland.  There is no indication of his real name, so it might be hard to find news articles with his name in it, to maybe see if we could figure out what happened.  The bio says he was 37, so hopefully it was not something serious.
Bill
We had his real name and the city he lived in.  I sent emails to 2 polish newspapers asking about him but they never responded.
About 2 weeks after he disappeared someone signed on to the forums with his account (like someone checking stuff out on his computer). His IP hasn't been on since.
He also hasn't signed on to his yahoo messenger account since he disappeared (we had been communicating daily, multiple times, up through that last day.

After all this time you have to figure he was in a car wreck or something for it to be that sudden.

LarryS did tell me recently that he found where there was a ID theft computer ring that was busted around that same time.
I guess on the positive side we could think he got arrested and incarcerated as part of that bust and may be back some day.
Although he had enough computer smarts to be able to do that he never displayed any hint of being that sort of person.

I just wish I had a fraction of the computer skills he had.  And apparently he was self taught.  He told me he learned English while reading the Windows SDK.
In the forums his posts were in better English than mine.  Few people knew the pains he went through to get his posts correct.
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library