home *** CD-ROM | disk | FTP | other *** search
/ Chip 1999 March / Chip_1999-03_cd.bin / zkuste / delphi / INFO / DI9807BL.ZIP / Intf / Server / ChatChannel.pas next >
Pascal/Delphi Source File  |  1998-05-08  |  5KB  |  193 lines

  1. { *****************************************************************************
  2.   Implementing COM Component Callbacks in Delphi
  3.   Code written for Delphi Informant publication
  4.  
  5.   Comments, questions, suggestions?
  6.   Binh Ly, Systems Analyst (bly@brickhouse.com)
  7.   Brickhouse Data Systems (http://www.brickhouse.com)
  8.   *****************************************************************************
  9. }
  10. unit ChatChannel;
  11.  
  12. interface
  13.  
  14. uses
  15.   ComObj, ActiveX, ChatServer_TLB, Classes;
  16.  
  17. type
  18.   TChatUsers = class;
  19.  
  20.   TChatChannel = class (TAutoObject, IChatChannel)
  21.   protected
  22.     { IChatChannel }
  23.     function ConnectUser(const Callback: IChatEvent; var UserId: Integer): WordBool; safecall;
  24.     function DisconnectUser(UserId: Integer): WordBool; safecall;
  25.     procedure BroadcastMessage (const UserName, Message: WideString); safecall;
  26.   protected
  27.     FUsers : TChatUsers;
  28.     procedure Initialize; override;
  29.   public
  30.     destructor Destroy; override;
  31.     property Users : TChatUsers read FUsers;
  32.   end;
  33.  
  34.   TChatUser = class
  35.   public
  36.     UserId : integer;
  37.     Callback : IChatEvent;
  38.   end;
  39.  
  40.   TChatUsers = class
  41.   protected
  42.     FItems : TList;
  43.     FLastUserId : integer;
  44.     function GetItems (i : integer) : TChatUser;
  45.   public
  46.     constructor Create;
  47.     destructor Destroy; override;
  48.     function AddUser (const Callback: IChatEvent; var UserId : integer): boolean;
  49.     function DeleteUser (UserId : integer) : boolean;
  50.     function FindUser (UserId : integer) : integer;
  51.     function Count : integer;
  52.     property Items [i : integer] : TChatUser read GetItems; default;
  53.   end;
  54.  
  55. const
  56.   MainChatChannel : IChatChannel = NIL;
  57.  
  58. implementation
  59.  
  60. uses
  61.   ComServ
  62.   ;
  63.  
  64. { TChatChannel }
  65.  
  66. function TChatChannel.ConnectUser(const Callback: IChatEvent; var UserId: Integer): WordBool;
  67. begin
  68.   { connect new client and return connection id (UserId) }
  69.   Result := Users.AddUser (Callback, UserId);
  70. end;
  71.  
  72. function TChatChannel.DisconnectUser(UserId: Integer): WordBool;
  73. begin
  74.   { disconnect client using specified connection id }
  75.   Result := Users.DeleteUser (UserId);
  76. end;
  77.  
  78. procedure TChatChannel.BroadcastMessage (const UserName, Message: WideString);
  79. var
  80.   i : integer;
  81. begin
  82.   { loops through all client connections and issues the callback message broadcast }
  83.   for i := 0 to Users.Count - 1 do
  84.   begin
  85.     try
  86.       Users [i].Callback.GotMessage (UserName, Message);
  87.     except
  88.       { if error happened, this callback client probably disconnected
  89.         prematurely; therefore we just ignore the error and process all
  90.         remaining clients.
  91.       }
  92.     end;  { except }
  93.   end;  { for }
  94. end;
  95.  
  96. procedure TChatChannel.Initialize;
  97. begin
  98.   inherited;
  99.  
  100.   { create TChatUsers list helper }
  101.   FUsers := TChatUsers.Create;
  102. end;
  103.  
  104. destructor TChatChannel.Destroy;
  105. begin
  106.   { destroy TChatUsers list helper }
  107.   FUsers.Free;
  108.   
  109.   inherited;
  110. end;
  111.  
  112.  
  113. { TChatUsers }
  114.  
  115. function TChatUsers.GetItems (i : integer) : TChatUser;
  116. begin
  117.   { returns a single TChatUser by index }
  118.   Result := TChatUser (FItems.Items [i]);
  119. end;
  120.  
  121. constructor TChatUsers.Create;
  122. begin
  123.   inherited;
  124.  
  125.   { create internal TChatUsers list }
  126.   FItems := TList.Create;
  127. end;
  128.  
  129. destructor TChatUsers.Destroy;
  130. var
  131.   i : integer;
  132. begin
  133.   { destroy internal TChatUsers list }
  134.   for i := 0 to Count - 1 do
  135.     Items [i].Free;
  136.   FItems.Free;
  137.  
  138.   inherited;
  139. end;
  140.  
  141. function TChatUsers.AddUser (const Callback: IChatEvent; var UserId : integer): boolean;
  142. var
  143.   User : TChatUser;
  144. begin
  145.   { add a new TChatUser to the internal list and returns a unique UserId to caller }
  146.   inc (FLastUserId);
  147.   UserId := FLastUserId;
  148.  
  149.   User := TChatUser.Create;
  150.   User.UserId := FLastUserId;
  151.   User.Callback := Callback;
  152.   FItems.Add (User);
  153.  
  154.   Result := TRUE;
  155. end;
  156.  
  157. function TChatUsers.DeleteUser (UserId : integer) : boolean;
  158. var
  159.   i : integer;
  160. begin
  161.   { remove a TChatUser item from the list by UserId }
  162.   Result := FALSE;
  163.   i := FindUser (UserId);
  164.   if (i >= 0) then begin
  165.     Items [i].Free;
  166.     FItems.Delete (i);
  167.     Result := TRUE;
  168.   end;  { if }
  169. end;
  170.  
  171. function TChatUsers.FindUser (UserId : integer) : integer;
  172. var
  173.   i : integer;
  174. begin
  175.   { locate a TChatUser item in the list by UserId }
  176.   Result := -1;
  177.   for i := 0 to Count - 1 do
  178.     if (Items [i].UserId = UserId) then begin
  179.       Result := i;
  180.       Break;
  181.     end;  { if }
  182. end;
  183.  
  184. function TChatUsers.Count : integer;
  185. begin
  186.   { returns the number of TChatUser items in the list }
  187.   Result := FItems.Count;
  188. end;
  189.  
  190. initialization
  191.   TAutoObjectFactory.Create(ComServer, TChatChannel, Class_ChatChannel, ciInternal);
  192. end.
  193.