⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chatclient.cpp

📁 关于书籍《Borland c++Builder工程实践》的源代码
💻 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 + -