📜 ⬆️ ⬇️

We write chat for the local network using C ++ Builder. Client part

Good day.

This is a continuation of the article , in which I will talk about creating a client for my chat.

I spent much more time for the client part of the server, since there is a second important component here - the graphic part.

Customer design is very simple, even primitive. I did not see the point in creating a menu bar in the application. There are 2 panels on the form, one of them changes color, if the client is connected to the server it is green, otherwise it is red. The next panel is the TabControl. I tried 5 or 6 variants of the application design, and found the most convenient use of the TabControl component. In its tabs, the names of users who are online are entered; when selecting the appropriate tab, correspondence with this user begins (the message history is also displayed). Messages are displayed in the Memo component, you need to write messages in the Edit component, sending - by pressing the corresponding button or the Enter key.
')
The client also has minimized windows in the notification area.

void __fastcall TFormMain::DrawItem(TMessage& Msg) { IconDrawItem((LPDRAWITEMSTRUCT)Msg.LParam); TForm::Dispatch(&Msg); } //--------------------------------------------------------------------------- void __fastcall TFormMain::MyNotify(TMessage& Msg) { POINT MousePos; switch(Msg.LParam) { case WM_RBUTTONUP: if (GetCursorPos(&MousePos)) { PopupMenu1->PopupComponent = FormMain; SetForegroundWindow(Handle); PopupMenu1->Popup(MousePos.x, MousePos.y); } else Show(); break; case WM_LBUTTONDBLCLK: Show(); break; default: break; } TForm::Dispatch(&Msg); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- bool __fastcall TFormMain::TrayMessage(DWORD dwMessage) { NOTIFYICONDATA tnd; PSTR pszTip; pszTip = TipText(); tnd.cbSize = sizeof(NOTIFYICONDATA); tnd.hWnd = Handle; tnd.uID = IDC_MYICON; tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; tnd.uCallbackMessage = MYWM_NOTIFY; if (dwMessage == NIM_MODIFY) { tnd.hIcon = (HICON)IconHandle(); if (pszTip) lstrcpyn(tnd.szTip, pszTip, sizeof(tnd.szTip)); else tnd.szTip[0] = '\0'; } else { tnd.hIcon = NULL; tnd.szTip[0] = '\0'; } return (Shell_NotifyIcon(dwMessage, &tnd)); } //--------------------------------------------------------------------------- HICON __fastcall TFormMain::IconHandle(void) { return (Image2->Picture->Icon->Handle); } //--------------------------------------------------------------------------- PSTR __fastcall TFormMain::TipText(void) { return ("Office Chat"); } //--------------------------------------------------------------------------- LRESULT IconDrawItem(LPDRAWITEMSTRUCT lpdi) { return 0; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void __fastcall TFormMain::FormDestroy(TObject *Sender) { TrayMessage(NIM_DELETE); } //--------------------------------------------------------------------------- void __fastcall TFormMain::N1Click(TObject *Sender) { Show(); } //--------------------------------------------------------------------------- void __fastcall TFormMain::N2Click(TObject *Sender) { Application->Terminate(); } //--------------------------------------------------------------------------- void __fastcall TFormMain::FormCloseQuery(TObject *Sender, bool &CanClose) { CanClose=false; FormMain->Hide(); } //--------------------------------------------------------------------------- 

When a new message arrives, a pleasant sound is played.

For all work with the network meets the standard component ClientSocket. The client, as well as the server, accepting messages first of all separates the first 4 characters from them. Then it is determined what to do next. Everything happens in the OnRead event.

Code 4796 means that the client should send his name to the "registration" on the server.

7788 - one of the most important codes, it is placed at the beginning of the incoming message. This separates the sender's name and the message itself. Next comes a check on the state of the client window. If the tab with the message sender's dialog is open, the message is simply added to the new Memo line, at the beginning the time of receipt of the message is added. If the tab of correspondence with another user is open, the sound is played and in the tab with the desired user, the inscription "+1" is added after the name. When you go to this tab, the inscription is removed. If the application window is minimized, a context menu pops up with two options: close the menu and go to the correspondence. The menu is called on all computers in the same place - the upper right corner. For this, the monitor resolution is determined. In any case, the message along with the time of receipt is entered in the file. For each user there is a correspondence file, from which the history of correspondence is taken.

8714 - it means it's time to update the list of users in TabControl.

 void __fastcall TForm1::ClientSocketRead(TObject *Sender, TCustomWinSocket *Socket) { AnsiString str=Now().CurrentDateTime(); message=Socket->ReceiveText(); AnsiString recieveText=message; AnsiString Text=recieveText; if(message.SubString(1,4).AnsiCompare("4796")==0) { ClientSocket->Socket->SendText("6141"+myname); } else if(message.SubString(1,4).AnsiCompare("7788")==0) { if(TabControl1->Tabs->operator [](TabControl1->TabIndex).AnsiCompare(message.SubString(5,message.Pos(":")-5))==0) { ListBox->Lines->Add(str+" "+message.SubString(5,message.Length())); file(message.SubString(5,message.Pos(":")-5),message.SubString(message.Pos(":")+1,message.Length()),Now().CurrentDateTime(),"in"); PlaySound("message.wav",0,SND_ASYNC); PopupMenu2->PopupComponent = Form1; PopupMenu2->Popup(GetSystemMetrics(SM_CXSCREEN)-200, 20); } else if(TabControl1->Tabs->operator [](TabControl1->TabIndex).AnsiCompare(message.SubString(5,message.Pos(":")-5))!=0) { PlaySound("message.wav",0,SND_ASYNC); AnsiString im; AnsiString mess; im=message.SubString(5,message.Pos(":")-5); mess=message.SubString(message.Pos(":")+1,message.Length()); file(im,mess,Now().CurrentDateTime(),"in"); AnsiString name=message.SubString(5,message.Pos(":")-5); active=TabControl1->TabIndex; count=TabControl1->Tabs->Count; AnsiString n; TabControl1->Tabs->Clear(); for(int i=0;i<count;i++) { n=m[i]; if(n.AnsiCompare(name)!=0) TabControl1->Tabs->Add(n); else if(n.AnsiCompare(name)==0) TabControl1->Tabs->Add(n+"+1"); } } } else if(message.SubString(1,4).AnsiCompare("8714")==0) { TabControl1->Tabs->Clear(); AnsiString str=message.SubString(5,message.Length()); const char separator[]=","; int i=0; char *Ptr=NULL; Ptr=strtok(str.c_str(),separator); while (Ptr) { //if(myname.AnsiCompare(Ptr)!=0) TabControl1->Tabs->Add(Ptr); strcpy(m[i],Ptr); Ptr=strtok(0,separator); i++; } } } 

A configuration file must be stored in the same folder with the application (with a purely symbolic extension ".config", then I will do a normal INI file). There are three lines in the file: client name, server ip-address and application version. When you run the application, all this is extracted from the files and used for its intended purpose.

Total


I managed to develop a primitive, but still very workable program that allows you to chat in the workplace to connect dozens of computers in the office and stop communicating using phone calls or even more walking around the office.

I have some ideas that will be implemented in the future, for example, adding a graphic chat, the ability to transfer files, maybe voice chat. All this, of course, must be realized not with the help of the 2006 builder. The project, for example, I have already transferred to Embarcadero RAD Studio XE8, I really needed a version for Mac.

On this I think everything, the most important thing I wrote. I really hope that this article will be useful for beginners working in C ++ Builder. All source code and the program itself is here .

PS The first part of the article was zaminusovali, but I really liked the first experience of writing articles. Comment, I will correct my mistakes. Thank you for your attention!

Source: https://habr.com/ru/post/259655/


All Articles