User Defined Attributes

John Chapman johnch_atms at hotmail.com
Tue Nov 6 12:33:14 PST 2012


On Tuesday, 6 November 2012 at 17:20:10 UTC, Walter Bright wrote:
> On 11/6/2012 9:07 AM, John Chapman wrote:
>> UDAs appear to work on class, struct and global methods, but 
>> not interface
>> methods. Any reason for the omission? Would be great to have 
>> them on interface
>> methods too - for example to define COM dispids.
>
> Can you show an example code snippet?

It would save having to read the registry and load type libraries 
at runtime just to map method names to corresponding IDs.

struct dispid {
   int value;
}

// WebBrowser event interface to be implemented
interface DWebBrowserEvents2 : IDispatch {
   [dispid(102)] void statusTextChange();
   [dispid(108)] void progressChange();
   [dispid(105)] void commandStateChange();
   /* and so on */
}

Then the implementing class maps method names to IDs.

mixin template COMDispatch() {
   int[string] dispIdMap;
   void delegate()[int] methodMap;
   this() {
     // Use __traits to get member names and dispid attributes
     // from base interfaces and store in dispIdMap.
     // Then connect up IDs to delegates in methodMap.
     foreach (T; InterfacesTuple!(typeof(this)))
       foreach (m; __traits(getMembers, T))
         methodMap[dispIdMap[m]] = &mixin(m);
   }
   HRESULT GetDispIDsOfNames(wchar** names, int count, int* ids) {
     // A COM component asks for IDs of our methods.
     foreach (i; 0 .. count) {
       ids[i] = dispIdMap.get(names[i].toString(), DISPID_UNKNOWN);
     }
   }
   HRESULT Invoke(int dispId) {
     // A COM component calls Invoke, and we forward to a method.
     if (auto m = dispId in methodMap) m();
   }
}

class WebBrowserEventsImpl : DWebBrowserEvents2 {
   mixin COMDispatch;

   void statusTextChange() {}
   void progressChange() {}
   void commandStateChange() {}
}




More information about the Digitalmars-d-announce mailing list