On Wed, 08 Apr 2009, Mindaugas Kavaliauskas wrote:
Hi,
>> 1. Empty date in hbwin TOLEAUTO is send as VT_NULL. Should we replicate it?
> Well, it would be nice to hear OLE users opinion. Does OLE has EMPTY DATE,
> etc.?
Probably any date earlier then 1899-12-30 will create problems for
applications which does not try to convert the value to julian.
Anyhow, it's possible that negative values will work with some
OLE systems which makes such conversion. In such case using VT_NULL
will cause that date type will be lost.
I do not know why it was introduced. Probably it was necessary for
some programs.
Maybe we should follow the rules in other dbase compatible languages.
Does xbase++ supports OLE? If yes what it does with dates earlier then
1899-12-30 and empty date?
>> 2. HB_IT_POINTER support. Should we add it?
> If we put some objects, etc, into untyped pointer it is not very good idea,
> but may be it could be useful in some case. Does anyone uses such features?
Yes, passing pointers to Harbour structures is bad idea. Such functionality
can be usable probably only to exchange pointers to some system structures/
resources or returned by other OLE calls.
I have no idea if it's usable.
>> 3. Array support. Should we add it?
> It would be a feature. Does anybody have some sample code using OLE arrays?
We can implement it though here I see two potential problems to resolve.
1. In MSDN I've found that cyclic references are forbidden so we should
block such arrays conversion. Anyhow this protection can be added
later. It may be necessary to avoid infinite conversion loop/recursive
calls.
Probably we should add RT error for all unsupported types.
IMHO is better then passing NIL/VT_NULL.
2. I've found also information that all items in array should have the same
type declared in array header. Old OLE code does not respect it.
How it looks in the real world? Should we ignore it?
>> 4. OLECREATEOBJECT() and OLEGETACTIVEOBJECT() return simple pointer item.
>> Maybe we should change it to GC pointer item. In such case we can
>> eliminate destructor from HB_OLEAUTO class. OLERELEASE() will also
>> not be longer necessary though we can leave it to force releasing
>> OLE objects even if some other references still exists.
> I'll add it.
Fine.
>> 5. The hbwin TOLEAUTO class supports iteration by FOR EACH loop.
>> Should we add it too?
> I've looked to hbwin OLE code. Each object uses ::pOleEnumerator to store
> enumerator. It is not very good solution, since we can have a few FOR EACH
> loops inside each other for the same object. I'll try to find a better way
> of implementation. Do we have any FOR EACH sample code for OLE?
This can be quite easy resolved.
Two possible solutions:
1-st: we add to HB_OLEAUTO class:
METHOD __enumStart( enum, lDescend ) CLASS HB_OLEAUTO
LOCAL hObjEnum
hObjEnum := __OLECREATEENUM( ::__hObj, lDescend )
IF !EMPTY( hObjEnum )
IF !EMPTY( ::__hObjEnum )
/* small hack - clone the object array for nested FOR EACH calls */
self := __objClone( self )
ENDIF
::__hObjEnum := hObjEnum
/* set base value for enumerator */
(@enum):__enumBase( self )
RETURN .T.
ENDIF
RETURN .F.
METHOD __enumSkip( enum, lDescend ) CLASS HB_OLEAUTO
LOCAL lContinue, xValue
IF lDescend
xValue := __OLEENUMPREV( ::__hObjEnum, @lContinue )
ELSE
xValue := __OLEENUMNEXT( ::__hObjEnum, @lContinue )
ENDIF
/* set enumerator value */
(@enum):__enumValue( xValue )
RETURN lContinue
METHOD PROCEDURE __enumStop() CLASS HB_OLEAUTO
::__hObjEnum := NIL /* activate autodestructor */
RETURN
2-nd: create new object used for enumeration and set it as __enumBase()
value in __enumStart() method. For this object we can use
HB_OLEENUM class.
In HB_OLEAUTO class we will have to define only __enumStart() method
METHOD __enumStart( enum, lDescend ) CLASS HB_OLEAUTO
LOCAL pOleEnum
pOleEnum := __OLECREATEENUM( ::__hObj, lDescend )
IF !EMPTY( pOleEnum )
/* set base value for enumerator */
(@enum):__enumBase( HB_OLEENUM():new( pOleEnum ) )
RETURN .T.
ENDIF
RETURN .F.
and inside HB_OLEENUM class we will have to define at least
__enumSkip() method:
METHOD __enumSkip( enum, lDescend ) CLASS HB_OLEENUM
LOCAL lContinue, xValue
IF lDescend
xValue := __OLEENUMPREV( ::pOleEnum, @lContinue )
ELSE
xValue := __OLEENUMNEXT( ::pOleEnum, @lContinue )
ENDIF
/* set enumerator value */
(@enum):__enumValue( xValue )
RETURN lContinue
If it will be usable then we can also define __enumStop() method
in this class.
In the second version we are loosing HB_OLEAUTO() object in __enumBase()
value so code like:
enum:__enumBase():oleMethod(...)
will not work though also this can be implemented if we will keep pointer
to original HB_OLEAUTO object and redirect all messages to it. Anyhow
the 1-st version seems to be much easier to implement.
>> 6. Should we add passing parameters by reference?
> Any sample code?
I guess you are asking about real life usage.
Sorry I cannot help here.
best regards,
Przemek
_______________________________________________
Harbour mailing list
[email protected]
http://lists.harbour-project.org/mailman/listinfo/harbour