home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1999 March
/
Chip_1999-03_cd.bin
/
zkuste
/
delphi
/
INFO
/
DI9807BL.ZIP
/
CpDisp
/
Server
/
ChatChannel.pas
next >
Wrap
Pascal/Delphi Source File
|
1998-05-08
|
5KB
|
141 lines
{ *****************************************************************************
Implementing COM Component Callbacks in Delphi
Code written for Delphi Informant publication
Comments, questions, suggestions?
Binh Ly, Systems Analyst (bly@brickhouse.com)
Brickhouse Data Systems (http://www.brickhouse.com)
*****************************************************************************
}
unit ChatChannel;
interface
uses
Windows, ComObj, ActiveX, ChatServer_TLB, Classes, AxCtrls;
type
TChatChannel = class (TAutoObject, IChatChannel)
protected
{ IChatChannel }
function ConnectUser(const Callback: IChatEvent; var UserId: Integer): WordBool; safecall;
function DisconnectUser(UserId: Integer): WordBool; safecall;
procedure BroadcastMessage (const UserName, Message: WideString); safecall;
protected
FChatUsers : TConnectionPoints;
FChatEventSinks : TConnectionPoint;
FDispChatEventSinks : TConnectionPoint;
procedure Initialize; override;
function ObjQueryInterface (const IID: TGUID; out Obj): Integer; override;
public
destructor Destroy; override;
end;
const
MainChatChannel : IChatChannel = NIL;
implementation
uses
ComServ
;
{ TChatChannel }
function TChatChannel.ConnectUser(const Callback: IChatEvent; var UserId: Integer): WordBool;
var
cpChatUsers : IConnectionPointContainer;
cpChatEventSinks : IConnectionPoint;
begin
{ Standard connect code for connection points }
cpChatUsers := Self as IConnectionPointContainer;
cpChatUsers.FindConnectionPoint (IChatEvent, cpChatEventSinks);
cpChatEventSinks.Advise (Callback as IUnknown, UserId);
//OleCheck ((FChatEventSinks as IConnectionPoint).Advise (Callback as IUnknown, UserId));
Result := TRUE;
end;
function TChatChannel.DisconnectUser(UserId: Integer): WordBool;
var
cpChatUsers : IConnectionPointContainer;
cpChatEventSinks : IConnectionPoint;
begin
{ Standard disconnect code for connection points }
cpChatUsers := Self as IConnectionPointContainer;
cpChatUsers.FindConnectionPoint (IChatEvent, cpChatEventSinks);
cpChatEventSinks.UnAdvise (UserId);
//OleCheck ((FChatEventSinks as IConnectionPoint).UnAdvise (UserId));
Result := TRUE;
end;
procedure TChatChannel.BroadcastMessage (const UserName, Message: WideString);
var
Enum : IEnumConnections;
ConnectData : TConnectData;
Fetched : Longint;
ifDisp : IDispatch;
begin
{ loops through all client connections and issues the callback message broadcast }
{ Handle normal ChatEvent sinks }
OleCheck ((FChatEventSinks as IConnectionPoint).EnumConnections (Enum));
while Enum.Next (1, ConnectData, @Fetched) = S_OK do
begin
try
(ConnectData.pUnk as IChatEvent).GotMessage (UserName, Message);
ConnectData.pUnk := nil;
except
{ if error happened, this callback client probably disconnected
prematurely; therefore we just ignore the error and process all
remaining clients.
}
end; { except }
end; { while }
{ Handle Dispatch only ChatEvent sinks using direct dispatch Id binding }
Enum := NIL;
OleCheck ((FDispChatEventSinks as IConnectionPoint).EnumConnections (Enum));
while Enum.Next (1, ConnectData, @Fetched) = S_OK do
begin
try
ifDisp := ConnectData.pUnk as IDispatch;
IDispChatEvent (ifDisp).GotMessage (UserName, Message);
ConnectData.pUnk := nil;
except
{ if error happened, this callback client probably disconnected
prematurely; therefore we just ignore the error and process all
remaining clients.
}
end; { except }
end; { while }
end;
procedure TChatChannel.Initialize;
begin
inherited;
FChatUsers := TConnectionPoints.Create (Self);
FChatEventSinks := FChatUsers.CreateConnectionPoint (IChatEvent, ckMulti, NIL);
FDispChatEventSinks := FChatUsers.CreateConnectionPoint (IDispChatEvent, ckMulti, NIL);
end;
function TChatChannel.ObjQueryInterface (const IID: TGUID; out Obj): Integer;
begin
Result := inherited ObjQueryInterface (IID, Obj);
if not Succeeded (Result) then
{ delegate QueryInterface to FChatUsers for IConnectionPointContainer }
if (IsEqualIID (IID, IConnectionPointContainer)) then
if FChatUsers.GetInterface (IID, Obj) then Result := S_OK;
end;
destructor TChatChannel.Destroy;
begin
FDispChatEventSinks.Free;
FChatEventSinks.Free;
FChatUsers.Free;
inherited;
end;
initialization
TAutoObjectFactory.Create(ComServer, TChatChannel, Class_ChatChannel, ciInternal);
end.