目录
最终目标

配置昵称原理
1.启动客户端,就应该有个读取配置文件的操作,把昵称从配置文件里面读到控件
2.客户配置昵称,需要写入到配置文件
在昵称保存控件函数中
- void CMFCChatClientDlg::OnBnClickedSavenameBtn()
- {
- //获取文本框里的内容
- CString strName;
- GetDlgItemText(IDC_NAME_EDIT, strName);
- //判断昵称框是否为空
- if (strName.GetLength() <= 0) {
- MessageBox(_T("昵称不能为空!"));
- return;
- }
- //MB_OKCANCEL表示消息框是OK/CANCEL键,用户选择OK则进入if语句
- if (IDOK == AfxMessageBox(_T("是否修改昵称"), MB_OKCANCEL)) {
- //保存昵称
- //关于路径数组的定义,内置的260大小
- WCHAR strPath[MAX_PATH] = { 0 };
- //获取当前路径
- GetCurrentDirectoryW(MAX_PATH, strPath);
-
- //L"%s"也表示宽字节,如果是"%ls"发现无法输出全部内容
- TRACE(L"#####strPath= %s", strPath);
-
- CString strFilePath;
- //大写L表示宽字节,.ini表示配置文件
- strFilePath.Format(L"%ls//Test.ini", strPath);
-
- //在配置文件里写入一个字符串
- WritePrivateProfileStringW(_T("CLIENT"), _T("NAME"), strName, strFilePath);
- //WritePrivateProfileStringW(
- // _In_opt_ LPCWSTR lpAppName, 项名
- // _In_opt_ LPCWSTR lpKeyName, 键名
- // _In_opt_ LPCWSTR lpString,
- // _In_opt_ LPCWSTR lpFileName
- //);
- }
-
- }
在初始化都画框函数中OnInitDlg
- //从配置文件获取昵称
- WCHAR strPath[MAX_PATH] = { 0 };
- GetCurrentDirectoryW(MAX_PATH, strPath);
- CString strFilePath;
- strFilePath.Format(L"%ls//Test.ini", strPath);
- //拿到昵称
- WCHAR wszName[MAX_PATH] = { 0 };
- DWORD dwNum = GetPrivateProfileStringW(_T("CLIENT"), _T("NAME"), NULL, wszName, MAX_PATH, strFilePath);
- if (dwNum > 0) {
- //读到了
- //显示在昵称框
- GetDlgItem(IDC_NAME_EDIT)->SetWindowText(wszName);
- }
- else {
- //没有读到或者文件损坏了
- //先随便在文件写一个,再显示在昵称框
- WritePrivateProfileStringW(_T("CLIENT"), _T("NAME"), _T("客户端"), strFilePath);
- GetDlgItem(IDC_NAME_EDIT)->SetWindowText(_T("客户端"));
- }
- //GetPrivateProfileStringW(
- // _In_opt_ LPCWSTR lpAppName, 项名
- // _In_opt_ LPCWSTR lpKeyName, 键名
- // _In_opt_ LPCWSTR lpDefault, 默认值
- // _Out_writes_to_opt_(nSize, return +1) LPWSTR lpReturnedString, 一个Buff,将内容搞到buff里
- // _In_ DWORD nSize,
- // _In_opt_ LPCWSTR lpFileName
- //);
在客户端的接收函数中,如果用户选择了自动发送消息,则将消息框中的内容发送给服务端,然后在历史消息框中显示该条消息

在客户端OnReceive函数中补充代码
- //自动回复
- //如果选中
- if (((CButton*)dlg->GetDlgItem(IDC_AUTOSEND_RADIO))->GetCheck()) {
- //1.读编辑框的内容
- CString strAutoSendMsg;
- dlg->GetDlgItemText(IDC_AUTOSEND_RADIO, strAutoSendMsg);
- //2.封包+组格式
- CString strName;
- dlg->GetDlgItemTextW(IDC_NAME_EDIT, strName);
- //时间+昵称+[自动回复]+内容
- CString strMsg = strName + _T(":") + _T("[自动回复]") + strAutoSendMsg;
- char* szSendBuf = T2A(strMsg);
- //发送给服务端
- dlg->m_client->Send(szSendBuf, SEND_MAX_BUF, 0);
- //显示在列表框
- CString strShow;
- strShow = dlg->CatShowString(_T(""), strMsg);
- dlg->m_list.AddString(strShow);
-
- }
补充自动回复的控件函数
- //自动回复
- void CMFCChatClientDlg::OnBnClickedAutosendRadio()
- {
- if (((CButton*)GetDlgItem(IDC_AUTOSEND_RADIO))->GetCheck()) {
- TRACE("####选中");
- ((CButton*)GetDlgItem(IDC_AUTOSEND_RADIO))->SetCheck(FALSE);
- }
- else {
- TRACE("#####为选中");
- ((CButton*)GetDlgItem(IDC_AUTOSEND_RADIO))->SetCheck(TRUE);
- }
- }

只需要在对应控件函数下使用ResetControl函数即可
在客户端或者服务端启动时,应将除连接控件外的一些按钮置灰,防止程序崩溃
- GetDlgItem(IDC_SEND_BTN)->EnableWindow(FALSE);
- //断开按钮置灰
- GetDlgItem(IDC_DISCONNECT_BTN)->EnableWindow(FALSE);
- //自动回复置灰
- GetDlgItem(IDC_AUTOSEND_CHECK)->EnableWindow(FALSE);
- //连接按钮可用
- GetDlgItem(IDC_CONNECT_BTN)->EnableWindow(TRUE);

在断开控件函数里
- void CMFCChatClientDlg::OnBnClickedDisconnectBtn()
- {
- //1.控制控件
-
- GetDlgItem(IDC_SEND_BTN)->EnableWindow(FALSE);
- //断开按钮置灰
- GetDlgItem(IDC_DISCONNECT_BTN)->EnableWindow(FALSE);
- //自动回复置灰
- GetDlgItem(IDC_AUTOSEND_CHECK)->EnableWindow(FALSE);
- //连接按钮可用
- GetDlgItem(IDC_CONNECT_BTN)->EnableWindow(TRUE);
-
- //2.回收资源
- m_client->Close();
- if (m_client != NULL) {
- delete m_client;
- m_client = NULL;
- }
-
- //3.显示到列表框
- CString strShow;
- strShow = CatShowString(_T(""), _T("断开与服务器连接"));
- m_list.AddString(strShow);
- UpdateData(FALSE);
- }
在断开控件函数里
- void CMFCChartServerDlg::OnBnClickedStopBtn()
- {
- //1.控制控件
- GetDlgItem(IDC_START_BTN)->EnableWindow(TRUE);
- GetDlgItem(IDC_STOP_BTN)->EnableWindow(FALSE);
- GetDlgItem(IDC_SEND_BTN)->EnableWindow(FALSE);
-
- //2.回收资源
- m_server->Close();
- if (m_server != NULL) {
- delete m_server;
- m_server = NULL;
- }
- if (m_chat != NULL) {
- delete m_chat;
- m_chat = NULL;
- }
-
- //3.显示在列表框
- CString strShow;
- strShow = CatShowString(_T(""), _T("服务器停止"));
- m_list.AddString(strShow);
- UpdateData(FALSE);
-
- }

为控件绑定成员变量,在初始化函数中添加颜色并设置默认选项
- m_WordColorCombo.AddString(_T("黑色"));
- m_WordColorCombo.AddString(_T("红色"));
- m_WordColorCombo.AddString(_T("蓝色"));
- m_WordColorCombo.AddString(_T("绿色"));
- //设置当前选择为第0个
- m_WordColorCombo.SetCurSel(0);
- SetDlgItemText(IDC_COLOUR_COMBO, _T("黑色"));
设置控制颜色响应函数
- HBRUSH CMFCChatClientDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
- {
- HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
- CString strColor;
- m_WordColorCombo.GetWindowTextW(strColor);
- //GetDlgCtrlID返回指向给定控件或子窗口的指针,不存在返回NULL
- if (IDC_LIST1 == pWnd->GetDlgCtrlID() || IDC_SENDMSG_EDIT == pWnd->GetDlgCtrlID()) {
- if (strColor == L"黑色") {
- pDC->SetTextColor(RGB(0, 0, 0));
- }
- else if (strColor == L"红色") {
- pDC->SetTextColor(RGB(255, 0, 0));
- }
- else if (strColor == L"绿色") {
- pDC->SetTextColor(RGB(0, 255, 255));
- }
- else if (strColor == L"蓝色") {
- pDC->SetTextColor(RGB(0, 0, 255));
- }
- }
- return hbr;
- }

在OnPaint函数中
- //确定目标区域→加载资源图片并且转换为内存设备→绘图
- //1.定义dc
- CPaintDC dc(this); // 用于绘制的设备上下文
- //2.确定绘制区域
- CRect rect;
- GetClientRect(&rect); //拿到对话框区域
- //3.创建一个内存设备环境 创建兼容性dc
- CDC dcBmp;
- dcBmp.CreateCompatibleDC(&dcBmp);
-
-
- //4.载入资源图片
- CBitmap bmpBackGround;
- bmpBackGround.LoadBitmap(IDB_BITMAP);
- //5.将图片紫云啊载入到位图里面bBitMap位图
- BITMAP bBitmap;
- bmpBackGround.GetBitmap(&bBitmap);
-
- //6.将位图选入到临时的内存设备环境
- CBitmap* pbmpOld = dcBmp.SelectObject(&bmpBackGround);
-
- //7.开始绘制
- dc.StretchBlt(0, 0, rect.Width(), rect.Height(), &dcBmp, 0, 0, bBitmap.bmWidth, bBitmap.bmHeight, SRCCOPY);