📄 chatclient.cpp
字号:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <stdlib.h>
#include "chatclient.h"
#include "setting.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TChatForm *ChatForm;
//---------------------------------------------------------------------------
__fastcall TChatForm::TChatForm(TComponent* Owner)
: TForm(Owner)
{
OutSocket = NULL;
Application->OnIdle = ValidateControls;
NickName = "无名氏";
UserList="";
CurrentUserListStatus=ULS_SHOW;
CurrentLinkStatus=LS_STOP;
//默认广播模式
UserCheckListBox->Enabled=false;
}
//---------------------------------------------------------------------------
void __fastcall TChatForm::ValidateControls(TObject *Sender, bool &Done)
{
if (CurrentLinkStatus==LS_START) Settings->Enabled =true;
else Settings->Enabled =false;
Memo2->ReadOnly = !OutSocket;
}
//---------------------------------------------------------------------------
void __fastcall TChatForm::ConnectDisconnectClick(TObject *Sender)
{
switch(CurrentLinkStatus)
{
case LS_START:
{
EnableClient();
ConnectDisconnect->Caption="断开连接";
CurrentLinkStatus=LS_STOP;
break;
}
case LS_STOP:
{
if (CurrentLinkStatus==LS_START)
{
DisableClient();
}
CurrentLinkStatus=LS_START;
ConnectDisconnect->Caption="连接";
break;
}
}
}
//---------------------------------------------------------------------------
void __fastcall TChatForm::SettingsClick(TObject *Sender)
{
SettingsForm = new TSettingsForm(this);
SettingsForm->HostEdit->Text = ClientSocket1->Host;
SettingsForm->NickNameEdit->Text = NickName;
if (SettingsForm->ShowModal() == mrOk)
{
ClientSocket1->Host = SettingsForm->HostEdit->Text;
NickName = SettingsForm->NickNameEdit->Text;
}
delete SettingsForm;
}
//---------------------------------------------------------------------------
void __fastcall TChatForm::Memo2KeyDown(TObject *Sender, WORD &Key,
TShiftState Shift)
{
// 发送消息!
AnsiString sendtxt="";
if (OutSocket)
{
if (Key == VK_RETURN)
{
if(Multicast->Checked)
{
// 多播格式: Multicast$user1/user2/.../usern*信息正文
//添加标记"Multicast$"
sendtxt+="Multicast$";
//添加信息头!
sendtxt+=UserList;
//替换用户序列尾部的"/"为"*"
sendtxt=sendtxt.SubString(1,sendtxt.Length()-1)+"*";
}
//添加信息正文!
sendtxt+=Memo2->Text;
OutSocket->SendText(sendtxt);
Memo2->Lines->Clear();
Key = 0;
}
}
}
//---------------------------------------------------------------------------
void __fastcall TChatForm::ClientSocket1Connect(TObject *Sender,
TCustomWinSocket *Socket)
{
StatusBar1->SimpleText = "已和服务器建立连接...";
OutSocket = Socket;
AnsiString sendstring = NickName + '\n';
Socket->SendText(sendstring);
}
//---------------------------------------------------------------------------
void __fastcall TChatForm::ClientSocket1Disconnect(TObject *Sender,
TCustomWinSocket *Socket)
{
DisableClient();
}
//---------------------------------------------------------------------------
void __fastcall TChatForm::ClientSocket1Connecting(TObject *Sender,
TCustomWinSocket *Socket)
{
StatusBar1->SimpleText = "正在和服务器建立连接...";
}
//---------------------------------------------------------------------------
void __fastcall TChatForm::ClientSocket1Lookup(TObject *Sender,
TCustomWinSocket *Socket)
{
StatusBar1->SimpleText = "正在寻找服务器...";
}
//---------------------------------------------------------------------------
void __fastcall TChatForm::ClientSocket1Error(TObject *Sender,
TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
StatusBar1->SimpleText = "错误代码为" + IntToStr(ErrorCode);
ShowMessage("套接字错误,代码为" + IntToStr(ErrorCode));
ErrorCode = 0;
DisableClient();
}
//---------------------------------------------------------------------------
void __fastcall TChatForm::ClientSocket1Read(TObject *Sender,
TCustomWinSocket *Socket)
{
//接收信息!
AnsiString rcvtxt,user,userlist;
int pos,i,index;
rcvtxt=Socket->ReceiveText();
StatusBar1->SimpleText = "从服务器上获取数据...";
//从欢迎信息中提取已登录用户,修改UserCheckListBox中的项目
if(rcvtxt.AnsiPos("欢迎登录"))
{
// 添加本机
UserCheckListBox->Items->Add(NickName);
//rcvtxt的格式: xxx,欢迎登录服务器/user1/user2/.../usern*
pos=rcvtxt.Pos("/");
if(!pos) Memo1->Lines->Add(rcvtxt);
else //有后续用户序列
{
//显示欢迎信息
Memo1->Lines->Add(rcvtxt.SubString(1,pos-1));
// 提取已登录用户序列并修改UserCheckListBox中的项目
userlist= rcvtxt.SubString(pos+1,rcvtxt.Length()-pos);
while (userlist.Pos("*"))
{
pos=userlist.Pos("/");
if(pos) //非最后一个
{
user=userlist.SubString(1,pos-1);
UserCheckListBox->Items->Add(user);
userlist=userlist.SubString(pos+1,userlist.Length()-pos);
}
else //最后一个
{
user=userlist.SubString(1,userlist.Length()-1);
UserCheckListBox->Items->Add(user);
userlist="";
}
}
}
// 默认广播模式,故设置checked属性为true
for(int i=0;i<UserCheckListBox->Items->Count;i++)
{
UserCheckListBox->Checked[i]=true;
}
}
// 收到登录和注销信息时修改UserCheckListBox中的项目:
// 注册则添加,注销则删除
else if(rcvtxt.AnsiPos("刚登录"))
{
pos=rcvtxt.AnsiPos("刚登录");
user=rcvtxt.SubString(1,pos-2); //注意汉字位置减2!!
if (user!=NickName) UserCheckListBox->Items->Add(user);
Memo1->Lines->Add(rcvtxt);
// 默认广播模式,故设置checked属性为true
for(int i=0;i<UserCheckListBox->Items->Count;i++)
{
UserCheckListBox->Checked[i]=true;
}
}
else if (rcvtxt.AnsiPos("刚注销"))
{
pos=rcvtxt.AnsiPos("刚注销"); //注意汉字位置减2!!
user=rcvtxt.SubString(1,pos-2);
index=UserCheckListBox->Items->IndexOf(user);
UserCheckListBox->Items->Delete(index);
Memo1->Lines->Add(rcvtxt);
}
else Memo1->Lines->Add(rcvtxt);
}
//---------------------------------------------------------------------------
void TChatForm::EnableClient()
{
CurrentLinkStatus==LS_START;
StatusBar1->SimpleText = "正在进行连接...";
ClientSocket1->Open();
ChatForm->Caption="网络聊天程序-"+NickName;
}
//---------------------------------------------------------------------------
void TChatForm::DisableClient()
{
DefaultSBText();
OutSocket = NULL;
CurrentLinkStatus==LS_STOP;
ClientSocket1->Close();
}
//---------------------------------------------------------------------------
void __fastcall TChatForm::ExitClick(TObject *Sender)
{
if (CurrentLinkStatus==LS_START)
{
DisableClient();
}
Close();
}
//---------------------------------------------------------------------------
void TChatForm::DefaultSBText()
{
StatusBar1->SimpleText = "请选择一模式";
}
//---------------------------------------------------------------------------
void __fastcall TChatForm::UserCheckListBoxClickCheck(TObject *Sender)
{
//动态更改所选用户序列
int i,index;
AnsiString username;
UserList="";
for(i=0;i<UserCheckListBox->Items->Count;i++)
{
if(UserCheckListBox->Checked[i]==true)
{
UserList+=UserCheckListBox->Items->Strings[i];
//single username is divided by "/"
UserList+="/";
}
}
}
//---------------------------------------------------------------------------
void __fastcall TChatForm::BroadcastClick(TObject *Sender)
{
UserCheckListBox->Enabled=false;
for(int i=0;i<UserCheckListBox->Items->Count;i++)
{
UserCheckListBox->Checked[i]=true;
}
}
//---------------------------------------------------------------------------
void __fastcall TChatForm::MulticastClick(TObject *Sender)
{
UserCheckListBox->Enabled=true;
}
//---------------------------------------------------------------------------
void __fastcall TChatForm::ShowHideUserListClick(TObject *Sender)
{
switch(CurrentUserListStatus)
{
case ULS_HIDE:
{
Panel1->Visible=false;
ShowHideUserList->Caption="显示用户列表";
CurrentUserListStatus=ULS_SHOW;
break;
}
case ULS_SHOW:
{
Panel1->Visible=true;
CurrentUserListStatus=ULS_HIDE;
ShowHideUserList->Caption="隐藏用户列表";
break;
}
}
}
//---------------------------------------------------------------------------
//TlistBox 应用实例
/*
This example uses a file listbox and a regular listbox on a form. The following
routine scans through the files listed in the file listbox and lists the sizes of any selected files to the regular list box:
for (int i = 0; i < FileListBox1->Items->Count; i++)
{
if (FileListBox1->Selected[i])
{
if (!FileExists(FileListBox1->Items->Strings[i]))
{
MessageBeep(0);
if (Application->MessageBox(AnsiString("File ") + FileListBox1->
Items->Strings[i] + " not found",NULL, MB_OKCANCEL | MB_DEFBUTTON1) == IDCANCEL)
break;
else
continue;
}
FILE *F = fopen(FileListBox1->Items->Strings[i].c_str(),"r");
struct stat statbuf;
fstat(fileno(F), &statbuf);
ListBox1->Items->Add(IntToStr(statbuf.st_size));
fclose(F);
}
}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -