June 16, 2024, 09:07:29 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


COM Events

Started by JR, April 24, 2006, 06:54:06 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

JR

I want to add an option to my TypeLib Browser for Aurora to generate classes for events sink. I already have made a test with hand made classes and got the events working. However, there is an small problem: The guid of the events interface is needed in three places. Is there a way to make it global?

JR

Here is how the class for ShockWave Flash will look:


class IShockwaveFlashEvents_IUnknownImpl : IUnknown
{
    declare virtual QueryInterface(GUID *riid, void *ppvObject), int;
    declare virtual AddRef(), unsigned int;
    declare virtual Release(), unsigned int;
    int m_refs;
}

IShockwaveFlashEvents_IUnknownImpl :: QueryInterface(GUID *riid, void *ppvObject), int
{
    GUID _IID__IShockwaveFlashEvents;
    DEFINE_GUID(_IID__IShockwaveFlashEvents, 0xD27CDB6D, 0xAE6D, 0x11CF, 0x96,0xB8,0x44,0x45,0x53,0x54,0x00,0x00);
    if IsEqualGUID(riid, _IID_IUnknown) or IsEqualGUID(riid, _IID_IDispatch) or IsEqualGUID(riid, _IID__IShockwaveFlashEvents)
    {
        *(pointer)ppvObject = this;
        AddRef();
        return S_OK;
    }
    *(pointer)ppvObject = null;
    return E_NOINTERFACE;
}

IShockwaveFlashEvents_IUnknownImpl :: AddRef(), unsigned int
{
    m_refs++;
    return m_refs;
}

IShockwaveFlashEvents_IUnknownImpl :: Release(), unsigned int
{
    m_refs--;
    if (!m_refs)
    {
        delete this;
        return 0;
    }
    return m_refs;
}

class IShockwaveFlashEvents_IDispatchImpl : IShockwaveFlashEvents_IUnknownImpl
{
    declare virtual GetTypeInfoCount(unsigned int *pctinfo), int;
    declare virtual GetTypeInfo(unsigned int iTInfo, int lcid, pointer *ppTInfo), int;
    declare virtual GetIDsOfNames(GUID *riid, unsigned word *rgszNames, unsigned int cNames, int lcid, int *rgDispID), int;
    declare virtual Invoke(int dispIdMember, GUID *riid, int lcid, unsigned word wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, unsigned int *puArgErr), int;
    declare virtual OnReadyStateChange(DISPPARAMS *pdispparams);
    declare virtual OnProgress(DISPPARAMS *pdispparams);
    declare virtual FSCommand(DISPPARAMS *pdispparams);
}

IShockwaveFlashEvents_IDispatchImpl :: GetTypeInfoCount(unsigned int *pctinfo), int
{
    *pctinfo = null;
    return S_OK;
}

IShockwaveFlashEvents_IDispatchImpl :: GetTypeInfo(unsigned int iTInfo, int lcid, pointer *ppTInfo), int
{
    return E_NOTIMPL;
}

IShockwaveFlashEvents_IDispatchImpl :: GetIDsOfNames(GUID *riid, unsigned word *rgszNames, unsigned int cNames, int lcid, int *rgDispID), int
{
    return E_NOTIMPL;
}

IShockwaveFlashEvents_IDispatchImpl :: OnReadyStateChange(DISPPARAMS *pdispparams)
{
    int newState;
    VARIANT *vArg;

    // Unpack the arguments
    vArg = *pdispparams.*(VARIANT)rgvarg[0];
    newState = vArg->lVal;

    return 0;
}

IShockwaveFlashEvents_IDispatchImpl :: OnProgress(DISPPARAMS *pdispparams)
{
    int percentDone;
    VARIANT *vArg;

    // Unpack the arguments
    vArg = *pdispparams.*(VARIANT)rgvarg[0];
    percentDone = vArg->lVal;

    return 0;
}

IShockwaveFlashEvents_IDispatchImpl :: FSCommand(DISPPARAMS *pdispparams)
{
    pointer pbstrcommand;
    pointer args;
    VARIANT *vArg;

    // Unpack the arguments
    vArg = *pdispparams.*(VARIANT)rgvarg[1];
    pbstrcommand = vArg->bstrVal;
    vArg = *pdispparams.*(VARIANT)rgvarg[0];
    args = vArg->bstrVal;

    return 0;
}

IShockwaveFlashEvents_IDispatchImpl :: Invoke(int dispIdMember, GUID *riid, int lcid, unsigned word wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, unsigned int *puArgErr), int
{
    select (dispIdMember)
    {
      case 0xFFFFFD9F:  // OnReadyStateChange
          OnReadyStateChange(pdispparams);
      case 0x000007A6:  // OnProgress
          OnProgress(pdispparams);
      case 0x00000096:  // FSCommand
          FSCommand(pdispparams);
      default:
          return DISP_E_MEMBERNOTFOUND;
    }
    return S_OK;
}


Niote: The attached file contains the full testing code.

Ionic Wind Support Team

Move the GUID variable outside of the subroutine.  If you need it global to other files use the 'global' keyword.

Ionic Wind Support Team

JR

April 24, 2006, 10:11:44 AM #3 Last Edit: April 24, 2006, 10:18:51 AM by José Roca
If I declare it as global, the call to AtlAdvise fails. I must be missing something.


GLOBAL _IID__IShockwaveFlashEvents;
GUID _IID__IShockwaveFlashEvents;
DEFINE_GUID(_IID__IShockwaveFlashEvents, 0xD27CDB6D, 0xAE6D, 0x11CF, 0x96,0xB8,0x44,0x45,0x53,0x54,0x00,0x00);

......

hr = AtlAdvise(win.m_pFlash, win.m_pFlashEvents, _IID__IShockwaveFlashEvents, win.m_FlashCookie);

JR

Apparently I can't assign the value of the guid outside the subroutine with DEFINE_GUID. The compiler doesn't complain, but the guid is null.

Ionic Wind Support Team

DEFINE_GUID in C is a macro.  I assume your using a function.

You'll need to execute that call somewhere in the path of execution.

Or have a separate project file and just do it in assembly, making them all global.

#asm
global _IID_IShockwaveFlashEvents
_IID_IShockwaveFlashEvents:
     dd 0xD27CDB6D
     dw 0xAE6D
     dw 0x11CF
     db 0x96,0xB8,0x44,0x45,0x53,0x54,0x00,0x00
#endasm

Then in the project file that uses them it's just

extern _IID_IShockwaveFlashEvents as GUID;

Once I have the built in data statements this will be a bit easier.
Ionic Wind Support Team