I've been trying to add a Stock Font Property to japheth's Asm Control.
Everything worked fine with the get & put font methods so I add an entry for PropertyBag.
Now, in VB IDE the get/set work fine, PropertyBag saves & loads fine. But when I try to
run it from the IDE or compiled I get 80010108 error. Debug shows it's dying on the get_Font method.
I'm not sure at all if what i've implemented is correct. Can anyone take a look and give me an idea of
what may be wrong.

Thanks
Posted on 2004-03-20 19:49:25 by Wayne
Hi Wayne,

with the debug messages its easy to see that VB - at least the version I used - used IPersistStreamInit to save and load an object's state. The code for the implementation of this interface in olectrl.inc is pretty simple:



mov ax,[esi].BagEntry.varType
.if (ax == VT_I2)
mov dl,2
.else
mov dl,4
.endif
movzx edx,dl
mov dwSize,edx
mov ecx,[esi].BagEntry.dwOffset
add ecx, __this

following ---->

invoke vf(pStream, IStream, Write), ecx, dwSize, ADDR bCount ;for Save method
invoke vf(pStream, IStream, Read), ecx, dwSize, ADDR bCount ;for Load method


This doesnt work for IDispatch objects, the save method will save the pointer itself - which is pretty useless - and to load and use such a pointer will most likely crash the app.

To handle IDispatchs the code for IPersistStreamInit::Save should be modified to something like:



mov dwSize,edx
mov ecx,[esi].BagEntry.dwOffset
add ecx, __this
;----------------------------------- 21.3.2004: VT_DISPATCH case added
.if (ax == VT_DISPATCH)
mov ecx, [ecx]
invoke vf(ecx, IUnknown, QueryInterface), addr IID_IPersistStream, addr pPersistStream
.if (eax == S_OK)
invoke OleSaveToStream, pPersistStream, pStream
invoke vf(pPersistStream, IUnknown, Release)
.endif
.else
invoke vf(pStream, IStream, Write), ecx, dwSize, ADDR bCount
.endif


and for IPersistStreamInit::Load it is



mov dwSize,edx
mov ecx,[esi].BagEntry.dwOffset
add ecx, __this
;----------------------------------- 21.3.2004: VT_DISPATCH case added
.if (ax == VT_DISPATCH)
invoke OleLoadFromStream, pStream, addr IID_IDispatch, ecx
.else
invoke vf(pStream, IStream, Read), ecx, dwSize, ADDR bCount
.endif


This code will not handle IDispatch objects which are NULL!

I attached my current versions of the include files.
If you get unresolved external _FireEvent, add "DEFINE_FIREEVENTHELPER" somewhere to your code

Japheth
Posted on 2004-03-21 03:41:29 by japheth
Thanks for the help Japheth.
It makes sense to me now.
I was thrown off because the save & load seemed to be working in the design mode so I was looking elsewhere.

Wayne
Posted on 2004-03-21 10:58:44 by Wayne