The IDL for the COM onject can be seen here.
A binary of the COM object can be downloaded from here.
The COM object created in Ada is found here.
A zip of the COM source code (in C++) can be downloaded from here.
To install the COM object on your system type:
regsvr32 beep.dll
To compile under ObjectAda remove the pragma Linker_Options and insure that your project includes the following directories in the project search path:
with win32.objbase; use win32.objbase;
with win32.winerror;
use type HRESULT;
with interfaces.c; use interfaces.c;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Unchecked_Conversion;
with system;
procedure ComBeep2 is
pragma Linker_Options("-lole32");
   -- IID for IBeep
   IID_IBeep         : aliased IID := (16#0FE0EE22#,16#8AA2#,16#11d2#,
                        (Char'Val(16#81#),Char'Val(16#AA#),Char'Val(16#44#),
                         Char'Val(16#45#),Char'Val(16#53#),Char'Val(16#54#),
                         Char'Val(16#00#),Char'Val(16#01#)) );
   -- Class ID of an object to create that has an interface to IBeep
   CLSID_BeepClass   : aliased CLSID := (16#0FE0EE21#,16#8AA2#,16#11d2#,
                        (Char'Val(16#81#),Char'Val(16#AA#),Char'Val(16#44#),
                         Char'Val(16#45#),Char'Val(16#53#),Char'Val(16#54#),
                         Char'Val(16#00#),Char'Val(16#01#)) );
                         
   -- IID for IClassFactory
   IID_IClassFactory : aliased IID := (16#00000001#,16#0000#,16#0000#,
                        (Char'Val(16#C0#),Char'Val(16#00#),
                         Char'Val(16#00#),Char'Val(16#00#),
                         Char'Val(16#00#),Char'Val(16#00#),
                         Char'Val(16#00#),Char'Val(16#46#)) );
   -- Interface IBeep
   type IBeep;
   type Pointer_To_IBeep is access all IBeep;
   -- C++ style VTBL of methods in the IBeep Interface
   type IBeepVtbl;
   type Pointer_To_IBeepVtbl is access all IBeepVtbl;
   -- Create method prototypes for IBeep
   -- Don't forger that first argument of C++ methods is C++'s this pointer
   -- IUnkown
   -- IBeep "interface inherits" from IUnkown and therefore requires those
   -- methods also.
   type af_IBeep_QueryInterface is access function (
      This     : access IBeep;
      riid     : REFIID;
      ppvObject: access Win32.PVOID)
      return HRESULT;
   pragma Convention(Stdcall, af_IBeep_QueryInterface);
   type af_IBeep_AddRef is access function (
      This: access IBeep)
      return Win32.ULONG;
   pragma Convention(Stdcall, af_IBeep_AddRef);
   type af_IBeep_Release is access function (
      This: access IBeep)
      return Win32.ULONG;
   pragma Convention(Stdcall, af_IBeep_Release);
   -- IBeep
   -- IBeep only has one method called Beep that sounds a beep and display a
   -- message box.
   type af_IBeep_Beep is access function (
      This: access IBeep)
      return HRESULT;
   pragma Convention(Stdcall, af_IBeep_Beep);
   -- IBeep just contains a pointer to its VTBL
   type IBeep is
      record
         lpVtbl: Pointer_To_IBeepVtbl;
      end record;
   -- IBeepVtbl contains pointers to all the methods IBeep interfaces to.
   type IBeepVtbl is
      record
         QueryInterface: af_IBeep_QueryInterface;
         AddRef        : af_IBeep_AddRef;
         Release       : af_IBeep_Release;
         Beep          : af_IBeep_Beep;
      end record;
   -- Normally Ada passes by reference non scalar types, so we need the
   -- following:
   pragma Convention(C_Pass_By_Copy, IBeep);
   pragma Convention(C_Pass_By_Copy, IBeepVtbl);
   -- Conversion functions to make the compiler happy.
   function To_LPOLESTR is
       new Ada.Unchecked_Conversion (wchar_array, LPOLESTR);
   function To_LPUNKNOWN is
       new Ada.Unchecked_Conversion (system.address, LPUNKNOWN);
   function To_LPCLASSFACTORY is
       new Ada.Unchecked_Conversion (system.address, LPCLASSFACTORY);
   function To_Pointer_To_IBeep is
       new Ada.Unchecked_Conversion (Win32.PVOID, Pointer_To_IBeep);
   RetPointer             : aliased Win32.PVOID;
   hr                     : HRESULT;
   ClassFactoryInterface  : LPCLASSFACTORY;
   BeepInterface          : Pointer_To_IBeep;
   refcount               : Win32.ULONG;
   com_error              : exception;
begin
   put_line("Initialize Com Libraries");
   hr := CoInitialize(system.null_address);
   if hr /= S_OK then
      raise com_error;
   end if;
   put_line("Use CoGetClassObject to get IClassFactory of Beeper Class");
   hr := CoGetClassObject(CLSID_BeepClass'unchecked_access,
                          Win32.DWORD(CLSCTX_ALL),
                          System.Null_Address,
                          IID_IClassFactory'unchecked_access,
                          RetPointer'unchecked_access);
   if hr /= S_OK then
      raise com_error;
   end if;
   put_line("Convert return pointer to pointer to IClassFactory");
   ClassFactoryInterface := To_LPCLASSFACTORY(RetPointer);
   put_line("Use class factory to construct IBeep");
   hr := ClassFactoryInterface.lpvtbl.CreateInstance(ClassFactoryInterface,
               To_LPUNKNOWN(system.null_address),
               IID_IBeep'unchecked_access,
               RetPointer'unchecked_access);
   put_line("Convert return pointer to pointer to IBeep");
   BeepInterface := To_Pointer_To_IBeep(RetPointer);
   put_line("Release class factory");
   refcount := ClassFactoryInterface.lpvtbl.Release(ClassFactoryInterface);
   put_Line("IBeep->Beep");
   hr := BeepInterface.lpvtbl.Beep(BeepInterface);
   if hr /= S_OK then
      raise com_error;
   end if;
   put_Line("Release IBeep Interface");
   refcount := BeepInterface.lpvtbl.Release(BeepInterface);
   put_line("Uninit COM Libs");
   CoUninitialize;
end ComBeep2;