稍微有些复杂。需要在服务器端建立一个Interface,然后由Client端完成。Client端将这个Interface注册到服务器端,服务器在特定的情况下,调用注册来的Interface的方法,就达到了Callback的目的。

解决方案 »

  1.   

    Client调用Server,实际上也是进行Interface调用,只不过Client调用的是由Server完成的Interface。现在要反过来,你明白了吗?
      

  2.   

    To:chechy(chechy)
    哈哈.
    这里有一个问题.
    反过来就是Client作DCOM的服务器.
    可是Client不具备做DCOM服务器的条件.
    原因如下:
      客房端为95/98,多台,不可能去配那么多台98Server。
    退做不了那么多的Server,怎么实现您说的反向实现呢?
      

  3.   

    我可没有Client作DCOM服务器。不过Client确实需要完成一个Interface,并将这个Interface的实例传递给服务器端。
      

  4.   

    To:chechy(chechy)
    你的意思我明白一点.
    可是我不知道如何实现?
    您有例子吗,
    如果您能在帖子里写一个关键部分的源码也好,帮忙大侠,我急用~~
      

  5.   

    Client 端代码:
    unit CallCli;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      DBClient, MConnect, StdCtrls, CallbackSrv_TLB, SConnect, ComObj, ActiveX,
      DB;type
      TClient = class(TAutoIntfObject, IClient)
      protected
        procedure Progress(RecNo, RecCount: integer; var Continue: WordBool); safecall;
        procedure Done; safecall;
      end;  TfrmClient = class(TForm)
        btnTraverse: TButton;
        DCOMConnection1: TDCOMConnection;
        SocketConnection1: TSocketConnection;
        chkStop: TCheckBox;
        gbProgress: TGroupBox;
        lblProgress: TLabel;
        Label1: TLabel;
        Label2: TLabel;
        procedure btnTraverseClick(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
        FClient: TClient;
      public
        { Public declarations }
        MyDispatchConnection: TDispatchConnection;
      end;var
      frmClient: TfrmClient;implementation{$R *.DFM}procedure TClient.Progress(RecNo, RecCount: integer; var Continue: WordBool);
    begin
      frmClient.lblProgress.Caption:=Format('%d/%d', [RecNo, RecCount]);
      Application.ProcessMessages;
      Continue:=not frmClient.chkStop.Checked;
    end;procedure TClient.Done;
    begin
      ShowMessage('Done!! [callback]');
    end;
    procedure TfrmClient.btnTraverseClick(Sender: TObject);
    begin
      MyDispatchConnection.AppServer.TraverseTable;
    end;{MyDispatchConnection shows how to switch between multiple DipatchConnection}
    {components easily, using polymorphism.}
    procedure TfrmClient.FormCreate(Sender: TObject);
    var
      typelib: ITypeLib;
    begin
      MyDispatchConnection:=DCOMConnection1;
      MyDispatchConnection.Connected:=true;
      OleCheck(LoadRegTypeLib(LIBID_CallbackSrv, 1, 0, 0, typelib));
      FClient:=TClient.Create(typelib, IClient);  MyDispatchConnection.AppServer.SetCallback(FClient as IDispatch);
    end;end.服务器一端:unit CallDM;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      ComServ, ComObj, VCLCom, StdVcl, DataBkr, CallbackSrv_TLB, Db,
      DBTables;type
      TServer = class(TRemoteDataModule, IServer)
        Table1: TTable;
      private
        { Private declarations }
    //    FCallback: IClient; {Cannot use early binding callback in socket mode}
        FCallback: OleVariant;
      public
        { Public declarations }
      protected
        procedure SetCallback(aCallback: OleVariant); safecall;
        procedure TraverseTable; safecall;
      end;var
      Server: TServer;implementation{$R *.DFM}procedure TServer.SetCallback(aCallback: OleVariant);
    begin
      FCallback:=aCallback;
    end;procedure TServer.TraverseTable;
    var
      bContinue: WordBool;
      iRecordCount: integer;
    begin
      Table1.Open;
      Table1.First;
      iRecordCount:=Table1.RecordCount;
      bContinue:=true;
      while (not Table1.eof) and bContinue do
      begin
        Table1.Next;
        FCallback.Progress(Table1.RecNo ,iRecordCount, bContinue);
      end;
      Table1.Close;
      FCallback.Done;
    end;initialization
      TComponentFactory.Create(ComServer, TServer,
        Class_Server, ciMultiInstance, tmApartment);
    end.