- Sacramento

advertisement
VIDEO CHAT ON LAN
Payal Dalwadi
B.E., Dharmsinh Desai University, Gujarat, India, 2006
PROJECT
Submitted in partial satisfaction of
the requirements for the degree of
MASTER OF SCIENCE
in
COMPUTER SCIENCE
at
CALIFORNIA STATE UNIVERSITY, SACRAMENTO
FALL
2010
VIDEO CHAT ON LAN
A Project
by
Payal Dalwadi
Approved by:
__________________________________, Committee Chair
Chung-E Wang, Ph.D.
__________________________________, Second Reader
Isaac Ghansah, Ph.D.
____________________________
Date
ii
Student:
Payal Dalwadi
I certify that this student has met the requirements for format contained in the University
format manual, and that this project is suitable for shelving in the Library and credit is to
be awarded for the Project.
__________________________, Graduate Coordinator
Nikrouz Faroughi, Ph.D.
Department of Computer Science
iii
________________
Date
Abstract
of
VIDEO CHAT ON LAN
by
Payal Dalwadi
This project is an implementation of a software application to provide real-time video
chat experience for a user on a local area network (LAN). Generally, chat applications
require their users to create detailed profiles before starting to use the application. This
can be time consuming as well as a potential hazard to privacy. This application
overcomes these problems by significantly reducing the time needed to start using it, as
the only information needed from the users is the IP address of the recipient. Users can
send instant messages and share live web cam data with other users. The application also
provides a feature to add and remove people from their contact list. The present design
confines its operation within the limits of a local area network, but the possibilities are
open for operation in extended networks or the Internet.
The application is implemented by using VC++.NET. Communication between two
systems is established by windows socket API (WinSock2).
_______________________, Committee Chair
Chung-E Wang, Ph.D.
______________________
Date
iv
ACKNOWLEDGEMENT
It was a wonderful time I spent in Sacramento while getting my Master’s degree, and I
have many people to thank for it.
First and foremost, I would like to thank my project advisor Dr. Chunge-E Wang for
helping me and guiding me through the project. His dedication and energy have always
inspired me. In future also it will continue to inspire me. Thank you, Professor for
everything. Also, I would like to thank Dr. Isaac Ghansah for providing me his support in
completion of my project. I am thankful to former Graduate Coordinator, Dr. Cui Zhang
for her support and guidance throughout my masters. I am also thankful to Dr. Nikrouz
Faroughi for his support. I would like to express my honor to all the faculty members of
computer science, for adding to this experience.
I would like to thank all my friends including Kamlesh, Mantej, Mruga and Dhvani, for
making my entire study memorable. Finally, and most importantly, I would like to thank
my family for never giving up on me. Thanks a lot Mom and Dad, for always being there
for me.
v
TABLE OF CONTENTS
Page
Acknowledgement………………………………………………………………………...v
List of Tables…………………………………………………………………………...viii
List of Figures…………………………………………………….…………………….ix
Chapter
1. INTRODUCTION…………………………………………………………………….1
1.1 Project Objective………………………….…………..…………………………..2
1.2 Project Plan………………………………………………………………………..2
1.3 Future Work……………………………………………………….…………...….3
2. TECHNOLOGY USED FOR APPLICATION……………………………………….5
2.1 Introduction to .NET Framework……………………….………………………...5
2.2 Component of .NET………………………………………………….……………6
2.3 Microsoft Foundation Class Library…………………………….………………..6
2.4 Features of VC++.NET 2005………………………………………………..…….9
2.5 Socket…………………………………………………………………………….12
2.6 Windows Socket in MFC………………………………………………………...16
2.6.1 WinSock2 Architecture…………………………………………………….17
3. PROJECT IMPLEMENTATION………..………………………………………….21
3.1 Project Layout……………………………………………………………………21
3.1.1 Implementation of Features………………………………………………..21
vi
3.1.2 Establish Connection Using Socket………………………………………..31
3.1.3 Capturing Webcam Driver………………………….……………………..35
4. CONCLUSION AND FUTURE WORK……………………………………………39
Appendix…………………………………………………………………………………40
References………………………………………………………………………………..96
vii
LIST OF TABLES
Page
1. Table 3.1.1.1 Classes used by video chat on LAN…………………..………………30
2. Table 3.1.1.2 Functions used by video chat on LAN……………………….……….30
3. Table 3.1.3.1 Macros used by video chat on LAN…………………………………..36
viii
LIST OF FIGURES
Page
1. Figure 2.3.1 MFC document/view interface…………………………………………..7
2. Figure 2.5.1 Communication using socket.………………………………..………..13
3. Figure 2.6.1.1 WinSock2 architecture…………………………………………….…19
4. Figure 3.1.1.1 Main window of application………………………………………….22
5. Figure 3.1.1.2 Add contact in contact list……………………………………………23
6. Figure 3.1.1.3 Connection accepted by user…………………………………………24
7. Figure 3.1.1.4 Sending text data……………………………………………………..25
8. Figure 3.1.1.5 Initialization of webcam……………………………………………...26
9. Figure 3.1.1.6 Invitation to view webcam…………………………………………...27
10. Figure 3.1.1.7 Request to view webcam……………………………………………..28
11. Figure 3.1.1.8 Disconnection of webcam……………………………………………29
12. Figure 3.1.2.1 Communication between two system………………………………...33
13. Figure 3.1.2.2 Dialog data exchange………………………………………………...34
ix
1
Chapter 1
INTRODUCTION
The Internet has enhanced the ways in which people communicate. Emails and instant
messaging have replaced traditional means of contact. Text and video conferencing have
gained popularity as they allow instantaneous human friendly communication. Save and
edit contacts, storage of conversations and other user information are some common
features in these applications. Many of these chat applications are based on server-client
architecture. A centralized server is used to maintain all the information necessary to
authenticate the user and relay data or connection information between users. Most of the
chat applications existing today require user created profiles containing personal
information before being able to chat. All this information is stored on a server. This
method of connecting users leads to the server being a store-house of personal
information. Such a system has many potential disadvantages. It creates a performance
bottle-neck as vast amounts of data must be processed by server. Connectivity issues
between the clients and the server can interrupt connections between users that could
otherwise be avoided. Thus, we need a chat application that overcomes these drawbacks;
one which can work without the complications of having a centralized server.
2
1.1 Project Objective
The objective of this project is to implement video chat on LAN using Microsoft
Foundation Class Library. MFC library wraps portion of Windows API in C++ classes. It
provides functionality that enables C++ classes to use a default application framework.
Once the frame work is able to do video chat on LAN, the project can be extended in
future for developing audio chat as well. Two users are able to chat by entering each
others’ IP addresses. Users can easily add and delete contacts from their contact list.
Users can accept and reject invitations or requests of video chat. Since the only form of
authentication is enabling the recipient to accept chat request, this application is not very
secure to use on the Internet. But, this application is intended to be used inside a LAN
where users are known and trusted.
1.2 Project Plan
The first step is to list out the features that define the application, as listed below, and
implement those features. This process is explained in more detail in chapter 3 of this
report.

Simple connection interface using entered IP or one stored in a list.

Easy to use webcam controls consisting of stop, start, invite, and request.
3

Independent webcam and text chat controls.
The next step involves creating sockets which are used to establish connection. Three
types of sockets are created: DATA (text), VIDEO (video) and CONTROLMESGS (for
control messages like ‘stop webcam’, ‘request to view webcam’, and other webcam
functions).
To implement the webcam capture driver module, MFC library functions and macros are
used. Implemented functions includes connect, capture, stop, and disconnect webcam
driver.
1.3 Future Work
Chapter 4 gives the direction for further research and development for the project. Some
of the possible improvements are as follows:
1. Add IP discovery module.

Right now this application needs to add IP address manually to initiate chat.
To solve this problem, a module can be added to the application which can
perform IP discovery and list IP address in a LAN with associated hostnames.
2. Add features such as audio and send file.
4

This application only provides the feature to perform real-time streaming of
video and text. It does not have the features to send files or audio chat. To
make this application better, modules can be added which provide audio and
send file feature.
3. Use TCP instead of UDP as the underlying transport layer protocol.

To improve video chat and to make connections reliable, create TCP
connections between the sender and the recipient.
5
Chapter 2
TECHNOLOGY USED FOR APPLICATION
In this chapter, the technology used to implement the project is discussed in detail. Video
chat on LAN is a Windows based application. The front-end and the back-end are
implemented using Visual Studio .NET 2005 (VC++). Visual Studio allows the usage of
MFC classes and macros, which are used to initialize, connect and disconnect the drivers
for the web-cam, and to capture the web-cam image. This application uses Windows
socket API (winsock) to establish a connection between two systems.
2.1 Introduction to .NET Framework
The .NET Framework is Microsoft's comprehensive and consistent programming model
for building applications that have visually stunning user experiences, seamless and
secure communication, and many more features. The .NET framework provides a large
library of classes. Framework supports multiple programming languages. It supports both
windows and web applications.
6
2.2 Components of .NET
.NET framework consists of two components: Common Language Runtime and .NET
class library.
Common Language Runtime (CLR) - The Common Language Runtime (CLR) is the
environment where all programs in .NET are run. Memory management and thread
management is done by CLR. Programs that run in the CLR need not manage memory, as
it is completely taken care of by the CLR. For example, when a program needs a block of
memory, CLR provides the block and releases the block when program is done.
.NET class library - .NET comes with thousands of classes to perform all important and
not-so-important operations. Library is completely object-oriented, providing more than
a thousand classes to utilize.
Video chat on LAN uses VC++.NET and MFC. Once the coding is done, building the
application with active solution configuration and active solution platform creates a
single executable.
2.3 Microsoft Foundation Class Library
MFC classes and multimedia macros are used for GUI elements and driver interface.
7
Microsoft Foundation Class Library (MFC) is a library that wraps a portion of the
Windows API in C++ classes. It also includes functionality that enables MFC to use a
default allocation framework. MFC application generates C++ source files, resource files,
header files, and a project files. The MFC Reference usually does not describe inherited
member functions or inherited operators.
A standard Visual C++ program based on the MFC Document/View interface is made up
of five main parts:
 The Application Object — our Windows program itself
 The Main Frame Window Object — our main window
 The Document Object — handles our data
 The View Object — handles data display
 The Document Template
Figure 2.3.1 MFC document/view interface [13]
8
 The application object is an instance of the CRealtorApp class. InitInstance()
method is called within the built-in and implicit WinMain() function and this
object runs first. Main window appears on the screen once this object is started
and it also starts passing Windows messages to main window.
 The main window object displays the main tool bars for the application. It maps
the menu bar, the title bar of the window, and the tool bar. The main window
object is an instance of the class CMainFrame. This object deals with graphics
like drawing, text and other graphics on the window. The area on which the main
window object displays data is called the client area in a window; for example,
drawing a line in MS Paint appears in the MS paint’s client area. The client area is
handled by the view object [13].
 The view object handles the client area. The formation and display of data take
place here. For example, the text editing for a word processing program is
handled by the view object. In fact, the view object is really a window itself that
appears on top of the client area. The document object stores the data which is
displayed in the view object.
 The document object is used by program to store the data. Visual C++ makes it
easier by allowing all that data in the document object to store and then handle the
display of the data that fits into the client area in the view object. That implies,
several different views can be open in the same document at once like MDI
application.
9
 The document template is created in the InitInstance() function of the application
object and this is how the program connects the other three classes — the
document, main frame window, and view classes — to the program itself.
The CSingleDocTemplate object is found if it is SDI application or the
CMultiDocTemplate object found if it is MDI application.
2.4 Features of VC++.NET 2005
This section gives a brief overview of main features of VC++.NET as listed below:

Powerful Windows-based Applications
Visual C++ .NET comes with features such as a powerful new forms designer, an inplace menu editor, and automatic control anchoring and docking. Visual C++.NET
delivers new productivity features for building more robust applications easily and
quickly. With an improved integrated development environment (IDE) and a significantly
reduced startup time, Visual C++ .NET offers fast, automatic formatting of code,
improved IntelliSense, an enhanced object browser and XML designer, and much more.
10

Powerful, Flexible, Simplified Data Access
The data access can be tackled easily with SQL server data reader and SQL connection.
The flexibility of SQL connection enables data binding to any database, as well as
classes, collections, and arrays, and provides true XML representation of data. Seamless
access to SQL enables simple data access for connected data binding scenarios. Using
SQL connection, any .NET programming language can gain high-speed access to MS
SQL Server, Oracle, DB2, Microsoft Access, and more.

Direct Access to the Platform
Visual C++ developers can have full access to the capabilities available in .NET
Framework 1.1. Developers can easily program system services including the event log,
performance counters and file system. The new Windows Service project template
enables to build real Microsoft Windows NT Services [10].

ISO/ANSI C++ Standard Compliance
It provides most standards-compliant C++ compiler which can run on any platform today.
Also, it provides new features including Partial Template Specialization, Partial
Ordering, Member Template Definitions, and much more [9].
11

Performance Optimizations
Microsoft has significantly enhanced optimization performance with two new compiler
options,
 The first complier options is the /G7 flag. Code optimization is done by
complier for the Intel Pentium 4 and AMD Athlon processors using this flag. The
numbers can vary when recompilation of the code is done with /G7. Recompiling
with this flag will not produce code that only executes on the Intel Pentium 4 or
AMD Athlon, but the code produced may have a minor performance penalty on
older generations of these processors [9][12].
 The second complier option is /arch: [argument], where the argument is
either SSE or SSE2. Streaming SIMD Extensions (SSE) and Streaming SIMD
Extensions 2 (SSE2_) instructions, as well as other instructions that support SSE
or SSE2 are used by the complier using this option[9][12].

Security Enhancements
There are well known problems for C and C++ programs and they are Buffer overruns. It
occurs due to unmanaged code which does not perform array bounds checking or typesafety checking. C++ gives an advantage for certain classes of applications. The
downside is that buffer overruns become security holes and opportunities for several
12
kinds of security attacks. To overcome this problem, Microsoft has added
the /GS compiler option [9].

Managed C++ Windows Forms Designer
Last, but certainly not least, it also provides support for creating Windows forms in the
managed C++ language. The main benefit is of drag-and-drop placement and layout
capabilities using different tools. Users do not have to write code for each small tool, it is
generated by .NET.
2.5 Socket
Socket functionality, and an overview of WinSock2 are discussed in this section. Sockets
are a protocol independent method of creating a connection between processes.
A socket is an interface between the transport layer and the application layer.
13
Application
Application
Sockets
Transport
Transport
Network
Network
Data Link
Data Link
Physical
Physical
Figure 2.5.1 Communication using socket
To use a socket, a program has to provide socket type and address domain. Any two
processes can communicate with each other if their sockets are in the same domain and of
the same type [11].

Socket domain
There are two widely used address domains. Each of these domains has its own address
format.
 UNIX domain - Two processes which share a common file system can
communicate. UNIX domain provides network transparency. With UNIX domain
sockets, the credential of the process can be retrieved that creates the remote
14
socket, and use that for access control also, which can be quite convenient on
multi-user systems. The address of a socket in the UNIX domain is a character
string which is basically an entry in the file system. UNIX domain sockets have
explicit knowledge that they are being executed on the same system. They avoid
the extra context switch through the software interrupt ‘NETISR’ [11], and a
sending thread writes the traffic stream or the datagrams directly into the
receiving socket buffer. No checksums are calculated, no headers are inserted, no
routing is performed, etc. Because they have access to the remote socket buffer,
they can also directly provide feedback to the sender when it is filling, or more
importantly, emptying, rather than having the added overhead of explicit
acknowledgement and window changes.
The one piece of functionality that
UNIX domain sockets don't provide that TCP does is out-of-band data [10].
 Internet domain – Two processes running on two different hosts on the
Internet can communicate. It uses TCP/IP Internet protocol suit. The address of a
socket in the Internet domain consists of the Internet address of the host machine.
In addition, each socket needs a port number on that host. Port numbers are 16 bit
unsigned integers.

Socket Types
Socket types define the communication properties visible to the application. Processes
communicate only between sockets of the same type. There are different types of socket.
15
However, there are two socket types are widely used – stream sockets, and datagram
sockets.
 A stream socket - Stream sockets treat communications as a continuous
stream of characters. It uses Transmission Control Protocol (TCP). It provides
two-way, sequenced, reliable, and unduplicated flow of data with no record
boundaries. A stream operates much like a telephone conversation [11]. The
socket type is SOCK_STREAM.
 A datagram socket - Datagram sockets reads entire messages at once. It uses
User Datagram Protocol (UDP). It provides a two-way flow of messages.
Datagram socket may receive messages in a different order from the sequence in
which the messages were sent [11]. Record boundaries in the data are preserved.
The socket type is SOCK_DGRAM.
 A sequential packet socket – It provides a two-way, sequenced, reliable,
connection, for datagrams of a fixed maximum length. The socket type is
SOCK_SEQPACKET.
No protocol for this type has been implemented for any
protocol family [11].
 A raw socket - provides access to the underlying communication protocols
[11].
16
2.6 Windows Socket in MFC
Windows Sockets 2 is designed for use by C/C++ programmers. Windows Sockets 2 can
be used on all Windows platforms.WinSock2 provides a powerful and flexible API for
creating universal TCP/IP applications. Windows Sockets version 2.0 (WinSock 2)
formalizes the API for a number of other protocol suites like ATM, IPX/SPX, and
DECnet and it allows them to coexist simultaneously [9].
Here is a list of the new features that WinSock 2 provides [9].
 Multiple Protocol support: WOSA architecture enable service providers to
offer "plug-in" and "pile-on" features.
 Transport Protocol Independence: Choose the transport protocol depending on
the services provided.
 Multiple Namespaces: Allows used to select the protocol to resolve
hostnames, or locate services.
 Scatter and Gather: Provided features like receive and send, to and from
multiple buffers.
 Overlapped I/O and Event Objects: Enhanced throughput can be achieved by
utilizing Win32 paradigms.
 Quality of Service: It helps to negotiate and keep track of bandwidth per
socket.
17
 Multipoint and Multicast: This feature is Protocol independent APIs and
protocol specific APIs.
 Conditional Acceptance: Before connection is made it can reject or defer a
connect request.
 Connect and Disconnect data: This feature supports for transport protocols.
 Socket Sharing: Socket handler can be shared by two or more processes
 Vendor IDs and a mechanism for vendor extensions: This feature allows
adding Vendor specific APIs.
 Layered Service Providers: Service can be added to existing transport
providers using this feature.
2.6.1 WinSock 2 Architecture
WinSock2 API is used to implement socket in the application. This section gives brief
overview of WinSock2.
WinSock 2 has an all-new architecture that provides much more flexibility. The WinSock
2 architecture allows for simultaneous support of multiple protocol stacks, interfaces, and
service providers. Flexibility is added because there is a one DLL on the top and another
layer below, and standard service provider interface. WinSock 2 adopts the Windows
Open Systems Architecture (WOSA) model, which separates the API from the protocol
18
service provider. In this model the WinSock DLL provides the standard API, and each
vendor installs its own service provider layer underneath. The API layer "talks" to a
service provider via a standardized Service Provider Interface (SPI), and it is capable of
multiplexing between multiple service providers simultaneously [9].
WinSock 2 specification has two distinct parts: the API for application developers and
the SPI for protocol stack and namespace service providers. There is also an intermediate
DLL layers which are independent of both the application developers and service
providers. These DLLs are provided and maintained by Microsoft and Intel. Layered
Service Provider comes on the top of a transport service provider [9].
19
The following figure illustrates the WinSock 2 architecture.
+---------------+ +-----------------++-----------------+
|
WinSock 2
| | 16-bit WinSock || 32-bit WinSock |
| Application | | 1.1 Application || 1.1 Application |
+---------------+ +-----------------++-----------------+
|
|
|
|
+-----------------++-----------------+
WinSock
|
|
WINSOCK.DLL
|| WSSOCK32.DLL
|
API
|
|
(16-bit)
||
(32-bit)
|
|
+-----------------++-----------------+
|
|
+-------------------------------------------------------+
WinSock
|
WS2-32.DLL (32-bit)
|
API
+-------------------------------------------------------+
|
+-------------------------------------------------------+
WinSock
|+-----------++--------------++------------++----------+|
SPI
|| TCP/IP
|| TCP/IP-based || additional ||Layered SP||
|| transport ||
namespace ||
service |+----------+|
|| service || service pro- || providers |+----------+|
|| provider || vider (DNS) || (SPX, etc.)|| Any TSP ||
|+-----------++--------------++------------++----------+|
+-------------------------------------------------------+
<-1.1
<-2.0
<--2.0
/
/
<--
Figure 2.6.1.1 WinSock2 Architecture [9]
MFC Provides two models for Windows socket programming.
 CAsyncSocket – Encapsulation of the Windows sockets API is done by this class.
This class converts notification of network events messages in to callback
functions.
 CSocket – It is derived form class CAsyncSocket. This class inherits many
member functions from CAsyncSocket that encapsulate Windows sockets APIs.
20
Synchronous operation is important so bloking is done by CSocket. It manages
aspects of communication using either API or class CAsyncSocket.
21
Chapter 3
PROJECT IMPLEMENTATION
This chapter is aimed to provide users with guidance on how the features provided by the
application are implemented, and to describe many details of the framework of video on
LAN application. Video chat on LAN is an application that is used for chatting within a
LAN. The following subjects are addressed in this chapter:

The overall architecture of application.

List of classes and macros.
3.1 Project Layout
Project is divided into three main parts

List out features provided by application and implement those features.

Make connection between two system using sockets.

Implement module for webcam driver capture using MFC macros.
3.1.1
Implementation of Features
This section gives details of implementation of features. Detail includes functions
implemented to make these features functional as described in chapter 1.
22
Detail description of functionality.

Map all the buttons and menu items corresponding to the function.
EnableMenuItem() and (CButton*)GetDlgItem(button) functions are implemented
to
map menu options and buttons. EnableMenuItem() take menu item to be enabled and
action to take as parameters. Action includes enable, disable, grayed and other.
(CButton*)GetDlgItem(button) takes pointer to child window as parameter. To set and
get the window for the host and guest webcam SetWindowPos() and GetWindowRect()
functions are used.
Figure 3.1.1.1 Main window of application
23

Add Contact and Delete Contact
As, this application work on LAN, it adds IP address as contact. To get IP address and
host name GetAddress() and gethostname() functions are used. This function updates
contact list as well as contact.log file. OnDeleteCintact() function implemented to delete
contact from the contact list. This function executes methods GetcaretIndex, GetText,
DeleteString to delete contact form contact list. This will also update “contact.log” file.
Figure 3.1.1.2 Add contact in contact list
24

Connect to a Remote System
CAsyncSocket model is used to create socket in order to establish connection. Methods
SendTo() and OnReceive() are used to make connection to remote system. Depending on
the message type three sockets are created: DATA, VIDEO and CONTROLMSGS.
Figure 3.1.1.3 Connection accepted by user

Send Text Data
Once connection is establised and the socketType is defined as TEXTDATA, then it
calls function StartTextChat().The function textSocket.SendTextData is implemented to
25
send the text data over the network. This function updates chat Windows on both the
systems.
Figure 3.1.1.4 Sending text data

Start Host CAM
When the web cam is initialized, it calls the below functions:
 Create a capture window using the function capCreateCaptureWindow.
 Set the callback fuction by capSetCallbackOnFrame.
 Connect to the CAM Driver using capDriverConnect.
26
Capturing of frames starts once the initialization is being done. To capture frames
created, a thread created by AfxBeginThread. capGrabFrame() function is used to capture
frames. Once a frame is captured, it is stored in BMP format by using capFileSaveDIB().
Then the BMP file is converted to JPEG format by using CImage::Load and
CImage::Save functions.
Once the function capGrabFrame is executed it calls the
callback function to execute SendNDisplayVideo() function which displays the captured
frame using CImage::Draw and sends it to the remote host.
Figure 3.1.1.5 Initialization of webcam

Stop the Host CAM
27
Video chat has to be stopped on this function call. The methods capCaptureStop(),
capCaptureAbort(), and capDriverDisconnect() stop the capturing and disconnect the
driver.

Invite to View My CAM
CConnectCAMInvitation() function is called when this feature is executed. Depenging
upon
the
control
messages,
this
function
calls
CConnectCAMInvitation::OnConnectionAccept(),
CConnectCAMInvitation::OnConnectionReject()
Figure 3.1.1.6 Inivitation to view webcam
two
methods
and
28

Request to View Guest CAM
CConnectCAMRequest() function is called when this feature is executed. Depenging
upon
the
control
messages,
this
function
calls
CConnectCAMInvitation::OnConnectionAccept(),
two
methods
and
CConnectCAMInvitation::OnConnectionReject().
Figure 3.1.1.7 Request to view webcam

Stop Viewing Guest CAM
To implement this feature, the function capCaptureStop() is called. This function sends
control messages to the connected system.
29

Disconnect From Remote System
A sequence of methods are called to stop video and text chat. capCaptureStop(),
capCaptureAbort(), capDriverDisconnect() ,Close() executes sequentially.
Figure 3.1.1.8 Disconnection of webcam

Exit the Application
On exit , application closes all the open sockets. That includes it killing the thread to stop
the image-capturing process. OnExitApplication() calls the Shell_NotifyIcon()
function. It takes the arguments NIM_DELETE (0x00000002) and the pointer to the
thread-capturing structure.
30
The given tables give an overview of classes, functions and macros used by the
application.
CLASS
DESCRIPTION
REQUIREMENT USE IN
APPLICATION
CAsyncSocket encapsulates the
afxsock.h
To create socket
Windows Socket
DATA,VIDEO
Functions API
AND
CONTROLMSGS
CDialog
The base class used for afxwin.h
To create dialog
displaying dialog
box for chat
boxes on the screen.
window
Table 3.1.1.1 Classes used by video chat on LAN
FUNCTION
DoDataExchange
DESCRIPTION
Called by the
framework to
exchange and
validate dialog
data.
GetDlgItem
Retrieves a handle
to a control in the
specified dialog
box.
CapCreateCaptureWind Capture window is
ow
created by this
function
REQUIREMENT USE IN
APPLICAT
ION
To exchange
text and
video data
-
Vfw.h, Vfw32.lib
To handle
video and
text controls
To create
host and
guest capture
window for
text data.
Table 3.1.1.2 Functions used by video chat on LAN
31
3.1.2
Establish Connection Using Socket
Sockets are used to make connection between two systems. A class named DataSocket
was created, which is a subclass of CSocket. The DataSocket class contains a
datamember named SocketType and the PortNumber. The sockets created are the objects
of the class DataSocket. Three types of UDP sockets were created, and port numbers used
for those sockets were defined.
// Type of UDP socket
#define TYPE_CONTROLMESG
#define TYPE_VIDEODATA
#define TYPE_TEXTDATA
11 // for control messages
12 //for video data
13 // for text data
// Port Numbers used for different UDP sockets
#define PORT_CONTROLMESG
#define PORT_VIDEODATA
#define PORT_TEXTDATA
6000 // for control messages
6002 // for video data
6004 // for text data
To create Winsock application, the build environment should be linked to the library
wininet.lib. #pragma comment indicates to the linker that the wininet.lib file is needed.
Winsock 2 header files are included to use Winsock API. The Winsock2.h header file
contains most of the Winsock functions, structures, and definitions. The Ws2tcpip.h
header file contains definitions introduced in the WinSock 2 Protocol-Specific Annex
document for TCP/IP that includes newer functions and structures used to retrieve IP
addresses.
32

Below text describes how text chat works on the system.
Function CreateSocket(PORT_TEXTDATA,TYPE_TEXTDATA) creates the socket for
text data. ReceiveFrom ( textData , textLength , address , portNumber ) reads the data
from given address and portnumber and reads textData for length of textLength.
SendTo(data,n+2,PORT_CONTROLMESG,remoteaddress) sends the data of buffer size
n+2 to the given remoteaddress. OnAccept() function returns the value zero for success or
returns an error on network failure. OnConnect() function returns the value zero for
success or returns an error on network failure. OnReceive() returns the value zero if the
function is executed successfully or returns an error if socket implementation detects that
the network subsystem failed. OnSend() returns the value zero if the function is executed
successfully or returns an error if socket implementation detects that the network
subsystem failed. Function Close() closes the socket and releases the socket descriptor so
that no other references can use it.
33
The below figure is an example of communication between two systems.
User 1
192.168.1.11
Add IP in
contact log
GetAddress()
User 2
192.168.1.12
OnAddContact()
Accept
connection
request
CAsyscSocket::SendTo()
WebCAM
Started
StartTextChat()
CONTROLMESG_VIEWCAMRE
Q
CONTROLMESG_ACCEPTC
AMREQ
Check SocketType = TYPE_TEXTDATA/ TYPE_VIDEODATA/
TYPE_CONTROLMSGS
Check textData[0] = different CONTROLMESGS
Figure 3.1.2.1 Communication between two systems
In this example, User2 is added in the contact list of User 1. This is done by executing
function OnAddContact(). This function adds User2 in the contact list of User1. Once
34
User2 has accepted the connection request, User1 can initiate chat with User2. This is
done by executing StartOnChat() function. Here, User2 is sending request to User1 to
view User1’s webcam. The request is being accepted by User1. Once it is accepted,
User2 can view User1’s webcam. This example use all three sockets DATA for text chat,
VIDEO for video data and CONTROLMESGS for control messages like request to view
webcam and user1 has accepted webcam view request from user2.

Data exchange mechanism
The Dialog data exchange (DDX) mechanism is used to send and receive data. It is an
easy way to initialize the controls in a dialog box and to gather data input by the user.
Figure 3.1.2.2 Dialog data exchange
35
The initial values of the dialog object’s member variables are set in OnInitDialog handler.
DDX transfers the values of the member variables to the controls in the dialog box, where
they appear when the dialog box itself appears in response to DoModal. The same
mechanism transfers the values from the controls to the member variables when user
clicks the send button. If the user cancels a modal dialog box, the OnCancel member
function terminates the dialog box and DoModal returns the value IDCANCEL. In that
case, no data is exchanged between the dialog box and the dialog object.
3.1.3
Capturing Webcam Driver
This section describes how the webcam driver capture is done by MFC macros. Details
about capturing process of video frames and sending to other user are discussed here.
Following are the functions used to implement the webcam functionality:
void StartMyCAM();
//Start the webcam
void StopMyCAM();
//Stop the webcam
void InviteToViewCAM(); //Invite to view webcam
void ReqToViewCAM();
//Request to view webcam
void CAMDisconnected(); //Disconnect the webcam
void StopViewGuestCAM (); //Stop viewing webcam
To use MFC API’s for capturing webcam driver, “vfw32” library is used. #pragma
comment indicates to the linker that vfc32.lib file is needed. Also library “winmm” is
included so audio module can be implemented in future.
36
Given table lists the macros used by video chat on LAN:
MACRO
DESCRIPTION
REQUIREMENT
CapDriverConnect
Connects a
capture window
to a capture driver
Vfw.h
Disconnects a
capture driver
from a capture
window.
CapSetCallbckOnFrame Sets a preview
callback function
in the application.
AVICap calls this
procedure when
the capture
window captures
preview frames.
CapCaptureStop
Stops the capture
operation.
CapCaptureSetSetup
Sets the
configuration
parameters used
with streaming
capture
CapCaptureGetSetup
Retrieves the
current settings of
the streaming
capture
parameters.
CapSetVideoFormat
Sets the format of
captured video
data.
Vfw.h
CapDriverDisconnect
Vfw.h
Vfw.h
Vfw.h
USE IN
APPLICATION
To connect
capture window
to a webcam
driver
To disconnect
webcam driver
from the capture
window
Preview captured
frames. Returns
TURE on
successful or
FALSE if frame
capture session is
in progress.
Stop capturing
frames.
To set streaming
parameter with
capture window.
Vfw.h
To get streaming
parameter for
capture window
Vfw.h
To save frames
as bmp file.
Table 3.1.3.1 Macro used by video chat on LAN
37
Video data is captured in frames and stored in an image file, which is overwritten, every
hundred milliseconds by a new frame. To capture the frames, the structure
THREADSTRUCT
was
created.
Function
StartVideoCapture
is
called
using
AfxBeginThread function. This function creates an object of THREAD STRUCT and sets
volatile bool threadRun data type to TRUE. It calls capGrabFrame to capture the frame.
Once frame is captured it is saved as an image using capFileSaveDIB. Every 100ms, a
new frame is captured and old image is deleted. To send saved images to receiver
SendDisplayVideo() function is called. fread() function reads the RecivedImageObj which
is a pointer to CImage.

Below text describes how the webcam features work in the application:
Function capCreateCaptureWindow() creates the capture window. The function
capCreateCaptureWindow("Capture", WS_POPUP, 0, 0, 1, 1, 0, 0) takes the name used
for the capture window, style used for window, x-coordinate of the upper left corner of
the capture window, y-coordinate of the upper left corner of the capture window, Width
of the capture window, Height of the capture window, handle to the parent window and
the window identifier as arguments. The function capSetUserData(captureWindow, this)
captures
user
window.
The
function
capSetCallbackOnFrame(captureWindow,
OnCaptureVideo) macro points to the preview callback function of type Video Stream
Callback. AVICap calls this procedure when captureWiindow captures preview frames.
capDriverConnect(captureWindow, index) macro connects captureWindow to capture
38
driver with index. Used index=0 for webcam driver. When capDriverConnect function is
called, it connects the capture window to the webcam driver. The application captures the
image and stores it as a bmp file. It converts it into the jpeg file and sends it to the
destination. After converting bmp file to jpeg file it deletes the bmp file. Capturing of
frame happens at every 100ms. To capture frames, a thread is implemented using the
macro
AfxBeginThread.
The
thread
AfxBeginThread
(StartVideoCapture,
ThreadParameter) creates a new thread to capture images till the driver is connected.
capCaptureSetSetup
configuration
(captureWindow,&CapParms,sizeof(CapParms)
parameter
used
with
streaming
capture.
)
macro
sets
capCaptureGetSetup
(captureWindow, &CapParms, sizeof(CapParms)) macro retrieves the current settings of
the
streaming
capture
parameters.
The
macro
capSetVideoFormat(captureWindow,&VidCap_bmpinfo,sizeof(VidCap_bmpinfo))
called
to
set
the
format
of
capture
video
data.
is
capGetVideoFormat
(captureWindow,&m_bmpinfo,sizeof(m_bmpinfo)) macro is called to retrieve a copy of
the video format used. When the user stops to view the webcam, the macro
capCaptureStop(captureWindow) is called. This macro stops the capture operation for
captureWindow.
Once
the
function
capCaptureStop
is
executed,
capDriverDisconnect(captureWindow) will be executed and it disconnects the capture
driver for captureWindow.
39
Chapter 4
CONCLUSION AND FUTURE WORK
The primary goal of this project is to create a Video Chat on LAN application. Video is
generally used in these applications in order to provide a richer sense of presence [5],
help coordination of communication [4] and facilitate emotional expression. However,
delivering high-quality video remains technically challenging for this application as it
uses UDP connections. To make video quality better, TCP connections can be used
instead of UDP. Also, by adding modules for send file and audio features, the application
can be made more versatile.
This application has been successfully implemented using VC++.NET and MFC library. I
have learned a lot about MFC library during implementation of different functionalities
for the application, and how they can be integrated with .NET framework to make a userfriendly application.
To summarize, I would like to make a note that this Video chat on LAN Application is an
efficient and cost-effective application.
40
APPENDIX
VideoOverLanDlg.h
#pragma once
#define WM_TRAY_MESSAGE (WM_USER + 3)
// CVideoOverLanDlg dialog
class CVideoOverLanDlg : public CDialog
{
public:
CVideoOverLanDlg(CWnd* pParent = NULL);
// standard constructor
// Dialog Data
enum { IDD = IDD_VIDEOOVERLAN_DIALOG };
NOTIFYICONDATA m_TrayData;
CMenu m_menu;
afx_msg void OnBnClickedOk();
afx_msg void OnBnClickedButton1();
HICON m_hIcon;
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
void OnTrayRButtonDown(CPoint pt);
void OnExit();
LRESULT OnTrayNotify(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
protected:
virtual void DoDataExchange(CDataExchange* pDX);
support
private:
CBitmapButton btnBmpENTER , btnBmpEXIT;
};
// DDX/DDV
41
VideoOverLanDlg.cpp
#include "stdafx.h"
#include "VideoOverLan.h"
#include "VideoOverLanDlg.h"
#include "ChatBox.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
CChatBox * chatObj;
// CVideoOverLanDlg dialog
CVideoOverLanDlg::CVideoOverLanDlg(CWnd* pParent /*=NULL*/) :
CDialog(CVideoOverLanDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
btnBmpENTER.LoadBitmaps(IDB_BITMAP2);
btnBmpEXIT.LoadBitmaps(IDB_BITMAP3);
}
void CVideoOverLanDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
// Maping the Buttons with user defined functions.
BEGIN_MESSAGE_MAP(CVideoOverLanDlg, CDialog)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDOK, &CVideoOverLanDlg::OnBnClickedOk)
ON_MESSAGE(WM_TRAY_MESSAGE,OnTrayNotify)
ON_COMMAND(ID_EXIT, OnExit)
END_MESSAGE_MAP()
// CVideoOverLanDlg message handlers
BOOL CVideoOverLanDlg::OnInitDialog()
{
CDialog::OnInitDialog();
42
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX,
strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE);
// Set big icon
SetIcon(m_hIcon, FALSE);
// Set small icon
// TODO: Add extra initialization here
CButton *btnENTER , *btnEXIT ;
//Load Bitmap images on Buttons.
btnENTER = reinterpret_cast<CButton *>(GetDlgItem(IDOK));
LONG GWLENTER = GetWindowLong(btnENTER->m_hWnd,
GWL_STYLE);
SetWindowLong(btnENTER->m_hWnd, GWL_STYLE, GWLENTER |
BS_OWNERDRAW) ;
btnBmpENTER.SubclassDlgItem(IDOK, this);
btnEXIT = reinterpret_cast<CButton *>(GetDlgItem(IDCANCEL));
LONG GWLEXIT = GetWindowLong(btnEXIT->m_hWnd, GWL_STYLE);
SetWindowLong(btnEXIT->m_hWnd, GWL_STYLE, GWLEXIT |
BS_OWNERDRAW) ;
btnBmpEXIT.SubclassDlgItem(IDCANCEL, this);
43
return TRUE; // return TRUE unless you set the focus to a control
}
void CVideoOverLanDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND,
reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CVideoOverLanDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
// When ENTER Pressed
void CVideoOverLanDlg::OnBnClickedOk()
{
chatObj = new CChatBox;
chatObj->SetParent(this);
//Create the System-tray Icon.
m_TrayData.cbSize = sizeof(NOTIFYICONDATA);
m_TrayData.hWnd = this->m_hWnd;
m_TrayData.uID = 1;
44
m_TrayData.uCallbackMessage
= WM_TRAY_MESSAGE;
m_TrayData.hIcon = this->m_hIcon;
strcpy(m_TrayData.szTip,"My Icon");
m_TrayData.uFlags = NIF_ICON|NIF_MESSAGE;
//Load the Menu on the tray icon.
BOOL BSus = FALSE;
BSus = m_menu.LoadMenu(IDR_MENU2);
if(!(BSus))
MessageBox("Unabled to Load menu");
BOOL bSuccess = FALSE;
bSuccess = Shell_NotifyIcon(NIM_ADD,&m_TrayData);
if(!(bSuccess))
MessageBox("Unable to Set Tary Icon");
else
{
this->ShowWindow(SW_MINIMIZE);
this->ShowWindow(SW_HIDE);
}
chatObj->DoModal();
// Draw the Next window ( Chat Box window ).
}
//Tray Icon notify Function.
LRESULT CVideoOverLanDlg::OnTrayNotify(WPARAM wParam, LPARAM lParam)
{
UINT uID;
UINT uMsg;
uID = (UINT) wParam;
uMsg = (UINT) lParam;
if (uID != 1)
return 0;
CPoint pt;
switch (uMsg )
{
case WM_LBUTTONDOWN:
GetCursorPos(&pt);
ClientToScreen(&pt);
OnTrayRButtonDown(pt);
break;
45
case WM_RBUTTONDOWN:
case WM_CONTEXTMENU:
GetCursorPos(&pt);
OnTrayRButtonDown(pt);
break;
}
return 1;
}
//On Right Button Pressed
void CVideoOverLanDlg::OnTrayRButtonDown(CPoint pt)
{
m_menu.GetSubMenu(0)-> TrackPopupMenu(TPM_BOTTOMALIGN|
TPM_LEFTBUTTON| TPM_RIGHTBUTTON,pt.x,pt.y,this);
}
//On EXIT.
void CVideoOverLanDlg::OnExit()
{
Shell_NotifyIcon(NIM_DELETE,&m_TrayData);
DestroyWindow();
}
46
VideoOverLan.h
#pragma once
#ifndef __AFXWIN_H__
#error "include 'stdafx.h' before including this file for PCH"
#endif
#include "resource.h"
// CVideoOverLanApp:
class CVideoOverLanApp : public CWinApp
{
public:
CVideoOverLanApp();
public:
virtual BOOL InitInstance();
DECLARE_MESSAGE_MAP()
};
extern CVideoOverLanApp theApp;
47
VideoOverLan.cpp
#include "stdafx.h"
#include "VideoOverLan.h"
#include "VideoOverLanDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CVideoOverLanApp
BEGIN_MESSAGE_MAP(CVideoOverLanApp, CWinApp)
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
// CVideoOverLanApp construction
CVideoOverLanApp::CVideoOverLanApp()
{
}
// The one and only CVideoOverLanApp object
CVideoOverLanApp theApp;
// CVideoOverLanApp initialization
BOOL CVideoOverLanApp::InitInstance()
{
// InitCommonControlsEx() is required on Windows XP if an application
// manifest specifies use of ComCtl32.dll version 6 or later to enable
// visual styles. Otherwise, any window creation will fail.
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// Set this to include all the common control classes you want to use
// in your application.
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
48
CWinApp::InitInstance();
AfxEnableControlContainer();
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
CVideoOverLanDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
}
else if (nResponse == IDCANCEL)
{
}
return FALSE;
}
49
stdafx.h
// stdafx.h : include file for standard system include files, or project specific include files
that are used frequently, but are changed infrequently
#pragma once
#ifndef _SECURE_ATL
#define _SECURE_ATL 1
#endif
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN
#endif
// Exclude rarely-used stuff from Windows headers
// Modify the following defines if you have to target a platform prior to the ones specified
below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER
// Allow use of features specific to Windows XP or later.
#define WINVER 0x0501
// Change this to the appropriate value to target other
versions of Windows.
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
// Allow use of features specific to Windows XP or
//later.
// Change this to the appropriate value to target
//other versions of Windows.
#endif
#ifndef _WIN32_WINDOWS
// Allow use of features specific to Windows 98 or
//later.
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target
//Windows Me or later.
#endif
#ifndef _WIN32_IE
// Allow use of features specific to IE 6.0 or later.
#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other
// versions of IE.
#endif
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors
//will be explicit
50
// turns off MFC's hiding of some common and often safely ignored warning messages
#define _AFX_ALL_WARNINGS
#include <afxwin.h>
#include <afxext.h>
// MFC core and standard components
// MFC extensions
#include <afxdisp.h>
// MFC Automation classes
#ifndef _AFX_NO_OLE_SUPPORT
#include <afxdtctl.h>
// MFC support for Internet Explorer 4 Common Controls
#endif
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>
// MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
#include <afxsock.h>
// MFC socket extensions
#include "atlimage.h"
#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32'
name='Microsoft.Windows.Common-Controls' version='6.0.0.0'
processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_IA64
#pragma comment(linker,"/manifestdependency:\"type='win32'
name='Microsoft.Windows.Common-Controls' version='6.0.0.0'
processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32'
name='Microsoft.Windows.Common-Controls' version='6.0.0.0'
processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32'
name='Microsoft.Windows.Common-Controls' version='6.0.0.0'
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#endif
51
stdafx.cpp
// stdafx.cpp : source file that includes just the standard includes
// VideoOverLan.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
52
Resource.h
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by VideoOverLan.rc
//
#define IDM_ABOUTBOX
0x0010
#define IDD_ABOUTBOX
100
#define IDS_ABOUTBOX
101
#define IDD_VIDEOOVERLAN_DIALOG 102
#define IDR_MAINFRAME
128
#define IDD_DIALOG1
129
#define IDD_CHATBOX
129
#define IDR_MENU1
130
#define IDD_DIALOG2
131
#define IDD_DIALOG3
132
#define IDR_MENU2
133
#define IDB_BITMAP1
134
#define IDB_BITMAP2
135
#define IDB_BITMAP3
136
#define IDB_BITMAP4
137
#define IDB_BITMAP5
138
#define IDB_BITMAP6
139
#define IDD_DIALOG4
140
#define IDD_DIALOG5
142
#define IDB_BITMAP7
143
#define IDB_BITMAP8
144
#define IDC_IPADDRESS1
1000
#define IDC_LOCALVIDEO
1001
#define IDC_LOCALBORDER
1002
#define IDC_REMOTEBORDER
1003
#define IDC_REMOTEVIDEO
1004
#define IDC_LIST1
1005
#define IDC_EDIT1
1006
#define IDC_BUTTON1
1009
#define IDREJECT
1010
#define IDC_MESG
1011
#define IDC_EDIT2
1012
#define IDC_BUTTON2
1013
#define IDC_LIST2
1015
#define IDC_BUTTON3
1016
53
#define IDC_BUTTON4
1017
#define IDC_BUTTON5
1018
#define IDC_CAMREQ
1019
#define IDC_CAMINV
1021
#define IDB_STATIC
1022
#define ID_CHAT_CONNECT
32771
#define ID_CHAT_DISCONNECT
32772
#define ID_CHAT_EXIT
32773
#define ID_VIEW_LOCALVIDEOSCREEN
32774
#define ID_VIEW_REMOTEVIDEOSCREEN
32775
#define ID_HELP_ABOUT
32778
#define VIDEO_SEND
32784
#define VIDEO_RECEIVE
32785
#define HELP_ABOUT
32786
#define ID_EXIT_EXIT
32787
#define ID_EXIT
32788
#define CHAT_DISCONNECT
32789
#define CHAT_EXIT
32790
#define VIEW_MYCAM
32791
#define START_MYCAM
32792
#define STOP_MYCAM
32793
#define ID_VIEWCAM_STOPSENDINGVIDEO 32794
#define ID_VIEWCAM_STOPRECEIVINGVIDEO 32795
#define INVITE_CAM
32798
#define REQ_CAM
32799
#define STOP_GUESTCAM
32800
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE
#define _APS_NEXT_COMMAND_VALUE
#define _APS_NEXT_CONTROL_VALUE
#define _APS_NEXT_SYMED_VALUE
#endif
#endif
145
32801
1023
101
54
DataSocket.h
#if
!defined(AFX_DATASOCKET_H__B098630F_5F44_11D6_8897_000B2B0F84B6__I
NCLUDED_)
#define
AFX_DATASOCKET_H__B098630F_5F44_11D6_8897_000B2B0F84B6__INCLUDE
D_
// Type of UDP socket
#define TYPE_CONTROLMESG 11
#define TYPE_VIDEODATA 12
#define TYPE_TEXTDATA 13
// Port Numbers used for different UDP sockets
#define PORT_CONTROLMESG 6000
#define PORT_VIDEODATA 6002
#define PORT_TEXTDATA 6004
// Control Message types.
#define CONTROLMESG_CONNECT 101
#define CONTROLMESG_DISCONNECT 102
#define CONTROLMESG_ACCEPT
103
#define CONTROLMESG_REJECT
104
#define CONTROLMESG_VIEWCAMERAREQ 105
#define CONTROLMESG_ACCEPTCAMREQ
106
#define CONTROLMESG_REJECTCAMREQ
107
#define CONTROLMESG_VIEWCAMERAINV
#define CONTROLMESG_ACCEPTCAMINV
#define CONTROLMESG_REJECTCAMINV
108
109
110
#define CONTROLMESG_CAMDISCONNECT
#define CONTROLMESG_STOPVIEWCAM
#define CONTROLMESG_NOCAM
111
112
113
55
class DataSocket : public CSocket
{
public:
CDialog *parentDlg;
char localname[200];
static char remotename[500];
static char remoteaddress[500];
int SocketType;
static unsigned char textData[2000] , videoData[30000];
static unsigned int textLength , videoLength;
DataSocket();
virtual ~DataSocket();
void CreateSocket(int port,int type);
void SetParent(CDialog *dlg);
void OnReceive(int errcode);
void SendControlMessage(int type,char *address);
void SendVideoData(unsigned char *data,int length);
void SendTextData(unsigned char *data,short length);
void CloseSocket();
};
#endif
56
DataSocket.cpp
#pragma comment(lib, "wininet.lib")
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <windows.h>
#include "stdafx.h"
#include "VideoOverLan.h"
#include "DataSocket.h"
#include "VideoOverLanDlg.h"
#include "ChatBox.h"
#include "ConnectionRequestDlg.h"
#include "ConnectCAMRequest.h"
#include "ConnectCAMInvitation.h"
char DataSocket::remoteaddress[500]="";
char DataSocket::remotename[500]="";
unsigned char DataSocket::textData[2000];
unsigned char DataSocket::videoData[30000];
unsigned int DataSocket::textLength=2000;
unsigned int DataSocket::videoLength=30000;
DataSocket::DataSocket()
{
}
DataSocket::~DataSocket()
{
}
// Create the Socket with particular type and port number.
void DataSocket::CreateSocket(int port,int DataType)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
57
CString ERR;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
ERR.Format("WSAStartup failed with error: %d\n", err);
AfxMessageBox(ERR);
return ;
}
this->Create(port,SOCK_DGRAM);
SocketType=DataType;
gethostname(localname,300);
}
void DataSocket::SetParent(CDialog *dlg)
{
parentDlg=dlg;
}
//Called by the framework when message/data is received on the socket.
void DataSocket::OnReceive(int errcode)
{
CString address;
char hname[400],str[1000],mesg[500];
unsigned int portNumber , retvalue;
int n,len;
ConnectionRequestDlg requestDlg(NULL);
CConnectCAMRequest CAMRequestDlg(NULL);
CConnectCAMInvitation CAMInviteDlg(NULL);
// Checking for the DATA Type.
if(SocketType==TYPE_CONTROLMESG)
{
retvalue = this->ReceiveFrom ( textData , textLength , address ,
portNumber ); // Read the DATA.
if(retvalue==SOCKET_ERROR)
return;
int i = 0;
for ( i=0 ; i<textData[1] ; i++ )
hname[i] = textData[i+2];
58
hname[i] = 0;
strcpy ( remotename , hname );
strcpy ( remoteaddress , (LPCTSTR) address);
//Checking for Particular Message.
if ( textData[0] == CONTROLMESG_CONNECT ) // Connect Request
{
requestDlg.SetParameter(remotename,remoteaddress,parentDlg);
requestDlg.DoModal();
return;
}
else if ( textData[0] == CONTROLMESG_DISCONNECT )
{
( (CChatBox*)parentDlg)->StopTextChat();
sprintf(str,"User %s has disconnected",hname);
AfxMessageBox(str);
return;
}
else if ( textData[0] == CONTROLMESG_CAMDISCONNECT )
{
( (CChatBox*)parentDlg)->CAMDisconnected();
sprintf ( str , "USER %s has Disconnected the CAM" , hname );
AfxMessageBox ( str );
}
else if ( textData[0] == CONTROLMESG_ACCEPT )
{
AfxMessageBox("User has accepted the connection");
( (CChatBox*)parentDlg)->StartTextChat();
return;
}
else if ( textData[0] == CONTROLMESG_REJECT )
//Connection Rejected.
{
sprintf(str,"User %s has rejected your invitation",hname);
AfxMessageBox(str);
return;
}
else if ( textData[0] == CONTROLMESG_VIEWCAMERAREQ )
{
if ( ( ( CChatBox * ) parentDlg )->MyCAMStarted )
{
59
CAMRequestDlg.SetParameter(remotename,remoteaddress,parentDlg);
CAMRequestDlg.DoModal();
return;
}
else
((CChatBox*)parentDlg)->
controlMSGSocket.SendControlMessage (CONTROLMESG_NOCAM,NULL);
}
else if ( textData[0] == CONTROLMESG_ACCEPTCAMREQ )
{
AfxMessageBox("User has Accepted Your Request");
( ( CChatBox * ) parentDlg )->menu->EnableMenuItem (
REQ_CAM , MF_GRAYED );
( ( CChatBox * ) parentDlg )->menu->EnableMenuItem (
STOP_GUESTCAM , MF_ENABLED );
if ( ( ( CChatBox * ) parentDlg )->MyCAMStarted )
( ( CChatBox * ) parentDlg )->menu->EnableMenuItem (
INVITE_CAM , MF_ENABLED );
( ( CChatBox * ) parentDlg )->ReceiveCAM = TRUE;
( ( CChatBox * ) parentDlg )->StopGuestCAM = FALSE;
return;
}
else if ( textData[0] == CONTROLMESG_REJECTCAMREQ )
//Reject the Request to view the CAM
{
sprintf(str,"User %s has rejected your Request to View the
CAM",hname);
AfxMessageBox(str);
return;
}
else if ( textData[0] == CONTROLMESG_VIEWCAMERAINV )
{
CAMInviteDlg.SetParameter(remotename,remoteaddress,parentDlg);
CAMInviteDlg.DoModal();
return;
}
else if ( textData[0] == CONTROLMESG_ACCEPTCAMINV )
{
AfxMessageBox("User has accepted Your Invitation");
60
( ( CChatBox * ) parentDlg )->menu->EnableMenuItem (
INVITE_CAM , MF_GRAYED );
( ( CChatBox * ) parentDlg )->SendMyCAM = TRUE;
return;
}
else if ( textData[0] == CONTROLMESG_REJECTCAMINV )
//Reject the invitation.
{
sprintf(str,"User %s has rejected your Invitation to View the
CAM",hname);
AfxMessageBox(str);
return;
}
else if ( textData[0] == CONTROLMESG_STOPVIEWCAM )
{
( ( CChatBox * ) parentDlg )->menu->EnableMenuItem (
INVITE_CAM , MF_ENABLED );
sprintf ( str , "USER %s has Stoppped Viewing Your CAM" ,
hname );
AfxMessageBox ( str );
return ;
}
else if ( textData[0] == CONTROLMESG_NOCAM )
{
sprintf ( str , "Either USER %s Didn't Have a CAM or didn't
START CAM" , hname );
AfxMessageBox ( str );
return ;
}
return;
}
if ( SocketType == TYPE_VIDEODATA ) // Type Video.
{
retvalue = this->ReceiveFrom ( videoData , videoLength , address ,
portNumber );
if ( retvalue == SOCKET_ERROR )
return;
( ( CChatBox * ) parentDlg )->DisplayReceivedFrame ( videoData ,
retvalue );
return;
}
if ( SocketType == TYPE_TEXTDATA )
//Type Text Data.
61
{
retvalue = this->ReceiveFrom ( textData , textLength , address ,
portNumber );
if ( retvalue == SOCKET_ERROR )
return;
// Get host name from the data.
// Length of username
n = textData[1];
int i = 0;
for ( i = 0 ; i < n ; i++)
hname[i] = textData[i+2];
hname[i] = 0;
len = textData[n+2] | ( textData[n+3] << 8 );
memcpy(mesg,&textData[n+4],len);
mesg[len]=0;
sprintf(str,"%s >> %s ",hname,mesg);
// Display message in list box
((CChatBox *)parentDlg)->DisplayMesg(str);
return;
}
}
// Send the control message to remote host
void DataSocket::SendControlMessage(int type,char *address)
{
char data[1000];
int n;
// Prepare the message DATA
// Type of the Message
data[0]=type;
// Length of hostname
n=strlen(localname);
data[1]=n;
// Name of the sender host
62
memcpy(&data[2],localname,n);
if(address==NULL)
SendTo(data,n+2,PORT_CONTROLMESG,remoteaddress);
else
SendTo(data,n+2,PORT_CONTROLMESG,address);
}
//Send the VIDEO data to remote host
void DataSocket::SendVideoData(unsigned char *data,int length)
{
SendTo(data,length,PORT_VIDEODATA,remoteaddress);
}
//Send the TEXT data to remote host
void DataSocket::SendTextData(unsigned char *data,short length)
{
unsigned char *packet=new unsigned char[length+500];
int n;
// Create the Packet to Send
// Set the Type Text message
packet[0]=TYPE_TEXTDATA;
// Length of hostname
n=strlen(localname);
packet[1]=n;
// Hostname
memcpy(&packet[2],localname,n);
// Data length
packet[n+2]=(unsigned char) length;
packet[n+3]=(unsigned char) (length>>8);
// Data
memcpy(&packet[n+4],data,length);
SendTo(packet,n+4+length,PORT_TEXTDATA,remoteaddress);
}
63
//Closes the socket created by the createsocket method
void DataSocket::CloseSocket()
{
DataSocket::Close();
}
64
Chatbox.h
#include<vfw.h>
#include<afxmt.h>
#include<afxole.h>
#include "DataSocket.h"
#include "AddContactDlg.h"
#include "afxwin.h"
#define CAM_WIDTH 176
#define CAM_HEIGHT 144
#define IMAGE_WIDTH
#define IMAGE_HEIGHT
CAM_WIDTH
CAM_HEIGHT
// CChatBox dialog
class CChatBox : public CDialog
{
DECLARE_DYNAMIC(CChatBox)
public:
CDialog *mdlg;
HWND captureWindow;
CAPDRIVERCAPS caps;
BOOL TextChatStarted ;
BOOL MyCAMStarted , StopGuestCAM , InviteCAMEnable;
BOOL SendMyCAM ,ReceiveCAM;
PBITMAPINFO m_bmpinfo;
BITMAPINFO compbmp , VidCap_bmpinfo;
BITMAPINFOHEADER m_bmpheader;
BOOL CAMInitialize();
BOOL SetCaptureParameters();
void CAMDestroy();
void GetDriverCaps();
BOOL StartCapture();
BOOL StopCapture();
65
friend LRESULT CALLBACK OnCaptureVideo(HWND hWnd,
LPVIDEOHDR lpheader) ;
static UINT StartVideoCapture (LPVOID param);
typedef struct THREADSTRUCT
{
CChatBox * _this;
} THREADSTRUCT;
HDC m_hdc;
CMenu *menu;
CButton *SendButton;
CButton *ConnectButton;
CButton *CancelConnectButton;
CListBox *ChatListBox;
CListBox ContactListBox;
CStdioFile ContactListFile;
CChatBox * chatObj;
HICON m_hIcon;
HWND hwnd;
CAddContactDlg *addContactdlg;
DataSocket controlMSGSocket , videoSocket , textSocket;
HDRAWDIB hdib;
int local_wnd_x , local_wnd_y;
int remote_wnd_x , remote_wnd_y;
CChatBox(CWnd* pParent = NULL);
virtual ~CChatBox();
void SetParent(CDialog *dlg);
enum { IDD = IDD_CHATBOX };
virtual void DoDataExchange(CDataExchange* pDX);
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnCancel ();
66
afx_msg void OnContactSelect();
virtual void OnExitApplication();
void OnDisconnect();
void StartMyCAM();
void StopMyCAM();
void InviteToViewCAM();
void ReqToViewCAM();
void CAMDisconnected();
void StopViewGuestCAM ();
void OnAbout();
void StartTextChat();
void StopTextChat();
void OnSendMesg();
void OnConnect();
void OnCancelConnect();
void OnDeleteContct();
void OnAddContact();
void DisplayMesg(char *str);
void SendNDisplayVideo();
void DisplayReceivedFrame(unsigned char *data,int size);
DECLARE_MESSAGE_MAP()
};
67
ChatBox.cpp
#include "stdafx.h"
#include "VideoOverLan.h"
#include "VideoOverLanDlg.h"
#include "ChatBox.h"
#pragma comment(lib,"vfw32")
#pragma comment(lib,"winmm")
int lengthOfFile = 0;
bool JpegCreated = false;
volatile bool threadRun = TRUE;
unsigned char sendData[10000];
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
enum { IDD = IDD_ABOUTBOX };
// ClassWizard generated virtual function overrides
protected:
virtual void DoDataExchange(CDataExchange* pDX);
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
// DDX/DDV support
68
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CChatBox dialog
IMPLEMENT_DYNAMIC(CChatBox, CDialog)
CChatBox::CChatBox(CWnd* pParent /*=NULL*/)
pParent)
{
: CDialog(CChatBox::IDD,
}
CChatBox::~CChatBox()
{
}
void CChatBox::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST2, ContactListBox);
}
void CChatBox::SetParent(CDialog *dlg)
{
mdlg=dlg;
}
BEGIN_MESSAGE_MAP(CChatBox, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
// Chat menu handlers
ON_COMMAND(CHAT_DISCONNECT,OnDisconnect)
ON_COMMAND(CHAT_EXIT,OnExitApplication)
// Display CAM menu handlers
ON_COMMAND(START_MYCAM,StartMyCAM)
ON_COMMAND(STOP_MYCAM,StopMyCAM)
69
// View CAM menu handlers
ON_COMMAND(INVITE_CAM,InviteToViewCAM)
ON_COMMAND(REQ_CAM,ReqToViewCAM)
ON_COMMAND ( STOP_GUESTCAM , StopViewGuestCAM )
// ABOUT menu handlers
ON_COMMAND(HELP_ABOUT,OnAbout)
ON_COMMAND(IDOK,OnSendMesg)
ON_COMMAND(IDC_BUTTON1, OnConnect)
ON_COMMAND(IDC_BUTTON2, OnCancelConnect)
ON_COMMAND(IDC_BUTTON4, OnAddContact)
ON_COMMAND(IDC_BUTTON5, OnDeleteContct)
//Notification Handler for Contact List.
ON_LBN_SELCHANGE(IDC_LIST2, OnContactSelect)
END_MESSAGE_MAP()
// Init Dialog for ChatBox Dialog
BOOL CChatBox::OnInitDialog()
{
CDialog::OnInitDialog();
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING,
IDM_ABOUTBOX, strAboutMenu);
}
}
SetIcon(m_hIcon, TRUE);
// Set big icon
SetIcon(m_hIcon, FALSE);
// Set small icon
70
// Open ContactListFile
ContactListFile.Open("ContactFile.log",CFile::modeCreate |
CFile::modeNoTruncate | CFile::modeRead);
// Disable/Enable the menu items
menu=this->GetMenu();
menu->EnableMenuItem(CHAT_DISCONNECT,MF_DISABLED |
MF_GRAYED);
menu->EnableMenuItem(INVITE_CAM,MF_GRAYED);
menu->EnableMenuItem(REQ_CAM,MF_GRAYED);
menu->EnableMenuItem(STOP_GUESTCAM,MF_GRAYED);
menu->EnableMenuItem(STOP_MYCAM,MF_GRAYED);
menu->EnableMenuItem(START_MYCAM,MF_ENABLED);
ChatListBox = (CListBox*)GetDlgItem(IDC_LIST1); //Initialize ChatListBox
SendButton = (CButton*)GetDlgItem(IDOK);
ConnectButton = (CButton*)GetDlgItem(IDC_BUTTON1);
CancelConnectButton = (CButton*)GetDlgItem(IDC_BUTTON2);
// Disable the send button
SendButton->EnableWindow(FALSE);
MyCAMStarted = FALSE;
StopGuestCAM = FALSE;
SendMyCAM=FALSE;
ReceiveCAM=FALSE;
TextChatStarted = FALSE;
CWnd *wnd,*bwnd;
CRect rect,brect;
// Initialize the Window for viewing MY CAM
wnd=this->GetDlgItem(IDC_LOCALVIDEO);
bwnd=this->GetDlgItem(IDC_LOCALBORDER);
bwnd->GetWindowRect(brect);
71
ScreenToClient(brect);
local_wnd_x=brect.TopLeft().x+(brect.Width()-IMAGE_WIDTH)/2;
local_wnd_y=brect.TopLeft().y+(brect.Height()-IMAGE_HEIGHT)/2;
wnd->SetWindowPos(&wndTop,local_wnd_x-4,local_wnd_y-4,
IMAGE_WIDTH+9,IMAGE_HEIGHT+9,SWP_SHOWWINDOW |
SWP_DRAWFRAME);
// Initialize the Window for viewing Guest's CAM
wnd=this->GetDlgItem(IDC_REMOTEVIDEO); // Video display window
bwnd=this->GetDlgItem(IDC_REMOTEBORDER); // Border window...
bwnd->GetWindowRect(brect);
ScreenToClient(brect);
remote_wnd_x=brect.TopLeft().x+(brect.Width()-IMAGE_WIDTH)/2;
remote_wnd_y=brect.TopLeft().y+(brect.Height()-IMAGE_HEIGHT)/2;
wnd->SetWindowPos(&wndTop,remote_wnd_x-4,remote_wnd_y-4,
IMAGE_WIDTH+9,IMAGE_HEIGHT+9,SWP_SHOWWINDOW |
SWP_DRAWFRAME);
// Get Dialog DC
m_hdc=this->GetDC()->m_hDC;
// Setup the connect dialog box
addContactdlg=new CAddContactDlg(NULL);
addContactdlg->SetParent(this);
// Setup the parent for differnt UDP sockets
controlMSGSocket.SetParent(this);
videoSocket.SetParent(this);
textSocket.SetParent(this);
// Create UDP socket for Transmitting and receiving Control messages
controlMSGSocket.CreateSocket(PORT_CONTROLMESG,TYPE_CONTROL
MESG);
//Read the contents of Contact list file and display on the contact list window.
lengthOfFile = ContactListFile.GetLength();
72
if ( lengthOfFile )
{
int i = 0 , j = 0;
char * Buffer = NULL;
char contact[300] = "";
Buffer = new char [lengthOfFile];
ContactListFile.Read ( Buffer , lengthOfFile );
for ( i = 0 ; i < lengthOfFile ; i++ , j++ )
{
if ( Buffer[i] != '\n' )
contact[j] = Buffer[i];
else
{
contact[j] = '\0';
j = 0;
ContactListBox.AddString ( contact );
}
}
}
ContactListFile.Close ();
return TRUE; // return TRUE unless you set the focus to a control
}
void CChatBox::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
void CChatBox::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
73
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
HCURSOR CChatBox::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CChatBox::OnCancel()
{
OnExitApplication();
}
void CChatBox::OnExitApplication()
{
//Stop the Thread
threadRun = FALSE;
// If the not disconnected from the remote system then disconnect
if(TextChatStarted)
StopTextChat();
//If Cam is not stopped, stop the CAM
if ( MyCAMStarted )
StopMyCAM();
// Close the control message Socket
controlMSGSocket.CloseSocket();
74
// Close the video capture device
CAMDestroy();
// Close graphics....
if(hdib!=NULL)
{
::DrawDibEnd(hdib);
::DrawDibClose(hdib);
}
CDialog::OnCancel();
//Close the Parent Window.
( ( CVideoOverLanDlg * )mdlg)->OnExit();
}
void CChatBox::OnDisconnect()
{
// Send notification to the remote host...
controlMSGSocket.SendControlMessage(CONTROLMESG_DISCONNECT,NULL);
StopTextChat();
}
void CChatBox::StartMyCAM()
{
CMenu *menu=this->GetMenu();
if( MyCAMStarted == FALSE )
{
if ( CAMInitialize () )
{
m_bmpinfo=&VidCap_bmpinfo;
menu-> EnableMenuItem(START_MYCAM,MF_DISABLED |
MF_GRAYED);
menu->EnableMenuItem(STOP_MYCAM,MF_ENABLED);
if ( TextChatStarted == TRUE )
{
menu->EnableMenuItem(INVITE_CAM,MF_ENABLED);
InviteCAMEnable = TRUE;
}
MyCAMStarted=TRUE;
75
if ( StartCapture () == FALSE )
{
MessageBox("Unable to start the capture");
}
}
}
}
void CChatBox::StopMyCAM()
{
CMenu *menu=this->GetMenu();
if ( MyCAMStarted )
{
StopCapture ();
CAMDestroy ();
CWnd *wnd=(CWnd*)this->GetDlgItem(IDC_LOCALVIDEO);
wnd->Invalidate(TRUE);
menu->EnableMenuItem(START_MYCAM,MF_ENABLED);
menu->EnableMenuItem(STOP_MYCAM,MF_GRAYED);
if ( InviteCAMEnable == TRUE )
{
if ( SendMyCAM == TRUE )
controlMSGSocket.SendControlMessage(CONTROLMESG_CAMDISCONNEC
T,NULL);
menu->EnableMenuItem(INVITE_CAM,MF_GRAYED);
InviteCAMEnable = FALSE;
}
MyCAMStarted = FALSE;
}
}
void CChatBox::InviteToViewCAM()
{
controlMSGSocket.SendControlMessage(CONTROLMESG_VIEWCAMERAIN
V,NULL);
}
void CChatBox::ReqToViewCAM()
{
controlMSGSocket.SendControlMessage(CONTROLMESG_VIEWCAMERAR
EQ,NULL);
}
76
void CChatBox::OnAbout()
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
void CChatBox::OnSendMesg()
{
unsigned char data[500];
char msg[500];
//Get the Message from Edit Box.
GetDlgItemText(IDC_EDIT1,(char*)data,500);
if(strlen((const char*)data)>0) // Checking if any Message is there or Not.
{
//Call the function to send the data to Remote Host.
textSocket.SendTextData(data,strlen((const char*)data));
//Clean the Edit Box.
SetDlgItemText(IDC_EDIT1,"");
//Call the function to Display the Message on the List Box.
sprintf ( msg , "%s >> %s" , "ME" , data );
DisplayMesg ( msg );
}
}
void CChatBox::DisplayMesg(char *mesg)
{
//The Message is Displaying On the List Box.
ChatListBox->AddString(mesg);
}
void CChatBox::DisplayReceivedFrame(unsigned char *data1,int size)
{
// If remote view disabled then return...
if(StopGuestCAM == TRUE)
return;
// If video reception disabled..then return..
77
if(ReceiveCAM == FALSE)
return;
FILE * JpegFileWrite = NULL ;
JpegFileWrite = fopen ( "RecivedFrame.jpg" , "wb+" );
fwrite ( data1 , sizeof ( unsigned char ) , size , JpegFileWrite );
fclose ( JpegFileWrite);
CImage * RecivedImageObj = new CImage; ;
CString ReciveFramePath = _T("RecivedFrame.jpg");
HRESULT hResult = RecivedImageObj->Load(ReciveFramePath);
RecivedImageObj->Draw
(m_hdc,remote_wnd_x,remote_wnd_y,IMAGE_WIDTH,IMAGE_HEIGHT,0,0,IMAGE
_WIDTH,IMAGE_HEIGHT);
}
void CChatBox::SendNDisplayVideo()
{
CRect wndrect;
// Display the captured frame...
if(MyCAMStarted)
{
CImage * RecivedImageObj = new CImage; ;
CString ReciveFramePath = _T("CaptureFrame.bmp");
HRESULT hResult = RecivedImageObj->Load(ReciveFramePath);
RecivedImageObj->Draw (m_hdc,local_wnd_x,local_wnd_y,
IMAGE_WIDTH,IMAGE_HEIGHT,0,0,IMAGE_WIDTH,IMAGE_HEI
GHT);
}
if(SendMyCAM == TRUE)
{
if ( JpegCreated == true )
{
int i = 0 , len = 0;
FILE * JpegFileRead;
unsigned char A[2];
if ( ( JpegFileRead = fopen ( "CaptureFrame.jpg" , "rb+") ) ==
NULL )
{
78
AfxMessageBox ( "File CaptureFrame.jpg can't open" );
return;
}
while(!feof(JpegFileRead))
{
fread(A , sizeof(unsigned char) , 1 , JpegFileRead) ;
sendData[i] = A[0];
i++;
}
fclose ( JpegFileRead) ;
videoSocket.SendVideoData ( sendData , i );
}
}
}
void CChatBox::StartTextChat()
{
if(TextChatStarted)
return;
TextChatStarted=TRUE;
// Enable / Disable menu items...
menu->EnableMenuItem(CHAT_DISCONNECT,MF_ENABLED);
menu->EnableMenuItem(REQ_CAM,MF_ENABLED);
if ( MyCAMStarted )
{
menu->EnableMenuItem(INVITE_CAM,MF_ENABLED);
InviteCAMEnable = TRUE ;
}
// Create Socket for text data transfer.
textSocket.CreateSocket(PORT_TEXTDATA,TYPE_TEXTDATA);
// Enable the send button
SendButton->EnableWindow(TRUE);
// Create Socket for video data transfer.
videoSocket.CreateSocket(PORT_VIDEODATA,TYPE_VIDEODATA);
79
ConnectButton->EnableWindow(FALSE);
CancelConnectButton->EnableWindow(FALSE);
}
void CChatBox::StopTextChat()
{
if(TextChatStarted==FALSE)
return;
TextChatStarted=FALSE;
// Enable/disable menu items
menu->EnableMenuItem(CHAT_DISCONNECT,MF_DISABLED |
MF_GRAYED);
// Close the Text tranfsfer
textSocket.CloseSocket();
// Disable the send button.
SendButton->EnableWindow(FALSE);
// Clear the contents of text chat windows
SetDlgItemText(IDC_EDIT1,"");
ChatListBox->ResetContent();
//Close the Video Transfer
videoSocket.CloseSocket();
// Update local and remote sytem CAM viewing Windows.
CWnd * wnd=(CWnd*)this->GetDlgItem(IDC_REMOTEVIDEO);
wnd->Invalidate(TRUE);
SendMyCAM=FALSE;
ReceiveCAM=FALSE;
menu->EnableMenuItem(INVITE_CAM,MF_GRAYED);
menu->EnableMenuItem(REQ_CAM,MF_GRAYED);
menu->EnableMenuItem(STOP_GUESTCAM,MF_GRAYED);
ConnectButton->EnableWindow ( TRUE );
CancelConnectButton->EnableWindow ( TRUE );
80
}
// When CONNECT Button Pressed.
void CChatBox::OnConnect()
{
char hostname[200];
this->GetDlgItemText(IDC_EDIT2,hostname,200); //Get the data from the Box.
SetDlgItemText(IDC_EDIT2,"");
// Clear the Box
controlMSGSocket.SendControlMessage(CONTROLMESG_CONNECT,hostna
me); //Send the Connection Request to Remote system.
}
//When CANCEL Button Pressed.
void CChatBox::OnCancelConnect()
{
SetDlgItemText(IDC_EDIT2,"");
// Clear the Box.
}
// When Add Contact Button Pressed
void CChatBox::OnAddContact()
{
addContactdlg->DoModal();
// Call the Contact Dialogue.
}
//Delete A Contact From the Contact List
void CChatBox::OnDeleteContct()
{
int index = 100;
CString DeleteData , CompareData;
//Get the Selected Contact and Delete it.
index = ContactListBox.GetCaretIndex();
ContactListBox.GetText ( index ,DeleteData );
ContactListBox.DeleteString ( index );
SetDlgItemText(IDC_EDIT2,"");
//Update the ContactFile Entries.
ContactListFile.Open("ContactFile.log",CFile::modeCreate |
CFile::modeNoTruncate | CFile::modeRead);
lengthOfFile = ContactListFile.GetLength();
if ( lengthOfFile )
{
int i = 0 , j = 0;
81
char * Buffer = NULL;
char contact[300] = "";
Buffer = new char [lengthOfFile];
ContactListFile.SeekToBegin();
ContactListFile.Read ( Buffer , lengthOfFile );
ContactListFile.Close();
ContactListFile.Open ( "ContactFile.log" , CFile::modeCreate |
CFile::modeWrite );
for ( i = 0 ; i < lengthOfFile ; i++ , j++ )
{
if ( Buffer[i] != '\n' )
contact[j] = Buffer[i];
else
{
contact[j] = '\0';
j = 0;
if ( DeleteData.Compare ( contact ) )
{
ContactListFile.SeekToEnd();
ContactListFile.Write ( contact , strlen ( contact ) );
ContactListFile.Write ( "\n" , 1 );
}
}
}
ContactListFile.Close ();
}
}
//Contact List notify function.
void CChatBox::OnContactSelect()
{
int index = 0;
int curPos= 0;
CString ContactListIP, ConnectBoxIP;
index = ContactListBox.GetCaretIndex();
ContactListBox.GetText ( index , ContactListIP );
ContactListIP.MakeReverse();
ConnectBoxIP = ContactListIP.Tokenize(" ",curPos);
82
ConnectBoxIP.MakeReverse();
SetDlgItemText(IDC_EDIT2,ConnectBoxIP);
}
// Initializing the CAM
BOOL CChatBox::CAMInitialize()
{
int index=0;
captureWindow = capCreateCaptureWindow("Capture",WS_POPUP,0,0,1,1,0,0);
//Create Capture Window
if(captureWindow==NULL)
return FALSE;
capSetUserData(captureWindow,this);
capSetCallbackOnFrame(captureWindow,OnCaptureVideo);//Set the Callback
Function.
// Connect to webcam driver
if( ! capDriverConnect(captureWindow,index) )
{
// Device may be open already or it may not have been closed properly last time.
AfxMessageBox("Unable to open Video Capture Device");
captureWindow=NULL;
return FALSE;
}
// Set the capture parameters
if(SetCaptureParameters()==FALSE)
{
capDriverDisconnect(captureWindow);
return FALSE;
}
return TRUE;
}
//Thread to perforn the Capturing.
UINT CChatBox::StartVideoCapture (LPVOID ThreadParameter)
{
THREADSTRUCT * ThreadStructObj = (THREADSTRUCT*)
ThreadParameter;
CImage * CaptureImage = new CImage;
threadRun = TRUE;
83
// Start the Capturing
while ( threadRun == TRUE )
{
capGrabFrame ( ThreadStructObj->_this->captureWindow );
if ( capFileSaveDIB ( ThreadStructObj->_this->captureWindow ,
"CaptureFrame.bmp" ) )
//Save as BMP file.
{
// Convert to JPEG image.
CString CaptureFramePath = _T("CaptureFrame.bmp");
HRESULT hResult = CaptureImage->Load(CaptureFramePath);
hResult = CaptureImage->Save(_T("CaptureFrame.jpg"));
JpegCreated = true;
}
Sleep(100);
}
delete CaptureImage;
return 1;
}
BOOL CChatBox::StartCapture()
{
THREADSTRUCT * ThreadParameter = new THREADSTRUCT;
ThreadParameter->_this = this;
AfxBeginThread (StartVideoCapture, ThreadParameter);
//Creating the thread.
return TRUE;
}
BOOL CChatBox::StopCapture()
{
capCaptureStop(captureWindow);
capCaptureAbort(captureWindow);
threadRun = FALSE;
Sleep(2000);
return TRUE;
}
void CChatBox::CAMDestroy()
{
if(captureWindow==NULL)
return;
84
// Stop the capturing process
capCaptureAbort(captureWindow);
// Disable the callback function..
capSetCallbackOnVideoStream(captureWindow, NULL);
Sleep(300);
// This delay is important...
// Disconnect the CAM driver
capDriverDisconnect(captureWindow);
}
BOOL CChatBox::SetCaptureParameters()
{
CAPTUREPARMS CapParms={0};
capCaptureGetSetup(captureWindow,&CapParms,sizeof(CapParms));
CapParms.fAbortLeftMouse = FALSE;
CapParms.fAbortRightMouse = FALSE;
CapParms.fYield = TRUE;
CapParms.wPercentDropForError = 50;
if(capCaptureSetSetup(captureWindow,&CapParms,sizeof(CapParms))==FALSE
)
return FALSE;
// Set Video Format
capGetVideoFormat(captureWindow,&m_bmpinfo,sizeof(m_bmpinfo));
VidCap_bmpinfo.bmiHeader.biWidth=IMAGE_WIDTH;
VidCap_bmpinfo.bmiHeader.biHeight=IMAGE_HEIGHT;
BOOL
ret=capSetVideoFormat(captureWindow,&VidCap_bmpinfo,sizeof(VidCap_bmpinfo));
return TRUE;
}
LRESULT CALLBACK OnCaptureVideo(HWND mwnd,LPVIDEOHDR lphdr)
{
CChatBox * vidcapObj = ( CChatBox * ) capGetUserData ( mwnd ) ;
if(vidcapObj!=NULL )
{
85
vidcapObj->SendNDisplayVideo();
}
return TRUE;
}
// Disconnect the CAM
void CChatBox::CAMDisconnected()
{
ReceiveCAM = FALSE;
menu->EnableMenuItem ( REQ_CAM , MF_ENABLED );
menu->EnableMenuItem(STOP_GUESTCAM,MF_GRAYED);
CWnd * wnd=(CWnd*)this->GetDlgItem(IDC_REMOTEVIDEO);
wnd->Invalidate(TRUE);
}
//Stop Viewing the Guest CAM
void CChatBox::StopViewGuestCAM ()
{
StopGuestCAM = TRUE;
controlMSGSocket.SendControlMessage(CONTROLMESG_STOPVIEWCAM,
NULL);
menu->EnableMenuItem ( STOP_GUESTCAM , MF_GRAYED );
menu->EnableMenuItem ( REQ_CAM , MF_ENABLED );
}
86
AddContactDlg.h
#pragma once
#include "afxcmn.h"
// CAddContactDlg dialog
class CAddContactDlg : public CDialog
{
DECLARE_DYNAMIC(CAddContactDlg)
// Attributes
public:
CDialog *mdlg;
CAddContactDlg(CWnd* pParent = NULL); // standard constructor
virtual ~CAddContactDlg();
CIPAddressCtrl ConnectIP;
void SetParent(CDialog *dlg);
afx_msg void OnAddContct();
afx_msg void OnClose();
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedCancel();
DECLARE_MESSAGE_MAP()
// Dialog Data
enum { IDD = IDD_DIALOG2 };
protected:
virtual void DoDataExchange(CDataExchange* pDX);
support
};
// DDX/DDV
87
ConnectCAMInvitation..h
#if
!defined(AFX_CONNECTCAMINVITATION_H__5FB1D083_5F66_11D6_8897_000
B2B0F84B6__INCLUDED_)
#define
AFX_CONNECTCAMINVITATION_H__5FB1D083_5F66_11D6_8897_000B2B0F84
B6__INCLUDED_
#pragma once
// CConnectCAMInvitation dialog
class CConnectCAMInvitation : public CDialog
{
DECLARE_DYNAMIC(CConnectCAMInvitation)
public:
char remoteName[500];
char remoteAddress[500];
CDialog *pdlg;
CConnectCAMInvitation(CWnd* pParent = NULL); // standard
constructor
virtual ~CConnectCAMInvitation();
afx_msg BOOL OnInitDialog();
afx_msg void OnConnectionAccept();
afx_msg void OnConnectionReject();
void SetParameter(char *hostname,char *hostaddress,CDialog *dlg) ;
DECLARE_MESSAGE_MAP()
// Dialog Data
enum { IDD = IDD_DIALOG5 };
protected:
virtual void DoDataExchange(CDataExchange* pDX);
support
};
#endif
// DDX/DDV
88
ConnectCAMInvitation.cpp
#include "stdafx.h"
#include "VideoOverLan.h"
#include "ConnectCAMInvitation.h"
#include "ChatBox.h"
// CConnectCAMInvitation dialog
IMPLEMENT_DYNAMIC(CConnectCAMInvitation, CDialog)
CConnectCAMInvitation::CConnectCAMInvitation(CWnd* pParent /*=NULL*/)
: CDialog(CConnectCAMInvitation::IDD, pParent)
{
}
CConnectCAMInvitation::~CConnectCAMInvitation()
{
}
void CConnectCAMInvitation::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CConnectCAMInvitation, CDialog)
ON_BN_CLICKED(IDOK, OnConnectionAccept)
ON_BN_CLICKED(IDCANCEL, OnConnectionReject)
END_MESSAGE_MAP()
// CConnectCAMInvitation message handlers
BOOL CConnectCAMInvitation::OnInitDialog()
{
CDialog::OnInitDialog();
char str[600];
89
sprintf(str,"Invitation to View %s CAM",remoteName);
this->SetDlgItemText(IDC_CAMINV,str);
return TRUE;
}
void CConnectCAMInvitation::SetParameter(char *hostname,char *hostaddress,CDialog
*dlg)
{
strcpy(remoteName,hostname);
strcpy(remoteAddress,hostaddress);
pdlg=dlg;
}
// When Accept button Pressed.
void CConnectCAMInvitation::OnConnectionAccept()
{
this->OnCancel();
// Send notification to remote user
( ( CChatBox * ) pdlg )->controlMSGSocket.SendControlMessage (
CONTROLMESG_ACCEPTCAMINV , NULL );
// Start the Receiving of Video
( ( CChatBox * ) pdlg )->menu->EnableMenuItem ( REQ_CAM , MF_GRAYED
);
( ( CChatBox * ) pdlg )->ReceiveCAM = TRUE;
( ( CChatBox * ) pdlg )->StopGuestCAM = FALSE;
}
// When Connection is Rejected.
void CConnectCAMInvitation::OnConnectionReject()
{
// Send notification to remote user
( ( CChatBox * ) pdlg )->controlMSGSocket.SendControlMessage (
CONTROLMESG_REJECTCAMINV , NULL );
CDialog::OnCancel();
}
90
ConnectCAMRequest.h
#if
!defined(AFX_CONNECTCAMREQUEST_H__5FB1D083_5F66_11D6_8897_000B2B
0F84B6__INCLUDED_)
#define
AFX_CONNECTCAMREQUEST_H__5FB1D083_5F66_11D6_8897_000B2B0F84B6
__INCLUDED_
#pragma once
// CConnectCAMRequest dialog
class CConnectCAMRequest : public CDialog
{
DECLARE_DYNAMIC(CConnectCAMRequest)
public:
char remoteName[500];
char remoteAddress[500];
CDialog *pdlg;
CConnectCAMRequest(CWnd* pParent = NULL); // standard
constructor
virtual ~CConnectCAMRequest();
afx_msg BOOL OnInitDialog();
afx_msg void OnConnectionAccept();
afx_msg void OnConnectionReject();
void SetParameter(char *hostname,char *hostaddress,CDialog *dlg) ;
DECLARE_MESSAGE_MAP()
// Dialog Data
enum { IDD = IDD_DIALOG4 };
protected:
virtual void DoDataExchange(CDataExchange* pDX);
support
};
#endif
// DDX/DDV
91
ConnectCAMRequest.cpp
#include "stdafx.h"
#include "VideoOverLan.h"
#include "ConnectCAMRequest.h"
#include "ChatBox.h"
// CConnectCAMRequest dialog
IMPLEMENT_DYNAMIC(CConnectCAMRequest, CDialog)
CConnectCAMRequest::CConnectCAMRequest(CWnd* pParent /*=NULL*/)
: CDialog(CConnectCAMRequest::IDD, pParent)
{
}
CConnectCAMRequest::~CConnectCAMRequest()
{
}
void CConnectCAMRequest::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CConnectCAMRequest, CDialog)
ON_BN_CLICKED(IDOK, OnConnectionAccept)
ON_BN_CLICKED(IDCANCEL, OnConnectionReject)
END_MESSAGE_MAP()
// CConnectCAMRequest message handlers
BOOL CConnectCAMRequest::OnInitDialog()
{
CDialog::OnInitDialog();
92
char str[600];
sprintf(str,"Request to View Your CAM from user %s ",remoteName);
this->SetDlgItemText(IDC_CAMREQ,str);
return TRUE;
}
/**
* Set remote user name and address
*/
void CConnectCAMRequest::SetParameter(char *hostname,char *hostaddress,CDialog
*dlg)
{
strcpy(remoteName,hostname);
strcpy(remoteAddress,hostaddress);
pdlg=dlg;
}
void CConnectCAMRequest::OnConnectionAccept()
{
this->OnCancel();
// Send notification to remote user
((CChatBox*)pdlg)>controlMSGSocket.SendControlMessage(CONTROLMESG_ACCEPTCAMREQ,NUL
L);
// Start the Sending of Video
((CChatBox*)pdlg)->menu->EnableMenuItem ( INVITE_CAM ,
MF_GRAYED );
((CChatBox*)pdlg)->SendMyCAM = TRUE;
}
void CConnectCAMRequest::OnConnectionReject()
{
// Send notification to remote user
((CChatBox*)pdlg)>controlMSGSocket.SendControlMessage(CONTROLMESG_REJECTCAMREQ,NUL
L);
93
CDialog::OnCancel();
}
ConnectionRequestDlg.h
#if
!defined(AFX_CONNECTIONREQUESTDLG_H__5FB1D083_5F66_11D6_8897_000
B2B0F84B6__INCLUDED_)
#define
AFX_CONNECTIONREQUESTDLG_H__5FB1D083_5F66_11D6_8897_000B2B0F84
B6__INCLUDED_
class ConnectionRequestDlg : public CDialog
{
public:
char rname[500];
char raddress[500];
CDialog *pdlg;
ConnectionRequestDlg(CWnd* pParent = NULL); // standard
constructor
afx_msg BOOL OnInitDialog();
afx_msg void OnConnectionAccept();
afx_msg void OnConnectionReject();
void SetParameter(char *hostname,char *hostaddress,CDialog *dlg) ;
DECLARE_MESSAGE_MAP()
// Dialog Data
enum { IDD = IDD_DIALOG3 };
protected:
virtual void DoDataExchange(CDataExchange* pDX);
support
};
#endif
// DDX/DDV
94
ConnectionRequestDlg.cpp
#include "stdafx.h"
#include "VideoOverLan.h"
#include "ConnectionRequestDlg.h"
#include "VideoOverLanDlg.h"
#include "ChatBox.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
ConnectionRequestDlg::ConnectionRequestDlg(CWnd* pParent /*=NULL*/)
: CDialog(ConnectionRequestDlg::IDD, pParent)
{
}
void ConnectionRequestDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(ConnectionRequestDlg, CDialog)
ON_BN_CLICKED(IDOK, OnConnectionAccept)
ON_BN_CLICKED(IDREJECT, OnConnectionReject)
END_MESSAGE_MAP()
BOOL ConnectionRequestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
char str[600];
sprintf(str,"Connection request from user %s ",rname);
95
this->SetDlgItemText(IDC_MESG,str);
return TRUE;
}
/**
* Set remote user name and IP address
*/
void ConnectionRequestDlg::SetParameter(char *hostname,char *hostaddress,CDialog
*dlg)
{
strcpy(rname,hostname);
strcpy(raddress,hostaddress);
pdlg=dlg;
}
// If User Accept the Connection.
void ConnectionRequestDlg::OnConnectionAccept()
{
this->OnCancel();
// Send notification to remote user
((CChatBox*)pdlg)>controlMSGSocket.SendControlMessage(CONTROLMESG_ACCEPT,NULL);
// Initialize the Connection
((CChatBox*)pdlg)->StartTextChat();
}
// If user Reject the Request.
void ConnectionRequestDlg::OnConnectionReject()
{
// Send notification to remote user
((CChatBox*)pdlg)>controlMSGSocket.SendControlMessage(CONTROLMESG_REJECT,NULL);
CDialog::OnCancel();
}
96
REFERENCES
[1] Shepherd, George (1996). MFC Internals. Addison-Wesley.
[2] Heremiah Scholl, John D. McCarthy, Angela Sasse, Peter Parnes: Designing a
Large-Scale Video Chat Application.
http://portal.acm.org.proxy.lib.csus.edu/results.cfm?h=1&cfid=114120636&cftoken=
62364332
[3] Daly-Jones, O., Monk, A. & Watts, L. (1998). Some advantages of video
conferencing over high-quality audio conferencing: Fluency and awareness of
attentional focus, International Journal of Human Computer Studies, 49, 1 (1998), 2158.
[4] Nardi, B.A., Whittaker, S., Bradner, E., Interaction and outeraction: instant
messaging in action. In Proc. CSCW 2000, ACM Press (2000)
[5] MSDN Library
http://msdn.microsoft.com/en-us/library/ms123401.aspx
[6] Visual C++ Libraries
http://msdn.microsoft.com/en-us/library/52cs05fz(VS.71).aspx
[7] Niranjan Babu Kalla. (2004, January), “What is the .NET Framework?” [Online],
Available: http://www.aspfree.com/c/a/.NET/What-is-the-NET-Framework/
[8] http://ondotnet.com/pub/a/dotnet/2002/11/18/everettcpp.html
[9] http://www.sockets.com/winsock2.htm#Architecture
97
[10] http://lists.freebsd.org/pipermail/freebsd-performance/2005February/001143.html
[11] http://www.cs.cf.ac.uk/Dave/C/node28.html
[12] http://software.intel.com/en-us/articles/use-the-microsoft-c-compiler-for-thepentium-m-processor/
[13] MFC Document/View architecture
http://www.sethi.org/classes/comp270/lab_notes/lab_11_mfc_doc_view_wizards.htm
l
Download