C ++ Builderを使用して、ローカルネットワークのチャットを作成しています。 クライアント部

良い一日。



これは、チャット用のクライアントの作成について説明する記事の続きです。



ここには2番目の重要なコンポーネントであるグラフィックパーツがあるため、サーバーパーツよりもクライアントパーツにより多くの時間を費やしました。



クライアントのデザインは非常にシンプルで、原始的です。 アプリケーションにメニューバーを作成する意味がわかりませんでした。 フォームには2つのパネルがあり、そのうちの1つは色が変わります。クライアントがサーバーに接続されている場合は緑、それ以外の場合は赤です。 次のパネルはTabControlです。 5つまたは6つのアプリケーション設計オプションを試しましたが、最も便利だったのはTabControlコンポーネントを使用することでした。 ネットワーク上のユーザーの名前はそのタブに入力されます。適切なタブを選択すると、このユーザーとの通信が開始されます(メッセージ履歴も表示されます)。 メッセージはメモコンポーネントに表示されます。メッセージを編集コンポーネントに書き込み、対応するボタンを押すかEnterキーを押して送信する必要があります。



また、クライアントは通知領域へのウィンドウを最小化しました。



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(); } //---------------------------------------------------------------------------
      
      





新しいメッセージが到着すると、心地よい音が再生されます。



ネットワークでのすべての作業については、標準のClientSocketコンポーネントが責任を負います。 クライアントとサーバーは、最初にメッセージを受信すると、最初の4文字がメッセージから分離されます。 次に、次に何をすべきかが決定されます。 すべてがOnReadイベントで発生します。



コード4796は、クライアントがその名前をサーバー上の「登録」に送信する必要があることを意味します。



7788は最も重要なコードの1つであり、着信メッセージの先頭に配置されます。 これにより、送信者の名前とメッセージ自体が分離されます。 次に、クライアントウィンドウのステータスを確認します。 メッセージ送信者のダイアログでタブが開かれた場合、メッセージは新しいメモ行に追加され、メッセージの到着時に追加されます。 別のユーザーとの通信タブが開いている場合、サウンドが再生され、目的のユーザーとのタブで、名前の後に「+1」という碑文が追加されます。 このタブに移動すると、碑文が削除されます。 アプリケーションウィンドウが最小化されている場合、コンテキストメニューがポップアップし、2つのオプションが表示されます。メニューを閉じて通信に進みます。 メニューは、同じ場所(右上隅)のすべてのコンピューターで呼び出されます。 このために、モニターの解像度が決定されます。 いずれの場合も、メッセージと受信時刻がファイルに入力されます。 各ユーザーには独自の通信ファイルがあり、通信履歴はそこから取得されます。



8714-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++; } } }
      
      





構成ファイルは、アプリケーションと同じフォルダーに格納する必要があります(純粋なシンボリック拡張子「.config」で、通常のINIファイルを作成します)。 ファイルには、クライアント名、サーバーIPアドレス、およびアプリケーションバージョンの3行があります。 アプリケーションが起動すると、これらすべてがファイルから抽出され、意図した目的に使用されます。



まとめ



は、職場でチャットしてオフィス内の数十台のコンピューターを接続し、電話での通信を停止したり、オフィスを歩き回ったりすることができる、原始的でありながら実行可能なプログラムを開発できました



たとえば、グラフィックチャットの追加、ファイル転送機能、ボイスチャットなど、将来実装されるアイデアがいくつかありました。 もちろん、これらすべてを2006ビルダーの助けを借りて実現してはなりません。 たとえば、プロジェクトをすでにEmbarcadero RAD Studio XE8に転送しました。ポピーのバージョンは非常に必要でした。



それがすべて、私が書いた最も重要なことだと思います。 この記事が、初心者がC ++ Builderで作業するのに役立つことを本当に願っています。 すべてのソースとプログラム自体はここにあります



PS記事最初の部分は圧縮されていましたが、記事を書く最初の経験が本当に好きでした。 コメント、間違いを訂正します。 ご清聴ありがとうございました!



All Articles