MFC CSocket AfxBeginThread PossMessage Menu 自定义消息

技术分享

 1 // StockServerDlg.h : 头文件
 2 //
 3 
 4 #pragma once
 5 #include "afxwin.h"
 6 
 7 UINT ThreadProc(LPVOID pParm);
 8 
 9 struct threadInfo
10 {
11     char recvMsg[256];
12     char sendMsg[256];
13     HWND hWnd;    //主窗口句柄,用于消息的发送
14 };
15 
16 // CStockServerDlg 对话框
17 class CStockServerDlg : public CDialogEx
18 {
19 // 构造
20 public:
21     CStockServerDlg(CWnd* pParent = NULL);    // 标准构造函数
22 
23 // 对话框数据
24     enum { IDD = IDD_STOCKSERVER_DIALOG };
25 
26     protected:
27     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
28 
29 
30 // 实现
31 protected:
32     HICON m_hIcon;
33     CWinThread *m_pThread;
34     threadInfo m_Info;
35 
36     // 生成的消息映射函数
37     virtual BOOL OnInitDialog();
38     afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
39     afx_msg void OnPaint();
40     afx_msg HCURSOR OnQueryDragIcon();
41     DECLARE_MESSAGE_MAP()
42 public:
43     afx_msg void OnStart();
44     CMenu m_menu;
45     afx_msg void OnClose();
46 protected:
47     afx_msg LRESULT OnInfo(WPARAM wParam, LPARAM lParam);
48 public:
49     CString m_edit1;
50     CString m_edit2;
51     CEdit m_edit3;
52 };

 

  1 // StockServerDlg.cpp : 实现文件
  2 //
  3 
  4 #include "stdafx.h"
  5 #include "StockServer.h"
  6 #include "StockServerDlg.h"
  7 #include "afxdialogex.h"
  8 
  9 #ifdef _DEBUG
 10 #define new DEBUG_NEW
 11 #endif
 12 
 13 BOOL ServerStatus = FALSE;
 14 
 15 // 用于应用程序“关于”菜单项的 CAboutDlg 对话框
 16 
 17 class CAboutDlg : public CDialogEx
 18 {
 19 public:
 20     CAboutDlg();
 21 
 22 // 对话框数据
 23     enum { IDD = IDD_ABOUTBOX };
 24 
 25     protected:
 26     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
 27 
 28 // 实现
 29 protected:
 30     DECLARE_MESSAGE_MAP()
 31 };
 32 
 33 CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
 34 {
 35 }
 36 
 37 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
 38 {
 39     CDialogEx::DoDataExchange(pDX);
 40 }
 41 
 42 BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
 43 END_MESSAGE_MAP()
 44 
 45 
 46 // CStockServerDlg 对话框
 47 
 48 
 49 
 50 CStockServerDlg::CStockServerDlg(CWnd* pParent /*=NULL*/)
 51     : CDialogEx(CStockServerDlg::IDD, pParent)
 52     , m_edit1(_T(""))
 53     , m_edit2(_T(""))
 54 {
 55     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
 56     
 57 }
 58 
 59 void CStockServerDlg::DoDataExchange(CDataExchange* pDX)
 60 {
 61     CDialogEx::DoDataExchange(pDX);
 62     DDX_Text(pDX, IDC_EDIT1, m_edit1);
 63     DDX_Text(pDX, IDC_EDIT2, m_edit2);
 64     DDX_Control(pDX, IDC_EDIT3, m_edit3);
 65 }
 66 
 67 BEGIN_MESSAGE_MAP(CStockServerDlg, CDialogEx)
 68     ON_WM_SYSCOMMAND()
 69     ON_WM_PAINT()
 70     ON_WM_QUERYDRAGICON()
 71     ON_COMMAND(ID_START, &CStockServerDlg::OnStart)
 72     ON_COMMAND(ID_CLOSE, &CStockServerDlg::OnClose)
 73 ON_MESSAGE(WM_INFO, &CStockServerDlg::OnInfo)    //自定义消息
 74 END_MESSAGE_MAP()
 75 
 76 
 77 // CStockServerDlg 消息处理程序
 78 
 79 BOOL CStockServerDlg::OnInitDialog()
 80 {
 81     CDialogEx::OnInitDialog();
 82 
 83     // 将“关于...”菜单项添加到系统菜单中。
 84 
 85     // IDM_ABOUTBOX 必须在系统命令范围内。
 86     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
 87     ASSERT(IDM_ABOUTBOX < 0xF000);
 88 
 89     CMenu* pSysMenu = GetSystemMenu(FALSE);
 90     if (pSysMenu != NULL)
 91     {
 92         BOOL bNameValid;
 93         CString strAboutMenu;
 94         bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
 95         ASSERT(bNameValid);
 96         if (!strAboutMenu.IsEmpty())
 97         {
 98             pSysMenu->AppendMenu(MF_SEPARATOR);
 99             pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
100         }
101     }
102 
103     // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
104     //  执行此操作
105     SetIcon(m_hIcon, TRUE);            // 设置大图标
106     SetIcon(m_hIcon, FALSE);        // 设置小图标
107 
108     // TODO: 在此添加额外的初始化代码
109     //添加自定义菜单
110     m_menu.LoadMenuW(IDR_MENU1);
111     SetMenu(&m_menu);
112     m_edit3.SetWindowText(_T("未启动"));
113     return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
114 }
115 
116 void CStockServerDlg::OnSysCommand(UINT nID, LPARAM lParam)
117 {
118     if ((nID & 0xFFF0) == IDM_ABOUTBOX)
119     {
120         CAboutDlg dlgAbout;
121         dlgAbout.DoModal();
122     }
123     else
124     {
125         CDialogEx::OnSysCommand(nID, lParam);
126     }
127 }
128 
129 // 如果向对话框添加最小化按钮,则需要下面的代码
130 //  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
131 //  这将由框架自动完成。
132 
133 void CStockServerDlg::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         CDialogEx::OnPaint();
155     }
156 }
157 
158 //当用户拖动最小化窗口时系统调用此函数取得光标
159 //显示。
160 HCURSOR CStockServerDlg::OnQueryDragIcon()
161 {
162     return static_cast<HCURSOR>(m_hIcon);
163 }
164 
165 void CStockServerDlg::OnStart()
166 {
167     // TODO: 在此添加命令处理程序代码
168     memset(m_Info.recvMsg,0,sizeof(m_Info.recvMsg));
169     memset(m_Info.sendMsg,0,sizeof(m_Info.sendMsg));
170     m_Info.hWnd = m_hWnd;
171     m_pThread = AfxBeginThread(ThreadProc,&m_Info);
172     if (m_pThread == NULL)
173     {
174         AfxMessageBox(_T("启动失败!"));
175         return;
176     }
177     ServerStatus = TRUE;
178     m_edit3.SetWindowText(_T("已启动"));
179 }
180 
181 
182 void CStockServerDlg::OnClose()
183 {
184     // TODO: 在此添加命令处理程序代码
185     m_edit3.SetWindowText(_T("未启动"));
186     ServerStatus = FALSE;
187 }
188 
189 UINT ThreadProc(LPVOID pParm)
190 {
191     threadInfo *pInfo=(threadInfo*)pParm;
192     CSocket srvSocket, connSocket;
193     //最好不要使用srvSocket.Create创建,因为容易会出现10048错误
194     if (!srvSocket.Socket())
195     {
196         AfxMessageBox(_T("Socket Create Faild!"));
197         return 1; 
198     }
199 
200     BOOL bOptVal = TRUE;
201     int bOptLen = sizeof(BOOL);
202 
203     //设置Socket的选项, 解决10048错误必须的步骤
204     srvSocket.SetSockOpt(SO_REUSEADDR, (void *)&bOptVal, bOptLen, SOL_SOCKET);
205     //绑定端口
206     if (!srvSocket.Bind(8090))
207     {
208         AfxMessageBox(_T("Bind Create Faild!"));
209     }
210     //监听
211     if(!srvSocket.Listen(10))
212     {    
213         AfxMessageBox(_T("Listen Create Faild!"));
214         return 1;
215     }
216     while(ServerStatus)
217     {
218         //接收外部连接
219         if(!srvSocket.Accept(connSocket))
220         {
221             continue;
222         }
223         else
224         {
225             char szRecvMsg[256] = {0};
226             char szOutMsg[256] = {0};    
227             //接收客户端内容:阻塞
228             connSocket.Receive(szRecvMsg, 256);
229             sprintf_s(pInfo->recvMsg,"Receive data = %s",szRecvMsg);
230     
231             //发送内容给客户端
232             connSocket.Send("Have Receive The Msg", 50);
233             sprintf_s(pInfo->sendMsg,"Have Receive The Msg");
234             ::PostMessage(pInfo->hWnd,WM_INFO,(WPARAM)pInfo,0);
235             //关闭
236             connSocket.Close();
237         }
238     }
239     //关闭
240     srvSocket.Close();
241     connSocket.Close();
242     return 0;
243     
244 }
245 
246 afx_msg LRESULT CStockServerDlg::OnInfo(WPARAM wParam, LPARAM lParam)
247 {
248     threadInfo *psInfo=(threadInfo*)wParam;
249     m_edit1 = psInfo->recvMsg;
250     m_edit2 = psInfo->sendMsg;
251     UpdateData(FALSE);
252     
253     return 0;
254 }

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。