Next Previous Contents

7.7 The EnumInterface library

The EnumInterface assists in the creation of COM-style iterators, that is, IEnum* interfaces which all support the following set of methods,

interface IEnum<It> : IUnknown {
    HRESULT Next
       ( [in] ULONG num
       , [ out
         , size_is(num)
         , length_is(*numFetched)
         ] <It>** outP
       , [out] ULONG *numFetched 
       );
    HRESULT Skip  ( [in] ULONG num );
    HRESULT Reset ( void );
    HRESULT Clone ( [out] <It>** ppv );
};

They collectively allow you to (repeatedly) iterate over a sequence of elements (of type It here).

However, since IDL doesn't allow you to parameterise over the element type you're iterating over, you end up having to define one IEnum interface per type.

Not much we can do about that, but at least EnumInterface provides you with a generic Haskell implementation of such a family of interfaces:

mkEnumInterface :: [a]
                -> Int
                -> (Ptr a -> a -> IO ())
                -> IO (ComVTable iid objState)

The mkEnumInterface action creates a method table containing the above four IEnum methods. It takes the following arguments:

Here's an example of its use:

enumInts :: IO (IEnumInt ()) 
enumInts = do
  vtbl <- mkEnumInterface [1..] HDirect.sizeofInt (HDirect.writeInt)
  createComInstance "" () [mkIface iidIEnumInt vtbl] iidIEnumInt

type IEnumInt  a = IUnknown (IEnumInt_ a)
dats IEnumInt_ a = IEnumInt__

iidIEnumInt :: IID (IEnumInt ())
iidIEnumInt = mkIID "{...}"


Next Previous Contents