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
A version that uses the Win32 Api from the OpenPack is available here from John Walker.
To compile under ObjectAda with Win32Ada 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 win32.winerror;
with interfaces.c; use interfaces.c;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Unchecked_Conversion;
with system;
procedure ComBeep 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#)) );
-- 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 Win32.Winerror.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 displays a
-- message box.
type af_IBeep_Beep is access function (
This: access IBeep)
return Win32.Winerror.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_LPUNKNOWN is
new Ada.Unchecked_Conversion (system.address, LPUNKNOWN);
function To_Pointer_To_IBeep is
new Ada.Unchecked_Conversion (Win32.PVOID, Pointer_To_IBeep);
RetPointer : aliased Win32.PVOID;
hr : Win32.Winerror.HRESULT;
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("CoCreateInstance");
hr := CoCreateInstance(CLSID_BeepClass'unchecked_access,
To_LPUNKNOWN(system.null_address),
Win32.DWORD(CLSCTX_ALL),
IID_IBeep'unchecked_access,
RetPointer'unchecked_access);
if hr /= S_OK then
raise com_error;
end if;
put_line("Convert return pointer to pointer to IBeep");
BeepInterface := To_Pointer_To_IBeep(RetPointer);
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 ComBeep;