|  | 
 
| ATL对话框中接收Socket数据的完整实现方案 代码说明:1.使用WSAAsyncSelect实现异步通知 2.通过窗口消息传递数据 3.接收数据自动显示到IDC_EDIT_RECV控件 4.状态信息显示到IDC_EDIT_STATUS
 ATLSocket.h
 
 MainDlg.h复制代码
#pragma once
#include <atlbase.h>
#include <atlwin.h>
#include <winsock2.h>
#define WM_SOCKET_MSG (WM_USER + 100)
#define BUFFER_SIZE 4096
class CATLSocket : public CWindowImpl<CATLSocket> {
public:
    DECLARE_WND_CLASS(NULL)
    
    BEGIN_MSG_MAP(CATLSocket)
        MESSAGE_HANDLER(WM_SOCKET_MSG, OnSocketMessage)
    END_MSG_MAP()
    BOOL Init() {
        WSADATA wsa;
        return WSAStartup(MAKEWORD(2,2), &wsa) == 0;
    }
    void SetReceiver(HWND hWnd) { m_hReceiver = hWnd; }
    LRESULT OnSocketMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) {
        if (WSAGETSELECTERROR(lParam)) {
            PostMessage(m_hReceiver, WM_SOCKET_MSG, 0, (LPARAM)_T("Socket error"));
            return 0;
        }
        switch(WSAGETSELECTEVENT(lParam)) {
        case FD_READ: {
            char buffer[BUFFER_SIZE];
            int len = recv((SOCKET)wParam, buffer, BUFFER_SIZE-1, 0);
            if (len > 0) {
                buffer[len] = '\0';
                CString strMsg = CA2T(buffer);
                PostMessage(m_hReceiver, WM_SOCKET_MSG, 1, (LPARAM)new CString(strMsg));
            }
            break;
        }
        case FD_CLOSE:
            PostMessage(m_hReceiver, WM_SOCKET_MSG, 0, (LPARAM)_T("Connection closed"));
            break;
        }
        return 0;
    }
private:
    HWND m_hReceiver = NULL;
};
 复制代码 CMainDlg : public CDialogImpl<CMainDlg> {
public:
    enum { IDD = IDD_MAIN_DIALOG };
    BEGIN_MSG_MAP(CMainDlg)
        MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
        MESSAGE_HANDLER(WM_SOCKET_MSG, OnSocketMsg)
        COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
    END_MSG_MAP()
    LRESULT OnInitDialog(UINT, WPARAM, LPARAM, BOOL&) {
        m_socket.Init();
        m_socket.Create(m_hWnd);
        m_socket.SetReceiver(m_hWnd);
        return TRUE;
    }
    LRESULT OnSocketMsg(UINT, WPARAM wParam, LPARAM lParam, BOOL&) {
        if (wParam == 1) { // 数据接收
            CString* pStr = (CString*)lParam;
            SetDlgItemText(IDC_EDIT_RECV, *pStr);
            delete pStr;
        } else { // 错误/关闭
            SetDlgItemText(IDC_EDIT_STATUS, (LPCTSTR)lParam);
        }
        return 0;
    }
    LRESULT OnCancel(WORD, WORD wID, HWND, BOOL&) {
        EndDialog(wID);
        return 0;
    }
private:
    CATLSocket m_socket;
};
 
 | 
 |