给你一个我自己写的,用UDP协议,里面用了CoolTrayIcon控件,平时程序最小化为系统托盘图标
收到新信息时,自动弹出窗口到最前端。
unit UnitUDPchat;
{=====================================================================================}
{协议说明: }
{New:新客户登录:程序启动时发送给列表中的所有用户:'New'+用户名(可以用机器名); }
{Hiu:客户返回的确认信息:当收到其它发送来的登录信息进行确认; }
{Msg:发送消息:用一个用户发送给另一个用户的消息:'Msg'+'='+消息的长度+'+'+消息的内容;}
{Bye:用户退出:程序关闭时发送给列表中的所有用户:'Bye'+用户名(可以用机器名); }
{=====================================================================================}
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, CoolTrayIcon, ComCtrls, NMUDP, Menus, ScktComp,
MmSystem, Registry, IniFiles;
const msghead='NewHiuMsgBye';
type
TfrmChat = class(TForm)
Panel1: TPanel;
lbClientList: TListBox;
StatusBar1: TStatusBar;
Splitter1: TSplitter;
Panel2: TPanel;
Panel3: TPanel;
Panel4: TPanel;
Panel5: TPanel;
Panel6: TPanel;
PopupMenu1: TPopupMenu;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
N4: TMenuItem;
N5: TMenuItem;
edtMessage: TEdit;
cbClientList: TComboBox;
btnSend: TButton;
Label1: TLabel;
Timer1: TTimer;
UDP2: TNMUDP;
TrayIcon: TCoolTrayIcon;
memClient: TRichEdit;
procedure FormCreate(Sender: TObject);
procedure TrayIconClick(Sender: TObject);
procedure N3Click(Sender: TObject);
procedure N5Click(Sender: TObject);
procedure edtMessageChange(Sender: TObject);
procedure btnSendClick(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormHide(Sender: TObject);
procedure UDP2Status(Sender: TComponent; status: String);
procedure UDP2DataSend(Sender: TObject);
procedure UDP2DataReceived(Sender: TComponent; NumberBytes: Integer;
FromIP: String; Port: Integer);
procedure FormDestroy(Sender: TObject);
procedure edtMessageKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frmChat: TfrmChat;
FormShow:Boolean; //是否显示窗口
ClientList, ClientIPList, ClientHostList:Tstrings;
ClientAddress, ClientName:string;
cfgFile:TiniFile;
i:integer;
ComputerName:string;
msg:string; //发送和接收到消息
MyStream: TMemoryStream;
StartPos, SelLen:integer;
implementation
{$R *.DFM}
procedure TfrmChat.FormCreate(Sender: TObject);
var
sz:dword;
s:string;
cn
char;
Reg: TRegistry;
ClientInfo:string;
cfgFileName:string;
begin
//将程序加入系统的启动组
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.OpenKey('/Software/Microsoft/Windows/CurrentVersion/Run', True)
then Reg.WriteString('UdpChat',ParamStr(0));
finally
Reg.CloseKey;
Reg.Free;
inherited;
end;
//文本参数初始化
StartPos:=0;
SelLen:=0;
//窗口状态初始化
FormShow:=False; //窗口隐藏
StatusBar1.Panels[1].text:=DateTimeToStr(Now());
//显示日期、时间
GetMem(cn, 100);
sz:=100;
GetComputerName(cn, sz);
ComputerName:=string(cn);
FreeMem(cn);
//取得计算机名
UDP2.ReportLevel := Status_Basic;
ClientList:=TStringList.Create;
ClientIPList:=TStringList.Create;
ClientHostList:=TStringList.Create;
//读取配置文件信息
cfgFileName:=ExtractFilePath(ParamStr(0))+ 'Chatcfg.ini';
cfgFile:=TIniFile.Create(cfgFileName);
cfgFile.ReadSectionValues('AllClient', ClientList);
cfgFile.Free;
for i:=0 to ClientList.Count-1 do
begin
ClientInfo:=ClientList.Strings
;
ClientIPList.Add(Copy(ClientInfo, 1, pos('=', ClientInfo)-1));
ClientHostList.Add(Copy(ClientInfo, pos('=', ClientInfo)+1,
Length(ClientInfo)-pos('=', ClientInfo)));
end;
//初始化用户信息列表
msg:='New'+ComputerName;
MyStream := TMemoryStream.Create;
try
MyStream.Write(msg[1], Length(msg));
for i:=0 to ClientIPList.Count-1 do
if ClientHostList.Strings<>ComputerName then
begin
UDP2.RemoteHost:=ClientIPList.Strings;
UDP2.SendStream(MyStream);
end;
finally
MyStream.Free;
end;
TrayIcon.Icon:=Application.Icon;
end;
procedure TfrmChat.TrayIconClick(Sender: TObject);
begin
FormShow:=not FormShow;
if FormShow then frmChat.Show else frmChat.Hide;
end;
procedure TfrmChat.N3Click(Sender: TObject);
begin
//frmAbout.Show;
end;
procedure TfrmChat.N5Click(Sender: TObject);
begin
Application.Terminate;
end;
procedure TfrmChat.edtMessageChange(Sender: TObject);
begin
if edtMessage.Text=''
then btnSend.Enabled:=False
else if cbClientList.Text='' then btnSend.Enabled:=False
else btnSend.Enabled:=True;
end;
procedure TfrmChat.btnSendClick(Sender: TObject);
begin
ClientName:=cbClientList.Text;
msg:='Msg'+'=' + IntToStr(Length(edtMessage.Text)) + '+' + edtMessage.Text;
ClientAddress:=ClientIPList.Strings[ClientHostList.IndexOf(ClientName)];
UDP2.RemoteHost:=ClientAddress;
MyStream := TMemoryStream.Create;
try
MyStream.Write(msg[1], Length(msg));
UDP2.SendStream(MyStream);
finally
MyStream.Free;
end;
msg:='To '+ ClientName+': '+ edtMessage.Text;
memClient.Lines.Add(msg);
memClient.SelStart:=StartPos;
memClient.SelLength:=Length(msg);
memClient.SelAttributes.Color:=clred; //设置插入字符的颜色
StartPos:=StartPos+Length(msg)+2;
edtMessage.Text:='';
edtMessage.SetFocus;
end;
procedure TfrmChat.Timer1Timer(Sender: TObject);
begin
StatusBar1.Panels[1].text:=DateTimeToStr(Now());
end;
procedure TfrmChat.FormHide(Sender: TObject);
begin
FormShow:=False;
end;
procedure TfrmChat.UDP2Status(Sender: TComponent; status: String);
begin
If StatusBar1 <> nil then
StatusBar1.SimpleText := status;
end;
procedure TfrmChat.UDP2DataSend(Sender: TObject);
begin
StatusBar1.SimpleText := '消息已经发送';
end;
procedure TfrmChat.UDP2DataReceived(Sender: TComponent;
NumberBytes: Integer; FromIP: String; Port: Integer);
var
C: array[1..2048] of Char;
msglen:integer;
begin
if NumberBytes <= 2048
then begin
UDP2.ReadBuffer(C, NumberBytes);
msg:=Trim(string(C));
case pos(copy(msg, 1, 3), msghead) of
1:begin //New:新客户登录
ClientAddress:=FromIP;
ClientName:=Copy(msg, 4, Length(msg)-3);
StatusBar1.Panels[0].Text:='好友 '+ ClientName + ' 上线啦!';
PlaySound('Global.wav', 0, SND_ASYNC);
if ClientIPList.IndexOf(ClientAddress)<>-1
then begin
if ClientHostList.Strings[ClientIPList.IndexOf(ClientAddress)]<>ClientName
then ClientHostList.Strings[ClientIPList.IndexOf(ClientAddress)]:=ClientName;
end
else begin
ClientIPList.Add(ClientAddress);
ClientHostList.Add(ClientName);
end;
cbClientList.Items.Add(ClientName);
lbClientList.Items.Add(ClientName +'('+ ClientAddress+')');
msg:='Hiu'+ComputerName; //返回响应消息
MyStream := TMemoryStream.Create;
try
MyStream.Write(msg[1], Length(msg));
UDP2.RemoteHost:=ClientAddress;
UDP2.SendStream(MyStream);
finally
MyStream.Free;
end;
end; //case 1
4:begin //Hiu:客户响应
ClientAddress:=FromIP;
ClientName:=Copy(msg, 4, Length(msg)-3);
StatusBar1.Panels[0].Text:='接收到 '+ ClientName + ' 发送来的消息';
if ClientIPList.IndexOf(ClientAddress)<>-1
then begin
if ClientHostList.Strings[ClientIPList.IndexOf(ClientAddress)]<>ClientName
then ClientHostList.Strings[ClientIPList.IndexOf(ClientAddress)]:=ClientName;
end
else begin
ClientIPList.Add(ClientAddress);
ClientHostList.Add(ClientName);
end;
cbClientList.Items.Add(ClientName);
lbClientList.Items.Add(ClientName +'('+ClientAddress+')');
end;
7:begin //Msg:正常消息
if FormShow=False then
begin
FormShow:=True;
frmChat.Show;
end;
PlaySound('msg.wav', 0, SND_ASYNC);
ClientAddress:=FromIP;
ClientName:=ClientHostList.Strings[ClientIPList.IndexOf(ClientAddress)];
msglen:=StrToInt(Copy(msg, 5, pos('+', msg)-5));
msg:='From '+ClientName+': '
+Copy(msg, pos('+', msg)+1, length(msg)-pos('+', msg));
memClient.Lines.Add(msg);
memClient.SelStart:=StartPos;
memClient.SelLength:=Length(msg);
memClient.SelAttributes.Color:=clBlue; //设置插入字符的颜色
StartPos:=StartPos+Length(msg)+2;
edtMessage.SetFocus;
end; //case 7
10:begin //Bye:客户退出
ClientAddress:=FromIP;
ClientName:=ClientHostList.Strings[ClientIPList.IndexOf(ClientAddress)];
cbClientList.Items.Delete(cbClientList.Items.IndexOf(ClientName));
lbClientList.Items.Delete(lbClientList.Items.IndexOf(ClientName+'('+ ClientAddress+')'));
end; //cse 10
else begin //其它
StatusBar1.Panels[0].Text:='您接收错误消息';
end; //else
end; //case
end //if
end; //UDP2DataReceived
procedure TfrmChat.FormDestroy(Sender: TObject);
var
cfgFileName:string;
begin
//向其他用户道别
msg:='Bye'+ComputerName;
MyStream := TMemoryStream.Create;
try
MyStream.Write(msg[1], Length(msg));
for i:=0 to ClientIPList.Count-1 do
if ClientHostList.Strings<>ComputerName then
begin
UDP2.RemoteHost:=ClientIPList.Strings;
UDP2.SendStream(MyStream);
end;
finally
MyStream.Free;
end;
//保存客户列表
cfgFileName:=ExtractFilePath(ParamStr(0))+ 'Chatcfg.ini';
cfgFile:=TIniFile.Create(cfgFileName);
for i:=0 to ClientIPList.Count-1 do
begin
cfgFile.writestring('AllClient', ClientIPList.strings, ClientHostList.Strings);
end;
cfgFile.Free;
ClientList.Free;
ClientIPList.Free;
ClientHostList.Free;
end;
procedure TfrmChat.edtMessageKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key=VK_Return
then if cbClientList.Text<>'' then btnSend.Click
else ShowMessage('请选择好友名称!');
end;
end.