推荐一篇文章
今天下午试通,没有问题
There is also a way for the server to call methods on the client. Its a
little involved to set up and I have not tried it myself, however, the
following is how todo
it :
Server
-------
1). In the server _TLB unit, create a new interface, lets call it IClient.
2). After adding this, expand its tree and add any client methods that will
be called. For example, lets add a method called SendRecordsProcessed which
takes one parameter NumberRecords of type Integer.
3). Now expand the main RemoteDataModule interface to add a new server
automation method called ConnectClient which takes one parameter, IClient.
4). ConnectClient assigns its interface reference parameter to a variable
that is added to the remote data module, so, edit that RemoteDataModule's
unit and add a private variable ClientConnection of type IClient. In other
words, ClientConnection is the server's reference to the object that
implements the IClient interface with the client. With this interface
reference the server can call any method of the interface.
5). Insert this new method's implementation code as follows :
procedure TServer.ConnectClient(const Client: IClient);
begin
ClientConnection := Client;
end;
6). In your server you must have a procedure(s) or function(s) which are
doing all of this processing of which you speak, so at the end of the
processing insert the following call :
ClientConnection.SendRecordsProcessed( <NumberOfRecords > );
So this is using the interface reference to call the SendRecordsProcessed
method in the client app.
Client
-------
We must now add the client side processing necessary, ie. an object that
implements the IClient interface. In your main formdo
the following :
1). Declare the client side object that implements the IClient interface
TCallBack = class( TAutoIntfObject, IClient )
procedure SendRecordsProcessed( const NumberRecords:
Integer );
safecall;
end;
The TCallback object descends from TAutoIntfObject which provides support
for the IDispatch interface. The implementation code for the
SendRecordsProcessed methoddo
es whatever it is you want todo
with that
number of records processed, ie. display it in a message box or on a form,
so I'll leave that up to you.
2). Include the server's _TLB unit in the uses clause of the main form.
3). Variable declarations global to the main form's unit
var
ServerTypeLib: ITypeLib;
TypeLibResult: HResult;
CallBack: IClient;
4). Build the heart of the callback mechanism in the OnCreate event handler
of the client app's main form.
procedure TMainForm.FormCreate(Sender: TObject);
var
Srvr: <ServerInterfaceName>;
// Name as defined in the
server TLB, eg. IServer
4.1). Call the Windows API function LoadRegTypeLib to load the server's type
library. The parameters are :
The type library's GUID, definied as a constant LIBID_XXX in the
server's TLB unit
The type library's major version number
The type library's minor version number
The national language code of the library
An interface reference variable of the type ITypeLib that is
initialised by the call
to point to the type library ( ServerTypeLib var above )
TypeLibResult := LoadRegTypeLib( LIBID_XXX, 1, 0, 0,
ServerTypeLib )
4.2). Check the result of the LoadRegTypeLib
If TypeLibResult <> S_OK then
begin
ShowMessage( 'Error loading type library' );
Exit;
end;
4.3). Create an instance of the TCallback automation object. The type
library and interface that the TCallBack object implements are passed as
parameters to its constructor and the returned value is assigned to the
interface reference variable CallBack.
CallBack := TCallBack.Create( ServerTypeLib, IClient );
4.4). Next, obtain a reference to the server's interface IClient by casting
the DComConnection ( MidasConnection ) AppServer property to the interface
type.
Srvr := IDispatch( <DataModule>.<DComConnection>.AppServer ) as
<ServerInterfaceName>;
4.5). Finally call the server's ConnectClient automation method, passing the
interface reference variable for the TCallBack object.
Srvr.ConnectClient( CallBack );
I apologise in advance if I have mis-typed or left anything out, but it
should be a good enough starting point.
Dave