Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Microsoft Visual C++ .NET Professional Projects - Premier Press

.pdf
Скачиваний:
180
Добавлен:
24.05.2014
Размер:
26 Мб
Скачать
☆

860

Project 10 NETWORKING AND REMOTING IN VC++.NET

 

 

 

 

 

{

 

 

 

 

 

 

 

 

 

 

 

 

 

m_pListBox->Items->Add(pstrData);

 

 

 

 

 

}

 

 

 

 

}

 

 

 

 

 

 

}

 

 

 

 

 

 

m_pListBox->Items->Add(S”Listener thread finished...”);

 

 

 

return;

 

 

Y

 

}

 

 

 

 

 

 

 

 

 

};

 

 

 

F

 

 

 

 

 

 

The following code creates a user interface for the chat application. The form

 

 

 

 

 

M

 

 

window and the controls, such as a text box, a list box, and command buttons, will

 

be coded in the ChatAppW.cpp file as shownLin the following code snippet:

 

 

 

E

 

 

// This is the main project file for VC++ application project

 

 

 

T

 

 

 

// generated using an Application Wizard.

 

 

#pragma once

 

A

 

 

#include “stdafx.h”

 

 

 

 

#include “Chat.h”

 

 

 

 

//Chat window class

 

 

 

 

__gc class CChatForm : public Form

 

 

{

 

 

 

 

 

 

private:

 

 

 

 

 

 

String *pCaption;

// Caption of the CChatForm

 

 

int

nWidth;

// Width of the CChatForm

 

 

int

nHeight;

// height of the CChatForm

// Pointers to different controls declared TextBox *pTxtMessage;

Label *pLblMessage;

Label *pLblLoggedOnUser;

ListBox* pLstBoxMessage;

ListBox* pchkdLstBoxUserList;

Button *pBtnSend;

Button *pBtnSave;

Team-Fly®

IMPLEMENTING NETWORKING

Chapter 29

861

 

 

 

 

Button *pBtnExit;

CChat* pChat;

//Thread variable declared Thread* pChatThread; bool bThreadStarted; Encoding* pASCII;

public:

CChatForm()

{

pCaption = “Chat Dialog”; nWidth = 500;

nHeight = 255; bThreadStarted = false;

//Prepare the Chat form InitForm();

pChat = new CChat(pLstBoxMessage, pchkdLstBoxUserList);

}

void ~CChatForm()

{

// Form is being destroyed. Do any necessary cleanup here. Form::Dispose();

}

In the preceding code, the class CChatForm is the user-defined class derived from the Form class. The pChatThread is an object of thread class. The variable pASCII variable is used to handle the encoding and decoding of data passing on network.

In the constructor, CChatForm(), the caption of the form is set to Chat Dialog, the width is set to 500, and the height is set to 255.

Now take a look at initializing the controls and placing them on the form in the code, as indicated in the following code:

void InitForm()

{

// Basic WinForm Settings

Text = pCaption;

862 Project 10 NETWORKING AND REMOTING IN VC++.NET

Size = Drawing::Size(nWidth, nHeight); set_MaximizeBox(false);

pTxtMessage = new TextBox(); pTxtMessage->Name=”Edit_message”; pTxtMessage->Size = Drawing::Size(280, 20); pTxtMessage->TabIndex = 0;

pTxtMessage->Location = Drawing::Point(10, 195); pLstBoxMessage = new ListBox(); pLstBoxMessage->Name=”ListBox_message”; pLstBoxMessage->TabIndex = 1; pLstBoxMessage->set_HorizontalScrollbar(true); pLstBoxMessage->Location = Drawing::Point(10, 10); pLstBoxMessage->Size = Drawing::Size(350, 160); pLstBoxMessage->Enabled = false; pchkdLstBoxUserList = new ListBox();

pchkdLstBoxUserList->Name=”CheckedListBox_UserList”; pchkdLstBoxUserList->set_HorizontalScrollbar(true); pchkdLstBoxUserList->TabIndex = 2; pchkdLstBoxUserList->Location = Drawing::Point(380, 30); pchkdLstBoxUserList->Size = Drawing::Size(100, 140); pchkdLstBoxUserList->Enabled = false;

pLblLoggedOnUser = new Label(); pLblLoggedOnUser->Text=”Logged on Users:”; pLblLoggedOnUser->Size = Drawing::Size(100, 20); pLblLoggedOnUser->Location = Drawing::Point(380, 10); pLblMessage = new Label();

pLblMessage->Text=”Type the message here:”; pLblMessage->Size = Drawing::Size(150, 20); pLblMessage->Location = Drawing::Point(10, 175); pBtnSend = new Button();

pBtnSend->Text = “Se&nd”; pBtnSend->Size = Drawing::Size(55, 20); pBtnSend->TabIndex = 3;

pBtnSend->Location = Drawing::Point(300, 195); pBtnSend->Click += (new EventHandler(this,

IMPLEMENTING NETWORKING

Chapter 29

863

 

 

 

 

&CChatForm::OnSendButtonClick)); pBtnSave = new Button(); pBtnSave->Text = “&Save”;

pBtnSave->Size = Drawing::Size(55, 20); pBtnSave->TabIndex = 4;

pBtnSave->Location = Drawing::Point(362, 195); pBtnSave->Click += (new EventHandler(this,

&CChatForm::OnSaveButtonClick)); pBtnExit = new Button(); pBtnExit->Text = “E&xit”;

pBtnExit->Size = Drawing::Size(55, 20); pBtnExit->TabIndex = 5;

pBtnExit->Location = Drawing::Point(425, 195); pBtnExit->Click += (new EventHandler(this,

&CChatForm::OnExitButtonClick)); Controls->Add(pTxtMessage); Controls->Add(pLblMessage); Controls->Add(pLblLoggedOnUser); Controls->Add(pLstBoxMessage); Controls->Add(pchkdLstBoxUserList); Controls->Add(pBtnSend); Controls->Add(pBtnSave); Controls->Add(pBtnExit);

//Set the pBtnSend as the default Form::set_AcceptButton(pBtnSend);

//Initialize the Chat session pChat->Initialize();

}

The initialization of the form and controls is done in the initForm() method. To set the caption and size of the form, initialize the Text and Size properties.

You also need to initialize the required property of the controls to place them on the form. Table 29-6 lists the different properties of the controls that are set in the code.

864

Project 10 NETWORKING AND REMOTING IN VC++.NET

 

 

 

 

 

 

Table 29-6 Properties of the Controls

 

 

 

 

 

 

 

Property

Description

 

 

 

 

 

 

 

Name

Sets the name to the control.

 

 

Text

Sets the constant text to be displayed in the control.

 

 

Size

Sets the size of the control. It takes the width and height of the

 

 

 

 

control.

 

 

Tabindex

Sets the tab stop of the control.

 

 

HorizontalScrollbar

Enables you to display the horizontal scroll bar.

 

 

Location

Enables you to specify the location on the form where the control

 

 

 

 

should be displayed.

 

 

 

 

 

Apart from the properties discussed in Table 29-6, you need to set the click property for buttons. The Click property will enable the button control to handle the Click event.

Once you have set the properties, add the controls by using the Add method of the

Controls class.

Next, you will start coding for the buttons that appear on the form. You can write the code for these methods in any sequence. To begin with, take a look at the code for the Exit button. This code will be executed when the user clicks on the Exit button.

//Handles the Exit button

void OnExitButtonClick (Object *sender, EventArgs *e)

{

if ( bThreadStarted && (pChatThread != NULL) )

{

CChat::m_bDone = true;

//Notify the listener, User is closing the app String* pStrMsg;

pStrMsg = S”:@”;

Byte bytearrayBuffer [] = new Byte[pStrMsg->Length + 1]; int nLen = pASCII->GetBytes( pStrMsg->ToCharArray(), 0,

pStrMsg->Length, bytearrayBuffer, 0);

IMPLEMENTING NETWORKING

Chapter 29

865

 

 

 

 

int nECode = CChat::m_pClient->Send(bytearrayBuffer, 2, pChat-

>GetRemoteEP());

//Raises a ThreadAbortException in the thread from within which it is invoked, //to begin the process of terminating the thread.

pChatThread->Abort();

//Blocks the calling thread until a thread terminates pChatThread->Join();

//Show the message in the list box

pLstBoxMessage->Items->Add(S”Thank you for using My Chat App !!!”);

pLstBoxMessage->Refresh();

//Terminate the Chat Session pChat->Terminate(); Thread::Sleep(2000);

}

Close();

}

In the preceding code, you delete all the objects, terminate the thread, and close the form.

Next, let me explain the code for the Save button. When the user clicks on the Save button, the items appearing in the list box need to be saved in the file specified by the user in the Save dialog box. Following is the code written in the Click event of the Save button:

void OnSaveButtonClick (Object *sender, EventArgs *e)

{

//Code here for saving the chat content

int nCount = pLstBoxMessage->Items->Count; String *pStrMessage, *pStrTemp;

for (int i=0; i < nCount; i++)

{

pStrTemp = pLstBoxMessage->Items->get_Item(i)->ToString(); pStrMessage = String::Concat(pStrMessage, S”\n”, pStrTemp);

}

866 Project 10 NETWORKING AND REMOTING IN VC++.NET

//Save pStrItem in a file

SaveFileDialog* pFileDlg = new SaveFileDialog(); pFileDlg->DefaultExt = “txt”;

pFileDlg->Filter = “txt files (*.txt)|*.txt|All files (*.*)|*.*”; pFileDlg->FilterIndex = 2;

pFileDlg->RestoreDirectory = true;

if (pFileDlg->ShowDialog() == DialogResult::OK)

{

Stream *pStream;

if((pStream = pFileDlg->OpenFile()) != NULL)

{

Byte bytearrayBuffer [] = new Byte[pStrMessage->Length + 1]; int nLen = pASCII->GetBytes( pStrMessage->ToCharArray(), 0,

pStrMessage->Length, bytearrayBuffer, 0);

pStream->Write(bytearrayBuffer, 0, pStrMessage->Length); pStream->Close();

}

}

}

In the preceding code, the variable nCount stores the count of items in the list box. The get_Item() method is used to get the values from the list box and store them in the temporary String variable pStrTemp. Once you get the values, concatenate these values using the Concat() method of the String class and store the concatenated string in the pStrMessage variable.

The SaveFileDialog object is declared to invoke the Save dialog box.

The DefaultExt property is set to specify the default extension for the file that the user saves.

The Filter property is used to set the list of extensions that will appear in the Save as type list box in the Save dialog box. The FilterIndex property is used to specify the default value that will be displayed in the Save as type list box.

After you have set the properties of the Save dialog box, you need to write the code for storing the contents of the list box in the file using the Stream class object.

To store the contents to the Stream object, you will first create a byte array bytearrayBuffer. Then, you will transfer the contents of the SUtring variable

pStrMUessage to bytearUrayBuffer by using the GetByte() method.

IMPLEMENTING NETWORKING

Chapter 29

867

 

 

 

 

Once the contents are stored in the byte array, write the contents to the Stream object using the Write() method and close the stream.

The following code adds the functionality to the Send button, which is used to broadcast the messages sent by a user to all the users that are currently logged in:

void OnSendButtonClick (Object *sender, EventArgs *e)

{

//Handles the Send button if (!bThreadStarted)

{

pChatThread = new Thread(new ThreadStart(0, CChat::Listener));

//Start the thread

pChatThread->Start(); pASCII = Encoding::ASCII; bThreadStarted = true;

}

//Get the text from the message window and send it to active user String* pStrTemp = pTxtMessage->Text;

String* pStrMsg = pStrTemp->Trim(); if (pStrMsg->Length == 0)

{

//Nothing to send return;

}

else

{

//Format the user typed message

String* pHostName = pChat->GetChatHostName(); int nItemIndex = pchkdLstBoxUserList-

>FindStringExact(pHostName);

if (nItemIndex == ListBox::NoMatches)

{

pchkdLstBoxUserList->Items->Add(pHostName);

}

pStrMsg = String::Concat(pChat->GetChatHostName(), S”:”,

pStrMsg);

868 Project 10 NETWORKING AND REMOTING IN VC++.NET

}

Byte bytearrayBuffer [] = new Byte[pStrMsg->Length + 1];

//Send data to remote peer

int nLen = pASCII->GetBytes( pStrMsg->ToCharArray(), 0, pStrMsg- >Length, bytearrayBuffer, 0);

int nECode = CChat::m_pClient->Send(bytearrayBuffer, nLen, pChat- >GetRemoteEP());

if(nECode <= 0)

{

String* pStr;

pStr = String::Format(“Error in send : {0}”,

nECode.ToString());

pLstBoxMessage->Items->Add(pStr);

}

//Empty the Edit window pTxtMessage->Text = “”; pTxtMessage->Focus();

}

};

After you have completed all the preceding coding, you need to instantiate the CChatForm for running the application. You will write this code in the main method, as shown in the following code snippet:

//This is the entry point for this application int _tmain(void)

{

Application::Run(new CChatForm()); return 0;

}

After coding the complete application, try executing it.

IMPLEMENTING NETWORKING

Chapter 29

869

 

 

 

 

Summary

This chapter introduced you to network programming. You learned that you can create a network application based on sockets. You were introduced to the Socket class and the related methods of the class (including namespaces). Another important concept that you learned is that of threads. You saw the functionality of the Thread class and its various methods.

Finally, you created an application that illustrates the implementation of sockets and threads.