實現類似qq的聊天小程序

這個程序是室友編的,由於自己現在對MFC還不瞭解吧,先放這裏吧以後好用(環境VS2010)
主函數:
// Chat.cpp : 定義應用程序的類行爲。
//
#include "stdafx.h"
#include "Chat.h"
#include "ChatDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 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()
{
 CWinApp::InitInstance();
 if (!AfxSocketInit())
 {
  AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
  return FALSE;
 }


 // 創建 shell 管理器,以防對話框包含
 // 任何 shell 樹視圖控件或 shell 列表視圖控件。
 CShellManager *pShellManager = new CShellManager;
 // 標準初始化
 // 如果未使用這些功能並希望減小
 // 最終可執行文件的大小,則應移除下列
 // 不需要的特定初始化例程
 // 更改用於存儲設置的註冊表項
 // TODO: 應適當修改該字符串,
 // 例如修改爲公司或組織名
 SetRegistryKey(_T("應用程序嚮導生成的本地應用程序"));
 CChatDlg dlg;
 m_pMainWnd = &dlg;
 INT_PTR nResponse = dlg.DoModal();
 if (nResponse == IDOK)
 {
  // TODO: 在此放置處理何時用
  //  “確定”來關閉對話框的代碼
 }
 else if (nResponse == IDCANCEL)
 {
  // TODO: 在此放置處理何時用
  //  “取消”來關閉對話框的代碼
 }
 // 刪除上面創建的 shell 管理器。
 if (pShellManager != NULL)
 {
  delete pShellManager;
 }
 // 由於對話框已關閉,所以將返回 FALSE 以便退出應用程序,
 //  而不是啓動應用程序的消息泵。
 return FALSE;
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
另外一個cpp文件:
 
// ChatDlg.cpp : 實現文件
//
#include "stdafx.h"
#include "Chat.h"
#include "ChatDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CChatDlg 對話框
 


CChatDlg::CChatDlg(CWnd* pParent )
 : CDialogEx(CChatDlg::IDD, pParent)
{
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CChatDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CChatDlg, CDialogEx)
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 ON_BN_CLICKED(IDOK, &CChatDlg::OnBnClickedOk)
 ON_MESSAGE(WM_RECVDATA,(LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM))OnRecvData)
 
END_MESSAGE_MAP()


// CChatDlg 消息處理程序
BOOL CChatDlg::OnInitDialog()
{
 CDialogEx::OnInitDialog();
 // 設置此對話框的圖標。當應用程序主窗口不是對話框時,框架將自動
 //  執行此操作
 SetIcon(m_hIcon, TRUE);   // 設置大圖標
 SetIcon(m_hIcon, FALSE);  // 設置小圖標
 // TODO: 在此添加額外的初始化代碼
 char hostport[100];
 char toipaddr[100];
 char toport[100];
 char hostname[256];
 GetPrivateProfileString("HOSTINFO","HOSTPORT","6500",hostport,100,".\\init.ini");
 GetPrivateProfileString("TOINFO","TOIPADDR","127.0.0.1",toipaddr,100,".\\init.ini");
 GetPrivateProfileString("TOINFO","TOPORT","6500",toport,100,".\\init.ini");
 
 gethostname(hostname,256);
 HOSTENT *hostinfo=gethostbyname(hostname);
 ((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESSHOST))->SetAddress(hostinfo->h_addr_list[0][0]&0x00ff,
                 hostinfo->h_addr_list[0][1]&0x00ff,
                 hostinfo->h_addr_list[0][2]&0x00ff,
                 hostinfo->h_addr_list[0][3]&0x00ff);
 SetDlgItemText(IDC_EDITHOST,hostport);
 
 
 DWORD dwIP;
 ((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESSHOST))->GetAddress(dwIP);
 IN_ADDR addbuf;
 addbuf.S_un.S_addr=htonl(dwIP);
 WritePrivateProfileString("HOSTINFO","HOSTIP",inet_ntoa(addbuf),".\\init.ini");
 
 host_socket=socket(AF_INET,SOCK_DGRAM,0);
 if(INVALID_SOCKET==host_socket)
 {
  MessageBox("套接字創建失敗!");
  return FALSE;
 }


 
 host_addrSock.sin_family=AF_INET;
 host_addrSock.sin_port=htons((u_short)atoi(hostport));
 host_addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
 int retval;
 retval=bind(host_socket,(SOCKADDR*)&host_addrSock,sizeof(SOCKADDR));
 if(SOCKET_ERROR==retval)
 {
  closesocket(host_socket);
  MessageBox("綁定失敗!");
  return FALSE;
 }
 
 ((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESSTO))->SetAddress(htonl(inet_addr(toipaddr)));
 SetDlgItemText(IDC_EDIT_PORTTO,toport);
 RECVPARAM *pRecvParam=new RECVPARAM;
 pRecvParam->sock=host_socket;
 pRecvParam->hwnd=m_hWnd;
 HANDLE hThread=CreateThread(NULL,0,RecvProc,(LPVOID)pRecvParam,0,NULL);
 CloseHandle(hThread);
 return TRUE;
 
 return TRUE;  // 除非將焦點設置到控件,否則返回 TRUE
}
// 如果向對話框添加最小化按鈕,則需要下面的代碼
//  來繪製該圖標。對於使用文檔/視圖模型的 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
 {
  CDialogEx::OnPaint();
 }
}
//當用戶拖動最小化窗口時系統調用此函數取得光標
//顯示。
HCURSOR CChatDlg::OnQueryDragIcon()
{
 return static_cast<HCURSOR>(m_hIcon);
}
 
void CChatDlg::OnBnClickedOk()
{
 // TODO: 在此添加控件通知處理程序代碼
 DWORD dwIP;
 ((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESSTO))->GetAddress(dwIP);
 CString strPort;
 GetDlgItemText(IDC_EDIT_PORTTO,strPort);
 
 SOCKADDR_IN addrTo;    
 addrTo.sin_family=AF_INET;
 addrTo.sin_port=htons((unsigned short)atoi(strPort));
 addrTo.sin_addr.S_un.S_addr=htonl(dwIP);
 CString strSend;
 GetDlgItemText(IDC_EDIT_SEND,strSend);
 strSend+="\r\n";
 sendto(host_socket,strSend,strSend.GetLength()+1,0,(SOCKADDR*)&addrTo,sizeof(SOCKADDR));
 SetDlgItemText(IDC_EDIT_SEND,"");
 CString strMy="我  說:"+strSend;
 CString strTemp;
 GetDlgItemText(IDC_EDIT_RECV,strTemp); 
 strMy=strTemp+strMy;
 SetDlgItemText(IDC_EDIT_RECV,strMy);
 //CDialogEx::OnOK();
}


DWORD WINAPI CChatDlg::RecvProc(LPVOID lpParameter)
{
 SOCKET sock=((RECVPARAM*)lpParameter)->sock;
 HWND hwnd=((RECVPARAM*)lpParameter)->hwnd;
 delete lpParameter; 
 SOCKADDR_IN addrFrom;
 int len=sizeof(SOCKADDR);
 char recvBuf[200];
 char tempBuf[300];
 int retval;
 while(TRUE)
 {
  retval=recvfrom(sock,recvBuf,200,0,(SOCKADDR*)&addrFrom,&len);
  if(SOCKET_ERROR==retval)
   break;
  sprintf_s(tempBuf,"%s說: %s",inet_ntoa(addrFrom.sin_addr),recvBuf);
  ::PostMessage(hwnd,WM_RECVDATA,0,(LPARAM)tempBuf);
 }
 return 0;
}


void CChatDlg::OnRecvData(WPARAM wParam,LPARAM lParam)
{
 CString str=(char*)lParam;
 CString strTemp;
 GetDlgItemText(IDC_EDIT_RECV,strTemp);
 str=strTemp+str;
 SetDlgItemText(IDC_EDIT_RECV,str);
 
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
一些頭文件:
1:// 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;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2:// ChatDlg.h : 頭文件
//
#pragma once
typedef struct recvparam
{
 SOCKET sock;
 HWND hwnd;
}RECVPARAM;  
#define WM_RECVDATA  WM_USER+1
// CChatDlg 對話框
class CChatDlg : public CDialogEx
{
// 構造
public:
 CChatDlg(CWnd* pParent = NULL); // 標準構造函數
// 對話框數據
 enum { IDD = IDD_CHAT_DIALOG };
 protected:
 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持


// 實現
 static DWORD WINAPI RecvProc(LPVOID lpParameter);
protected:
 HICON m_hIcon;
 // 生成的消息映射函數
 virtual BOOL OnInitDialog();
 afx_msg void OnPaint();
 afx_msg HCURSOR OnQueryDragIcon();
 afx_msg void OnRecvData(WPARAM wParam,LPARAM lParam);
 DECLARE_MESSAGE_MAP()
public:
 afx_msg void OnBnClickedOk();


private:
 SOCKET host_socket;  //本機套接字
 SOCKADDR_IN host_addrSock;
public:


 
};
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3://{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Chat.rc
//
#define IDD_CHAT_DIALOG                 102
#define IDP_SOCKETS_INIT_FAILED         103
#define IDR_MAINFRAME                   128
#define IDC_IPADDRESSTO                 1000
#define IDC_EDIT_SEND                   1001
#define IDC_EDIT_RECV                   1002
#define IDC_EDIT_PORTTO                 1003
#define IDC_IPADDRESSHOST               1004
#define IDC_EDIT1                       1005
#define IDC_EDITHOST                    1005
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        129
#define _APS_NEXT_COMMAND_VALUE         32771
#define _APS_NEXT_CONTROL_VALUE         1006
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4:// stdafx.h : 標準系統包含文件的包含文件,
// 或是經常使用但不常更改的
// 特定於項目的包含文件
#pragma once
#ifndef _SECURE_ATL
#define _SECURE_ATL 1
#endif
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN            // 從 Windows 頭中排除極少使用的資料
#endif
#include "targetver.h"
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // 某些 CString 構造函數將是顯式的
// 關閉 MFC 對某些常見但經常可放心忽略的警告消息的隱藏
#define _AFX_ALL_WARNINGS
#include <afxwin.h>         // MFC 核心組件和標準組件
#include <afxext.h>         // MFC 擴展
 
 
#ifndef _AFX_NO_OLE_SUPPORT
#include <afxdtctl.h>           // MFC 對 Internet Explorer 4 公共控件的支持
#endif
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>             // MFC 對 Windows 公共控件的支持
#endif // _AFX_NO_AFXCMN_SUPPORT
#include <afxcontrolbars.h>     // 功能區和控件條的 MFC 支持


#include <afxsock.h>            // MFC 套接字擴展
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5:#pragma once
// 包括 SDKDDKVer.h 將定義最高版本的可用 Windows 平臺。
// 如果要爲以前的 Windows 平臺生成應用程序,請包括 WinSDKVer.h,並將
// WIN32_WINNT 宏設置爲要支持的平臺,然後再包括 SDKDDKVer.h。
#include <SDKDDKVer.h>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
基本的一些就是這些吧,貌似還有一下VS的頭文件就算了~
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章