多线程中afxMessageBox

工作线程中afxMessageBox被主窗口覆盖,显示在最顶层的解决方法参考:

AttachThreadInput(::GetWindowThreadProcessId(::GetForegroundWindow(),NULL), ::GetCurrentThreadId(), TRUE);

具体参考AttachThreadInput的使用。

绑定之后还要解除,TRUE改为FALSE。

这样做是因为禁止设置Modal,如果允许设置,还是用systemmodal方便。

MFC(Microsoft Foundation Class)是微软公司提供的面向对象的 C++ 库,用于 Windows 程序的开发。基于 MFC 的多线程聊天程序可以使用 socket 技术实现。 以下是实现步骤: 1. 创建一个 MFC 应用程序,选择“多文档视图”类型。 2. 在应用程序类添加两个变量:`CAsyncSocket m_server;` 和 `CPtrList m_socketList;`。`m_server` 用于监听客户端连接,`m_socketList` 用于存储连接的客户端 socket。 3. 在应用程序类的 InitInstance 函数创建 socket: ``` if(!m_server.Create(8888)){ AfxMessageBox(_T("Failed to create server socket")); return FALSE; } if(!m_server.Listen()){ AfxMessageBox(_T("Failed to listen on server socket")); return FALSE; } ``` 4. 在应用程序类添加一个成员函数 `OnAccept`,当有客户端连接时,该函数将被调用。在该函数创建客户端 socket,并将其加入到 `m_socketList` 。 ``` void CMyChatApp::OnAccept(){ CMySocket* pSocket = new CMySocket(); if(m_server.Accept(*pSocket)){ m_socketList.AddTail(pSocket); pSocket->AsyncSelect(FD_CLOSE | FD_READ); }else{ delete pSocket; } } ``` 5. 创建一个自定义 socket 类 `CMySocket`,继承自 `CAsyncSocket`。在该类添加一个成员函数 `OnClose`,当客户端断开连接时,该函数将被调用。在该函数将客户端 socket 从 `m_socketList` 删除。 ``` void CMySocket::OnClose(int nErrorCode){ POSITION pos = theApp.m_socketList.Find(this); if(pos){ theApp.m_socketList.RemoveAt(pos); } delete this; } ``` 6. 在 `CMySocket` 类添加一个成员函数 `OnReceive`,当有数据传入时,该函数将被调用。在该函数读取数据并将其广播给所有连接的客户端。 ``` void CMySocket::OnReceive(int nErrorCode){ char buf[1024]; int len = Receive(buf, sizeof(buf)); if(len > 0){ buf[len] = '\0'; POSITION pos = theApp.m_socketList.GetHeadPosition(); while(pos){ CMySocket* pSocket = (CMySocket*)theApp.m_socketList.GetNext(pos); if(pSocket != this){ pSocket->Send(buf, len); } } } } ``` 7. 在主窗口添加一个编辑框和一个按钮。在按钮的 Click 事件创建一个客户端 socket,并连接到服务器。 ``` void CMyChatView::OnButtonConnect(){ CMySocket* pSocket = new CMySocket(); if(pSocket->Create()){ if(pSocket->Connect(_T("127.0.0.1"), 8888)){ pSocket->AsyncSelect(FD_CLOSE | FD_READ); theApp.m_socketList.AddTail(pSocket); }else{ delete pSocket; } }else{ delete pSocket; } } ``` 8. 在主窗口的 `OnDraw` 函数添加一个定时器,每隔一段时间检查是否有新的客户端连接。在该函数添加以下代码: ``` if(m_timer == 0){ m_timer = SetTimer(1, 1000, NULL); } ``` 9. 在主窗口添加一个成员变量 `UINT_PTR m_timer;`。 10. 实现定时器事件 `OnTimer`,在该事件调用应用程序类的 `OnAccept` 函数检查是否有新的客户端连接。 ``` void CMyChatView::OnTimer(UINT_PTR nIDEvent){ if(nIDEvent == 1){ theApp.OnAccept(); } } ``` 11. 在主窗口添加一个成员函数 `OnSocketNotify`,当有数据传入时,该函数将被调用。在该函数读取数据并显示在编辑框。 ``` void CMyChatView::OnSocketNotify(WPARAM wParam, LPARAM lParam){ CMySocket* pSocket = (CMySocket*)wParam; char buf[1024]; int len = pSocket->Receive(buf, sizeof(buf)); if(len > 0){ buf[len] = '\0'; CString strText; m_edit.GetWindowText(strText); strText += buf; m_edit.SetWindowText(strText); m_edit.LineScroll(m_edit.GetLineCount() - 1); } } ``` 12. 在主窗口添加一个成员变量 `HWND m_hWndServer;`。 13. 在主窗口的 Create 函数创建一个隐藏的窗口,并将其消息处理函数设置为 `OnSocketNotify`。在该函数添加以下代码: ``` m_hWndServer = CreateWindowEx(0, AfxRegisterWndClass(0), _T(""), 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, AfxGetInstanceHandle(), NULL); ::SetWindowLong(m_hWndServer, GWL_USERDATA, (LONG)this); ``` 14. 在主窗口的 `OnClose` 函数删除隐藏窗口。 ``` void CMyChatView::OnClose(){ ::DestroyWindow(m_hWndServer); CFormView::OnClose(); } ``` 15. 在主窗口的 `OnSize` 函数调整编辑框的大小。 ``` void CMyChatView::OnSize(UINT nType, int cx, int cy){ CFormView::OnSize(nType, cx, cy); m_edit.MoveWindow(0, 0, cx, cy - 50); m_button.MoveWindow(cx - 100, cy - 50, 100, 50); } ``` 16. 在主窗口添加一个成员函数 `PostSocketNotify`,用于向隐藏窗口发送消息。在该函数添加以下代码: ``` ::PostMessage(m_hWndServer, WM_SOCKET_NOTIFY, (WPARAM)pSocket, 0); ``` 17. 在主窗口添加一个宏定义 `WM_SOCKET_NOTIFY`。 ``` #define WM_SOCKET_NOTIFY (WM_USER + 1) ``` 18. 在隐藏窗口的消息处理函数 `OnSocketNotify` 调用主窗口的 `OnSocketNotify` 函数。 ``` LRESULT CALLBACK CMyChatView::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ switch(message){ case WM_SOCKET_NOTIFY: { CMyChatView* pView = (CMyChatView*)::GetWindowLong(hWnd, GWL_USERDATA); pView->OnSocketNotify(wParam, lParam); break; } } return CFormView::WndProc(hWnd, message, wParam, lParam); } ``` 至此,基于 MFC 和 socket 的多线程聊天程序就完成了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值