I have implemented an Automation Server in Delphi XE7 according to the code from the Eric Harmon Delphi COM programming book but I can't get COM events to work running on Windows 10.
The automation server has been setup for CiMultiInstance, so one server for multiple clients. The main class implements IConnectionPointContainer. In the Initialize method, I create FConnectionPoints and the FConnectionPoints.CreateConnectionPoint is called successfully. It also successfully calls RegisterActiveObject.
It works fine when calling the server methods, and it has an Events interface but when it tries to send data back to the client, it calls GetEnumerator and falls over at the QueryInterface(IConnectionPointContainer,Container) call.
I have run the server up from an elevated Command line but it makes no differences.
This is the first line of the class:
TMRILocalProxyServer = class(TAutoObject, IConnectionPointContainer, IMRILocalProxyServer)
The IMRILocalProxyServer_TLB includes an event and has component wrappers so for instance there is an InvokeEventMethod.
procedure TMRILocalProxyServer.InvokeEvent(DispID: TDispID; var Params: TVariantArray);
begin
case DispID of
-1: Exit; // DISPID_UNKNOWN
203: if Assigned(FOnReturnData) then
FOnReturnData(Self, Params[0] {OleVariant});
end; {case DispID}
end;
In the client code the OnReturnData has been assigned to a method.
This is part of the Initialize method:
FConnectionPoints := TConnectionPoints.Create(Self);
if AutoFactory.EventTypeInfo <> nil then
begin
FConnectionPoints.CreateConnectionPoint(AutoFactory.EventIID, ckMulti, EventConnect);
OleCheck(RegisterActiveObject(Self as IUnknown, CLASS_MRILocalProxyServer_, ActiveObject_Weak, FROTCookie))
end
This is the code that fails, the first code line of this function.
function TMRILocalProxyServer.GetEnumerator: IEnumConnections;
var
Container : IConnectionPointContainer;
ConnectionPoint : IConnectionPoint;
begin
OleCheck(QueryInterface(IConnectionPointContainer,Container));
OleCheck(Container.FindConnectionPoint(Autofactory.EventIID,ConnectionPoint));
ConnectionPoint.EnumConnections(Result);
end;
The error it is coming up with is '...raised exception class $C0000005 with message 'c0000005 ACCESS_VIOLATION'.
Looking at the two variables, they show as 00000000 i.e. nil.
One last thing, this is compiled for 64-bit code.