孙鑫 MFC 学习 聊天室程序

以下是在vs2008上写的孙鑫老师第十五讲中的聊天室程序,里面花时间最多的是CString、string和char*之间的转换。 由于初学,目前的解决办法中将 字符集 进行了设置,不知道这样对程序的健壮性或者可移植性有没有影响,不管怎样,实现出来了。下面是设置字符集的截图。

 

 

下面是 ChatDlg.h 文件

ChatDlg.h
 1 // ChatDlg.h : 头文件
2 //
3
4 #pragma once
5
6 #define WM_RECVDATA WM_USER + 1
7
8 typedef struct
9 {
10 SOCKET sock;
11 HWND hwnd;
12 }PARAM, *PPARAM;
13
14 // CChatDlg 对话框
15 class CChatDlg : public CDialog
16 {
17 // 构造
18 public:
19 CChatDlg(CWnd* pParent = NULL); // 标准构造函数
20
21 // 对话框数据
22 enum { IDD = IDD_CHAT_DIALOG };
23
24 protected:
25 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
26
27
28 // 实现
29 protected:
30 HICON m_hIcon;
31
32 // 生成的消息映射函数
33 virtual BOOL OnInitDialog();
34 afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
35 afx_msg void OnPaint();
36 afx_msg HCURSOR OnQueryDragIcon();
37 afx_msg LRESULT OnRecvData(WPARAM wParam, LPARAM lParam);
38 DECLARE_MESSAGE_MAP()
39 private:
40 SOCKET m_socket;
41 public:
42 bool initSocket(void);
43 static DWORD WINAPI RecvProc(LPVOID lpParameter);
44 afx_msg void OnBnClickedBtnSend();
45 };

下面是 ChatDlg.cpp 文件

ChatDlg.cpp
  1 // ChatDlg.cpp : 实现文件
2 //
3
4 #include "stdafx.h"
5 #include "Chat.h"
6 #include "ChatDlg.h"
7 #include <string>
8
9 #ifdef _DEBUG
10 #define new DEBUG_NEW
11 #endif
12
13
14 // 用于应用程序“关于”菜单项的 CAboutDlg 对话框
15
16 class CAboutDlg : public CDialog
17 {
18 public:
19 CAboutDlg();
20
21 // 对话框数据
22 enum { IDD = IDD_ABOUTBOX };
23
24 protected:
25 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
26
27 // 实现
28 protected:
29 DECLARE_MESSAGE_MAP()
30 };
31
32 CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
33 {
34 }
35
36 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
37 {
38 CDialog::DoDataExchange(pDX);
39 }
40
41 BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
42 END_MESSAGE_MAP()
43
44
45 // CChatDlg 对话框
46
47
48
49
50 CChatDlg::CChatDlg(CWnd* pParent /*=NULL*/)
51 : CDialog(CChatDlg::IDD, pParent)
52 {
53 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
54 }
55
56 void CChatDlg::DoDataExchange(CDataExchange* pDX)
57 {
58 CDialog::DoDataExchange(pDX);
59 }
60
61 BEGIN_MESSAGE_MAP(CChatDlg, CDialog)
62 ON_WM_SYSCOMMAND()
63 ON_WM_PAINT()
64 ON_WM_QUERYDRAGICON()
65 ON_MESSAGE(WM_RECVDATA, OnRecvData)
66 //}}AFX_MSG_MAP
67 ON_BN_CLICKED(IDC_BTN_SEND, &CChatDlg::OnBnClickedBtnSend)
68 END_MESSAGE_MAP()
69
70
71 // CChatDlg 消息处理程序
72
73 BOOL CChatDlg::OnInitDialog()
74 {
75 CDialog::OnInitDialog();
76
77 // 将“关于...”菜单项添加到系统菜单中。
78
79 // IDM_ABOUTBOX 必须在系统命令范围内。
80 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
81 ASSERT(IDM_ABOUTBOX < 0xF000);
82
83 CMenu* pSysMenu = GetSystemMenu(FALSE);
84 if (pSysMenu != NULL)
85 {
86 CString strAboutMenu;
87 strAboutMenu.LoadString(IDS_ABOUTBOX);
88 if (!strAboutMenu.IsEmpty())
89 {
90 pSysMenu->AppendMenu(MF_SEPARATOR);
91 pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
92 }
93 }
94
95 // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
96 // 执行此操作
97 SetIcon(m_hIcon, TRUE); // 设置大图标
98 SetIcon(m_hIcon, FALSE); // 设置小图标
99
100 // TODO: 在此添加额外的初始化代码
101 if (!initSocket())
102 {
103 return false;
104 }
105
106 PPARAM pparam= new PARAM;
107 pparam->sock = this->m_socket;
108 pparam->hwnd = m_hWnd;
109 HANDLE hThread = CreateThread(NULL, 0, RecvProc, (LPVOID)pparam, 0, NULL);
110 CloseHandle(hThread);
111
112
113 return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
114 }
115
116 void CChatDlg::OnSysCommand(UINT nID, LPARAM lParam)
117 {
118 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
119 {
120 CAboutDlg dlgAbout;
121 dlgAbout.DoModal();
122 }
123 else
124 {
125 CDialog::OnSysCommand(nID, lParam);
126 }
127 }
128
129 // 如果向对话框添加最小化按钮,则需要下面的代码
130 // 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
131 // 这将由框架自动完成。
132
133 void CChatDlg::OnPaint()
134 {
135 if (IsIconic())
136 {
137 CPaintDC dc(this); // 用于绘制的设备上下文
138
139 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
140
141 // 使图标在工作区矩形中居中
142 int cxIcon = GetSystemMetrics(SM_CXICON);
143 int cyIcon = GetSystemMetrics(SM_CYICON);
144 CRect rect;
145 GetClientRect(&rect);
146 int x = (rect.Width() - cxIcon + 1) / 2;
147 int y = (rect.Height() - cyIcon + 1) / 2;
148
149 // 绘制图标
150 dc.DrawIcon(x, y, m_hIcon);
151 }
152 else
153 {
154 CDialog::OnPaint();
155 }
156 }
157
158 //当用户拖动最小化窗口时系统调用此函数取得光标
159 //显示。
160 HCURSOR CChatDlg::OnQueryDragIcon()
161 {
162 return static_cast<HCURSOR>(m_hIcon);
163 }
164
165
166 bool CChatDlg::initSocket(void)
167 {
168 this->m_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
169 if (this->m_socket == SOCKET_ERROR)
170 {
171 AfxMessageBox("创建套接字失败!");
172 return false;
173 }
174
175 sockaddr_in addr;
176 addr.sin_family = AF_INET;
177 addr.sin_port = htons(4444);
178 addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
179
180 int retVal;
181 retVal = bind(m_socket, (SOCKADDR*)&addr, sizeof(SOCKADDR));
182 if (retVal == SOCKET_ERROR)
183 {
184 AfxMessageBox("绑定套接字失败!");
185 return false;
186 }
187
188 return true;
189 }
190
191 DWORD CChatDlg::RecvProc(LPVOID lpParameter)
192 {
193 SOCKET sock = ((PPARAM)lpParameter)->sock;
194 HWND hwnd = ((PPARAM)lpParameter)->hwnd;
195
196 sockaddr_in addrFrom;
197 int length = sizeof(SOCKADDR);
198
199 char recvBuf[200];
200 char tempBuf[300];
201
202
203 int retVal;
204 while (TRUE)
205 {
206 retVal = recvfrom(sock, recvBuf, 200, 0, (SOCKADDR*)&addrFrom, &length);
207 if (retVal == SOCKET_ERROR)
208 {
209 break;
210 }
211
212 sprintf(tempBuf, "%s说: %s", inet_ntoa(addrFrom.sin_addr), recvBuf);
213 ::PostMessage(hwnd, WM_RECVDATA, 0, (LPARAM)tempBuf);
214 }
215
216
217
218
219 return 0;
220 }
221
222
223 LRESULT CChatDlg::OnRecvData(WPARAM wParam, LPARAM lParam)
224 {
225 CString str = CString((LPCSTR)lParam);
226 CString strTemp;
227 GetDlgItemText(IDC_EDIT_RECEIVE, strTemp);
228 str += "\r\n";
229 str = strTemp + str;
230
231 SetDlgItemText(IDC_EDIT_RECEIVE, str);
232
233
234 return 0;
235 }
236 void CChatDlg::OnBnClickedBtnSend()
237 {
238 // TODO: 在此添加控件通知处理程序代码
239
240 DWORD dwIP;
241
242 ((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS))->GetAddress(dwIP);
243
244 sockaddr_in addrTo;
245 addrTo.sin_family = AF_INET;
246 addrTo.sin_port = htons(4444);
247 addrTo.sin_addr.S_un.S_addr = htonl(dwIP);
248
249 CString msg;
250 GetDlgItemText(IDC_EDIT_SEND, msg);
251 std::string strMsg(msg.GetBuffer());
252 sendto(m_socket, strMsg.c_str(), msg.GetLength()+1,0,(SOCKADDR*)&addrTo, sizeof(SOCKADDR));
253
254 SetDlgItemText(IDC_EDIT_SEND, "");
255 }



 

 

转载于:https://www.cnblogs.com/hanyuanbo/archive/2012/03/28/2420952.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值