• Delphi中COM自动化对象中使用事件


    unit SrvUnit2;
    
    interface
    
    uses
      ComObj, ActiveX, AxCtrls, Classes, SrvEvent_TLB, StdVcl, Srvunit1;
    
    type
      TSimpleEventServer = class(TAutoObject, IConnectionPointContainer, ISimpleEventServer)
      private
        { Private declarations }
        FConnectionPoints: TConnectionPoints;
        FConnectionPoint: TConnectionPoint;
        FEvents: ISimpleEventServerEvents;
        { note: FEvents maintains a *single* event sink. For access to more
          than one event sink, use FConnectionPoint.SinkList, and iterate
          through the list of sinks. }
      public
        procedure Initialize; override;
      protected
        { Protected declarations }
        property ConnectionPoints: TConnectionPoints read FConnectionPoints
          implements IConnectionPointContainer;
        procedure EventSinkChanged(const EventSink: IUnknown); override;
        procedure CallServer; safecall;
      end;
    
    implementation
    
    uses ComServ;
    
    procedure TSimpleEventServer.EventSinkChanged(const EventSink: IUnknown);
    begin
      FEvents := EventSink as ISimpleEventServerEvents;
    end;
    
    procedure TSimpleEventServer.Initialize;
    begin
      inherited Initialize;
      FConnectionPoints := TConnectionPoints.Create(Self);
      if AutoFactory.EventTypeInfo <> nil then
        FConnectionPoint := FConnectionPoints.CreateConnectionPoint(
          AutoFactory.EventIID, ckSingle, EventConnect)
      else FConnectionPoint := nil;
    end;
    
    
    procedure TSimpleEventServer.CallServer;
    begin
      Form1.Memo1.Lines.Add('I have been called by a client');
      if FEvents <> nil then
      begin
        FEvents.EventFired;
        Form1.Memo1.Lines.Add('I am firing an Event');
      end;
    end;
    
    initialization
      TAutoObjectFactory.Create(ComServer, TSimpleEventServer, Class_SimpleEventServer,
        ciMultiInstance, tmApartment);
    end.
    unit ClientUnit;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs,SrvEvent_TLB,ActiveX, ComObj, StdCtrls;
    
    type
      TForm2 = class(TForm)
        Button1: TButton;
        Memo1: TMemo;
        procedure FormCreate(Sender: TObject);
        procedure Button1Click(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        { Private declarations }
        FServer: ISimpleEventServer;
        FEventSink: IUnknown;
    
        FConnectionToken: integer;
      public
        { Public declarations }
        procedure OnEventFired;
      end;
    
      TEventSink = class(TInterfacedObject, IUnknown,IDispatch)
      private
        FController: TForm2;
        {IUknown methods}
        function QueryInterface(const IID: TGUID; out Obj):HResult;stdcall;
        {Idispatch}
        function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
        function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall;
        function GetIDsOfNames(const IID: TGUID; Names: Pointer;
          NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
        function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
          Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall;
      public
        constructor Create(Controller: TForm2);
      end;
    
    var
      Form2: TForm2;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm2.OnEventFired;
    begin
      Memo1.Lines.Add('I have recieved an event');
    end;
    
    constructor TEventSink.Create(Controller: TForm2);
    begin
      inherited Create;
      FController := Controller;
    end;
    
    function TEventSink.Invoke(DispID: integer; const IID: TGUID; LocaleID: integer; Flags: Word; var Params; VarResult,ExcepInfo,ArgErr:Pointer): HResult;
    begin
      Result := S_OK;
      case DispID of
        1: FController.OnEventFired;
      end;
    end;
    
    function TEventSink.QueryInterface(const IID: TGUID; out Obj):HResult;stdcall;
    begin
      if GetInterFace(IID,Obj) then
        Result := S_OK
      else if IsEqualIID(IID,ISimpleEventServerEvents) then
        Result := QueryInterface(IDispatch,Obj)
      else
        Result := E_NOINTERFACE;
    end;
    
    function TEventSink.GetTypeInfoCount(out Count: Integer): HResult;
    begin
      Result := S_OK;
    end;
    function TEventSink.GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult;
    begin
      Result := S_OK;
    end;
    function TEventSink.GetIDsOfNames(const IID: TGUID; Names: Pointer;
          NameCount, LocaleID: Integer; DispIDs: Pointer): HResult;
    begin
      Result := S_OK;
    end;
    
    procedure TForm2.FormCreate(Sender: TObject);
    begin
      FServer := CoSimpleEventServer.Create;
      FEventSink := TEventSink.Create(form2);
      InterfaceConnect(FServer, ISimpleEventServerEvents,FEventSink,FConnectionToken);
    end;
    
    procedure TForm2.Button1Click(Sender: TObject);
    begin
      Memo1.Lines.Add('I am calling the Server');
      FServer.CallServer;
    end;
    
    procedure TForm2.FormDestroy(Sender: TObject);
    begin
      InterfaceDisconnect(FServer,ISimpleEventServer,FConnectionToken);
      FServer := nil;
      FEventSink := nil;
    end;
    
    end.
  • 相关阅读:
    Alpha冲刺Day10
    Alpha冲刺Day9
    Alpha冲刺Day8
    Alpha冲刺Day7
    Alpha冲刺Day6
    SDN
    【Alpha
    【Alpha】团队课程展示
    【Alpha】团队项目测试报告与用户反馈
    【Alpha】总结
  • 原文地址:https://www.cnblogs.com/MaxWoods/p/4006421.html
Copyright © 2020-2023  润新知