// Chat.h : PROJECT_NAME 应用程序的主头文件
//
#pragma once
#ifndef __AFXWIN_H__
#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
#endif
#include "resource.h" // 主符号
// CChatApp:
// 有关此类的实现,请参阅 Chat.cpp
//
class CChatApp : public CWinApp
{
public:
CChatApp();
// 重写
public:
virtual BOOL InitInstance();
// 实现
DECLARE_MESSAGE_MAP()
};
extern CChatApp theApp;
// Chat.cpp : 定义应用程序的类行为。
//
#include "stdafx.h"
#include "Chat.h"
#include "ChatDlg.h"
//#ifdef _DEBUG
//#define new DEBUG_NEW
// CChatApp
BEGIN_MESSAGE_MAP(CChatApp, CWinApp)
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
// CChatApp 构造
CChatApp::CChatApp()
{
// TODO: 在此处添加构造代码,
// 将所有重要的初始化放置在 InitInstance 中
}
// 唯一的一个 CChatApp 对象
CChatApp theApp;
// CChatApp 初始化
BOOL CChatApp::InitInstance()
{
// 如果一个运行在 Windows XP 上的应用程序清单指定要
// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
//则需要 InitCommonControlsEx()。否则,将无法创建窗口。
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// 将它设置为包括所有要在应用程序中使用的
// 公共控件类。
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
AfxEnableControlContainer();
// 标准初始化
// 如果未使用这些功能并希望减小
// 最终可执行文件的大小,则应移除下列
// 不需要的特定初始化例程
// 更改用于存储设置的注册表项
// TODO: 应适当修改该字符串,
// 例如修改为公司或组织名
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
CChatDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: 在此放置处理何时用
// “确定”来关闭对话框的代码
}
else if (nResponse == IDCANCEL)
{
// TODO: 在此放置处理何时用
// “取消”来关闭对话框的代码
}
// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
// 而不是启动应用程序的消息泵。
return FALSE;
}
//#endif
// ChatDlg.h : 头文件
#include"Public.h"
#include"Server.h"
#include"Client.h"
#ifndef _CChatDlg_h_//用于防止头文件嵌套多次1
#define _CChatDlg_h_//用于防止头文件嵌套多次2
#include"Sound.h"
#pragma once
#define WM_DATAREACH WM_APP+110
#define CLIENT 1
#define SERVER 2
// CChatDlg 对话框
class CChatDlg : public CDialog
{
// 构造
public:
CChatDlg(CWnd* pParent = NULL); // 标准构造函数
// 对话框数据
enum { IDD = IDD_CHAT_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
// afx_msg void OnBnClickedButton3();
自定义数据/
public:
bool ServerFlag;//用于表示是否已经建立了服务器,没有则为false,已经建立则为true
bool ClientFlag;//用于表示是否已经连接了服务器,没有则为false,已经建立则为true
CServer Server;//用于服务器端的操作
CClient Client;//用于服务端的操作
CSound Sound;//用于音频操作
CString InPutCString;//用于保存输入窗口的文字数据
CString AllCString;//用于保存所有聊天记录的文字数据
int Mark;//用于标识是客户端还是服务器
bool SoundChat;//用于标识是否已经开始语音聊天,false表示没有,true表示已经建立语音聊天了
WAVEHDR *p;
自定义消息响应函数-开始/
LRESULT OnDataReach(WPARAM wParam, LPARAM lParam);//当有新数据到达时执行的代码
afx_msg LRESULT GetInBufferFull(WPARAM wp, LPARAM lp);//一个buffer满后调用
afx_msg LRESULT WriteOutBufferEmpty(WPARAM wp, LPARAM lp);//一个buffer播放完后调用
自定义消息响应函数-结束/
afx_msg void OnBnClickedLinkserver();
afx_msg void OnBnClickedBuildserver();
afx_msg void OnIpnFieldchangedIpaddress(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnBnClickedSend();
afx_msg void OnEnChangeChat();
afx_msg void OnBnClickedClose();
afx_msg void OnBnClickedVoicechat();
};
#endif//用于防止头文件嵌套多次3
// ChatDlg.cpp : 实现文件
#include "stdafx.h"
#include "ChatDlg.h"
//#include"Wmiutils.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// 对话框数据
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CChatDlg 对话框
CChatDlg::CChatDlg(CWnd* pParent /*=NULL*/)
: CDialog(CChatDlg::IDD, pParent)
{
ServerFlag=false;//初始化还没有建立服务器
ClientFlag=false;
Mark=0;
AllCString="";
SoundChat=false;
p=(WAVEHDR *)malloc(sizeof(WAVEHDR)+MAX_BUFFER_SIZE);
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CChatDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CChatDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
// ON_BN_CLICKED(IDC_BUTTON3, &CChatDlg::OnBnClickedButton3)
ON_BN_CLICKED(IDB_LINKSERVER, &CChatDlg::OnBnClickedLinkserver)
ON_BN_CLICKED(IDB_BUILDSERVER, &CChatDlg::OnBnClickedBuildserver)
ON_NOTIFY(IPN_FIELDCHANGED, IDI_IPADDRESS, &CChatDlg::OnIpnFieldchangedIpaddress)
//ON_WM_CREATE()
ON_BN_CLICKED(IDB_SEND, &CChatDlg::OnBnClickedSend)
用户自定义的消息-开始///
ON_MESSAGE(WM_DATAREACH,OnDataReach)
ON_MESSAGE(MM_WIM_DATA,GetInBufferFull)//一个buffer满了后调用
ON_MESSAGE(MM_WOM_DONE,WriteOutBufferEmpty)//buffer的内容被播放完了后,产生的消息调用这个函数
用户自定义的消息-结束///
//ON_EN_CHANGE(IDE_EDITCHAT, &CChatDlg::OnEnChangeEditchat)
//ON_EN_MAXTEXT(IDE_EDITCHAT, &CChatDlg::OnEnMaxtextEditchat)
//ON_EN_CHANGE(IDE_EDITCHAT, &CChatDlg::OnEnChangeEditchat)
ON_EN_CHANGE(IDE_CHAT, &CChatDlg::OnEnChangeChat)
ON_BN_CLICKED(IDB_CLOSE, &CChatDlg::OnBnClickedClose)
ON_BN_CLICKED(IDB_VOICECHAT, &CChatDlg::OnBnClickedVoicechat)
END_MESSAGE_MAP()
// CChatDlg 消息处理程序
BOOL CChatDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
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); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CChatDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CChatDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
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;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
///程序员添加代码-开始
((CIPAddressCtrl *)GetDlgItem(IDI_IPADDRESS))->SetAddress(::htonl(::inet_addr("192.168.177.29")));
((CEdit *)this->GetDlgItem(IDE_PORT))->SetWindowTextA("7000");
((CButton *)this->GetDlgItem(IDB_SEND))->SetFocus();//将焦点设置为发送按钮
///程序员添加代码-结束
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CChatDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CChatDlg::OnBnClickedLinkserver()
{
Client.InitM_dlg(this);
// TODO: 在此添加控件通知处理程序代码
if(ClientFlag==false)
{
Client.GetServerAddress();
if(Client.AddSocketLib()&&Client.CreateSocket()&&Client.ConnectSocket())
{
ClientFlag=true;
this->GetDlgItem(IDE_LINKSTATE)->SetWindowText("服务器连接成功");
Mark=CLIENT;
::WSAAsyncSelect(Client.ClientSocket,this->m_hWnd,
WM_DATAREACH,FD_OOB|FD_READ|FD_WRITE|FD_ACCEPT|FD_CLOSE|FD_CONNECT);
::WSAAsyncSelect(Client.ClientSocketSound,this->m_hWnd,
WM_DATAREACH,FD_OOB|FD_READ|FD_WRITE|FD_ACCEPT|FD_CLOSE|FD_CONNECT);
return ;
}
return ;
}
else
return ;
}
void CChatDlg::OnBnClickedBuildserver()
{
// TODO: 在此添加控件通知处理程序代码
Server.InitM_dlg(this);
if(ServerFlag==false)
{
Server.GetServerAddress();
if(Server.AddSocketLib()&&
Server.CreateSocket()&&
Server.BindSocket()&&
Server.ListeSocket()&&
Server.AcceptClient())
{
ServerFlag=true;
this->GetDlgItem(IDE_BUILDSTATE)->SetWindowText("服务器设置成功");
Mark=SERVER;
::WSAAsyncSelect(Server.C