VT_DISPATCH callback object

Pete Flugsatd <[email protected]> Wed, 21 Feb 2007 11:43:02 -0500
Newsgroups gmane.comp.windows.devel.jawin
Message-ID <LISTSERV%[email protected]>
Hello!

  I'm trying to use jawin (2.0-alpha1 - is there a better version to use?)
to interact with a COM object that requires I register a dispatch pointer
callback before doing anything with it.  The dispatch pointer is supposed to
be a specific interface type.

  The IDL for the registration looks like (with much stuff trimmed out):

library foo
{
    // Forward declare all types defined in this typelib
    dispinterface ILayer;
    interface ICallback;

    ...

    [
      uuid(1E4408DD-7CFF-11D3-80A9-00C04F60B086)
    ]
    dispinterface ILayer {
        properties:
        methods:
    ...
            [id(0x00000039)]
            long RegisterWithMapServer(
                            BSTR client_name,
                            long window_handle,
                            VARIANT dispatch_pointer);
    ...
    }; // ILayer

    [
      uuid(1E4408DF-7CFF-11D3-80A9-00C04F60B086)
    ]
    coclass Layer {
        [default] dispinterface ILayer;
    };

    ...

    interface ICallback : IDispatch {
        [id(0x60020000)]
        HRESULT GetHelpText(
                        [in] long layer_handle,
                        [in] long object_handle,
                        [in, out] BSTR* help_text);
        [id(0x60020001)]
        HRESULT GetInfoText(
                        [in] long layer_handle,
                        [in] long object_handle,
                        [in, out] BSTR* title_bar_txt,
                        [in, out] BSTR* dialog_txt,
                        [out, retval] long* result);
         ...
    }; // ICallback

  The idea is that I create an object that implements the ICallback
interface, and register this with the Layer object via the
registerWithMapServer.  Then, when the Layer object needs to call back for
something (such as to get Help Text for an object I've created on screen),
it uses this callback.

  In any case, I used the Jawin Type Browser to generate the code for this.
It generates the ILayer and Layer objects:

    ILayer layer = new ILayer( Layer.CLSID );

  This all appears to work.

  The Type Browser also created an instance of the ICallback object - I
create one of these with:

     ICallback callback = new ICallback();

  But I don't think this is correct, as this seems to be invoking the
functions on an ICallback COM object, instead of implementing that
interface.  What is the correct way to implement this object?

  In any case, then I try and create the variant to register, and then
actually register it:

           Variant variant = new Variant();
           variant.vt = VarTypes.VT_DISPATCH;
           variant.pdispVal = callback;
           layer.RegisterWithMapServer( "FVW Test Client", 0, variant );

  This fails with the error:

    8000ffff: A VT_VARIANT must be combined with VT_BYREF (base vartype 12)

  Note that this is not an OUT parameter at all - in any case. I change to:

           variant.vt = VarTypes.VT_DISPATCH | VarTypes.VT_BYREF;

  And now it fails:

     8000ffff: Unable to serialize variant: org.jawin.Variant@5d173

  I'm guessing I need to do something with byeref stuff?  What's the right
way to do this?

  I'll keep working on this, as I expect the answer is around, I'm just
hoping to get a short circuit.

Thanks,
Pete