RESOLUTION
There are several ways to work around this problem. One method is to use the
SINK_ENTRY_INFO macro and define an
_ATL_FUNC_INFO structure to provide type information for the event method. Use a VT_I4 type for the
enum parameter.
For more information about SINK_ENTRY_INFO, click the following article number to view the article in the Microsoft Knowledge Base:
194179
AtlEvnt.exe sample shows how to create ATL sinks by using the ATL IDispEventImpl and IDispEventSimpleImpl classes
If you are using IDispEventImpl<> for the sink, you can override the virtual function
GetFuncInfoFromID. A simple override is as follows.
HRESULT GetFuncInfoFromId(const IID& iid, DISPID dispidMember,LCID lcid, _ATL_FUNC_INFO& info)
{
// class base class implementation
HRESULT hr = IDispEventImpl<IDC_OBJ, CSinkObj, &DIID__IEnumEventEvents, &LIBID_TESTUNKARTICLELib, 1, 0>::GetFuncInfoFromId(iid, dispidMember,lcid, info);
if (SUCCEEDED(hr))
{
// is this the correct event interface
if (InlineIsEqualGUID(iid, DIID__IEnumEventEvents))
{
//check for dispid of event with enum param
switch(dispidMember)
{
case 1:
// the enumeration parameter is change to VT_I4
// info.pVarTypes represents the type of params
// params are stored in reverse order, with 0 base index
if (info.pVarTypes[0] == VT_USERDEFINED)
info.pVarTypes[0] = VT_I4;
break;
}
}
}
return hr;
}
The most direct approach when using IDispEventImpl<>is to change the implementation of
GetUserDefinedType in Atlcom.h. At line 3968, after the code block that begins "if(pta && pta->typekind == TKIND_ALIAS)", a second
if statement could be inserted that would set the correct
VARTYPE for enumerations. This block could be written as follows.
if (pta && pta->typekind == TKIND_ENUM)
{
vt = VT_I4;
}
REFERENCES
For more information, click the following article numbers to view the articles in the Microsoft Knowledge Base:
194179
AtlEvnt.exe sample shows how to creates ATL sinks by using the ATL IDispEventImpl and IDispEventSimpleImpl classes
181277 The AtlSink.exe sample demonstrates how to implement a dispinterface sink by using the Active Template Library (ATL) in Visual C++
See also the ATL Articles in the Visual C++ documentation, specifically "ATL Collections and Enumerators" and "Event Handling in ATL."