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

Reply via email to