《MFC网络编程》学习日记4

一、MFC socket网络编程(流程示例)

1.TCP流式套接字的编程步骤 在使用之前须链接库函数:工程->设置->Link->输入ws2_32.lib,OK!

服务器端程序:

1、加载套接字库

2、创建套接字(socket)。

3、将套接字绑定到一个本地地址和端口上(bind)。

4、将套接字设为监听模式,准备接收客户请求(listen)。

5、等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)。

6、用返回的套接字和客户端进行通信(send/recv)。

7、返回,等待另一客户请求。

8、关闭套接字。

客户端程序:

1、加载套接字库

2、创建套接字(socket)。

3、向服务器发出连接请求(connect)。

4、和服务器端进行通信(send/recv)。

5、关闭套接字。

服务器端代码如下:

#include <Winsock2.h>//加裁头文件

#include <stdio.h>//加载标准输入输出头文件

void main()

{

WORD wVersionRequested;//版本号

WSADATA wsaData;

int err;

wVersionRequested = MAKEWORD( 1, 1 );//1.1版本的套接字

err = WSAStartup( wVersionRequested, &wsaData );

if ( err != 0 ) { return; }//加载套接字库,加裁失败则返回

if ( LOBYTE( wsaData.wVersion ) != 1 ||HIBYTE( wsaData.wVersion ) != 1 )

{

WSACleanup( );

return;

}//如果不是1.1的则退出

SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);//创建套接字(socket)。

SOCKADDR_IN addrSrv;

addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//转换Unsigned short为网络字节序的格式 addrSrv.sin_family=AF_INET;

addrSrv.sin_port=htons(6000);

bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)); //将套接字绑定到一个本地地址和端口上(bind) listen(sockSrv,5);//将套接字设为监听模式,准备接收客户请求(listen)。

SOCKADDR_IN addrClient;//定义地址族

int len=sizeof(SOCKADDR);//初始化这个参数,这个参数必须被初始化

while(1)

{

SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len); //accept的第三个参数一定要有初始值。 //等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)。 //此时程序在此发生阻塞

char sendBuf[100];

sprintf(sendBuf,"Welcome %s to www.msn.com.cn",inet_ntoa(addrClient.sin_addr)); //用返回的套接字和客户端进行通信(send/recv)。

send(sockConn,sendBuf,strlen(sendBuf)+1,0);

char recvBuf[100];

recv(sockConn,recvBuf,100,0);

printf("%s\n",recvBuf);

closesocket(sockConn);//关闭套接字。等待另一个用户请求

}

}

客户端代码如下:

#include <Winsock2.h>

#include <stdio.h>

void main()

{

WORD wVersionRequested;

WSADATA wsaData;

int err;

wVersionRequested = MAKEWORD( 1, 1 );

err = WSAStartup( wVersionRequested, &wsaData );//加载套接字库

if ( err != 0 ) { return; }

if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )

{

WSACleanup( );

return;

}

SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);//创建套接字(socket)。

SOCKADDR_IN addrSrv;

addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");

addrSrv.sin_family=AF_INET;

addrSrv.sin_port=htons(6000);

connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//向服务器发出连接请求(connect)。

char recvBuf[100];//和服务器端进行通信(send/recv)。

recv(sockClient,recvBuf,100,0);

printf("%s\n",recvBuf);

send(sockClient,"This is blues_j",strlen("This is blues_j")+1,0);

closesocket(sockClient);//关闭套接字。

WSACleanup();//必须调用这个函数清除参数

}

2.UDP型套接字。 服务器端(接收端)程序:

1、创建套接字(socket)。

2、将套接字绑定到一个本地地址和端口上(bind)。

3、等待接收数据(recvfrom)。

4、关闭套接字。 客户端(发送端)程序:

1、创建套接字(socket)。

2、向服务器发送数据(sendto)。

3、关闭套接字。

服务器端代码:

#include <Winsock2.h>

#include <stdio.h>

void main()

{

WORD wVersionRequested;

WSADATA wsaData;

int err;

wVersionRequested = MAKEWORD( 1, 1 );

err = WSAStartup( wVersionRequested, &wsaData );

if ( err != 0 ) { return; }

if ( LOBYTE( wsaData.wVersion ) != 1 ||HIBYTE( wsaData.wVersion ) != 1 )

{

WSACleanup( );

return;

}

SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);

SOCKADDR_IN addrSrv;

addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);

addrSrv.sin_family=AF_INET;

addrSrv.sin_port=htons(6000);

bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

SOCKADDR_IN addrClient;

int len=sizeof(SOCKADDR);

char recvBuf[100];

recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);

printf("%s\n",recvBuf);

closesocket(sockSrv); WSACleanup();

}

客户端代码:

#include <Winsock2.h>

#include <stdio.h>

void main()

{

WORD wVersionRequested;

WSADATA wsaData;

int err;

wVersionRequested = MAKEWORD( 1, 1 );

err = WSAStartup( wVersionRequested, &wsaData );

if ( err != 0 ) { return; }

if ( LOBYTE( wsaData.wVersion ) != 1 ||HIBYTE( wsaData.wVersion ) != 1 )

{

WSACleanup( );

return;

}

SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);

SOCKADDR_IN addrSrv;

addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");

addrSrv.sin_family=AF_INET;

addrSrv.sin_port=htons(6000);

sendto(sockClient,"Hello",strlen("Hello")+1,0, (SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

closesocket(sockClient);

WSACleanup();

}

3.聊天程序常用的是UDP式套接字。因为TCP的三步握手开销比较大。

二、MFC的一些基本操作总结,比如操作字体,菜单,图片等

一:对控件上的字体操作

方法一:

CFont *pfont = m_heightvalue.GetFont();//m_heightvalue为控件

LOGFONT logfont;

pfont->GetLogFont(&logfont);

logfont.lfHeight = 100;

m_font.CreateFontIndirect(&logfont);

m_heightvalue.SetFont(&m_font);

方法二:

CFont m_newFont;

m_newFont.CreatePointFont(250,_T("隶书")); //

m_heightitle.SetFont(&m_newFont);

m_heightitle.SetWindowTextW(strTemp);

二:图行控件的操作:

CBrush newBrush;

CBrush *oldBrush;

CRect rect;

newBrush.CreateSolidBrush(RGB(255,0,0));

CClientDC cClientDc(this);

m_heightitle.GetWindowRect(&rect); //m_heightitle为图形控件

ScreenToClient(&rect);

oldBrush=cClientDc.SelectObject(&newBrush);

cClientDc.Rectangle(&rect);

cClientDc.SelectObject(oldBrush);

newBrush.DeleteObject();

三:改变控件的颜色:

添加消息响应:ON_WM_CTLCOLOR()

HBRUSH CDisplayValue::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)

{

HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);

switch(pWnd->GetDlgCtrlID())

{

case IDC_STATIC_HEIGHTVALUE:

pDC->SetBkMode(TRANSPARENT);

pDC->SetBkColor(RGB(191,223,255));

pDC->SetTextColor(RGB(255,0,0));

return (HBRUSH)GetStockObject(HOLLOW_BRUSH);

case IDC_STATIC_HEIGHTTITLE:

pDC->SetBkMode(TRANSPARENT);

pDC->SetBkColor(RGB(191,223,255));

pDC->SetTextColor(RGB(0,0,0));

return (HBRUSH)GetStockObject(HOLLOW_BRUSH);

case IDC_STATIC_THICKNESSTITLE:

pDC->SetBkMode(TRANSPARENT);

pDC->SetBkColor(RGB(191,223,255));//SetBkMode(TRANSPARENT);

pDC->SetTextColor(RGB(0,0,0));

return (HBRUSH)GetStockObject(HOLLOW_BRUSH);

case IDC_STATIC_THICKNESSVALUE:

pDC->SetBkMode(TRANSPARENT);

pDC->SetBkColor(RGB(191,223,255));

pDC->SetTextColor(RGB(255,0,0));

return (HBRUSH)GetStockObject(HOLLOW_BRUSH);

default:

break;

}

return hbr;

}

四:窗口大小改变:

添加消息响应void CDebugCrtDlg::OnSize(UINT nType, int cx, int cy)

参数: nType 指定了要求的调整大小的类型。这个参数可以是下列值之一: · SIZE_MAXIMIZED 窗口已

经被最大化。

· SIZE_MINIMIZED 窗口已经被最小化。

· SIZE_RESTORED 窗口被改变了大小,但SIZE_MINIMIZED和SIZE_MAXIMIZED都不适用。

· SIZE_MAXHIDE 当其它窗口被最大化时,消息被发送到所有的弹出窗口。

· SIZE_MAXSHOW 当其它窗口被恢复到原来的大小时,消息被发送到所有的弹出窗口。

cx 指定了客户区域的新宽度。

cy 指定了客户区域的新高度。

五:访问txt文件

file.Open(m_strFilePath,CFile::modeRead);

char pbufRead[1024];

memset(pbufRead,0, sizeof(pbufRead));

file.SeekToBegin();

file.Read(pbufRead, sizeof(pbufRead));

访问excel文件:

http://bbs.csdn.net/topics/390481737

代码:E:\c++Code\MMES_New_Code\WarehouseManagementcomV1.62

\WarehouseManagement\Outwarehouse.cpp

六:图标的操作:

从网上下载图象后,一般为.jpg格式,而MFC中图标格式为.ico格式,所以需要把.jpg格式转换为.ico格

式,一般百度在线都有操作直接转换方法。//一般宽和高为128*128

七:控件的位置改变和大小改变函数

用CWnd类的函数MoveWindow()或SetWindowPos()可以改变控件的大小和位置

void MoveWindow(int x,int y,int nWidth,int nHeight);

void MoveWindow(LPCRECT lpRect);

第一种用法需给出控件新的坐标和宽度、高度;

第二种用法给出存放位置的CRect对象;

例:

CWnd *pWnd;

pWnd = GetDlgItem( IDC_EDIT1 ); //获取控件指针,IDC_EDIT1为控件ID号

pWnd->MoveWindow( CRect(0,0,100,100) ); //在窗口左上角显示一个宽100、高100的编辑控件

SetWindowPos()函数使用更灵活,多用于只修改控件位置而大小不变或只修改大小而位置不变的情况:

BOOL SetWindowPos(const CWnd* pWndInsertAfter,int x,int y,int cx,int cy,UINT nFlags);

第一个参数我不会用,一般设为NULL;

x、y控件位置;cx、cy控件宽度和高度;

nFlags常用取值:

SWP_NOZORDER:忽略第一个参数;

SWP_NOMOVE:忽略x、y,维持位置不变;

SWP_NOSIZE:忽略cx、cy,维持大小不变;

例:

CWnd *pWnd;

pWnd = GetDlgItem( IDC_BUTTON1 ); //获取控件指针,IDC_BUTTON1为控件ID号

pWnd->SetWindowPos( NULL,50,80,0,0,SWP_NOZORDER | SWP_NOSIZE ); //把按钮移到窗口的

(50,80)处

pWnd = GetDlgItem( IDC_EDIT1 );

pWnd->SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER | SWP_NOMOVE ); //把编辑控件的大小设为

(100,80),位置不变

pWnd = GetDlgItem( IDC_EDIT1 );

pWnd->SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER ); //编辑控件的大小和位置都改变

以上方法也适用于各种窗口。

八:wchar_t *类型 转为char *类型

wchar_t是宽字符类型,每个wchar_t类型占2个字节,16位宽。汉字的表示就要用到wchar_t 。

char,我们都知道,占一个字节,8位宽。

CString strName("listen");

char *pcstr = (char *)new char[2 * strName.GetLength()+1] ;

WideCharToMultiByte( CP_ACP,

0,

strName, // 要转换的wchar_t*

-1,

pcstr, // 接收char*的缓冲区指针

2 * strName.GetLength()+1, // pcstr的缓冲区的大小

NULL,

NULL );

宽字节和多字节转换:

http://www.doc88.com/p-335763678408.html (该网站中有简易方法)

九:添加菜单:

CMenu menu ,* pSubMenu; //定义下面要用到的cmenu对象

menu.LoadMenu(IDR_MENU1); //装载自定义的右键菜单

//获取第一个弹出菜单,所以第一个菜单必须有子菜单

pSubMenu = menu.GetSubMenu(0);

CPoint oPoint; //定义一个用于确定光标位置的位置

GetCursorPos( &oPoint); //获取当前光标的位置,以便使得菜单可以跟随光标

pSubMenu->TrackPopupMenu (TPM_LEFTALIGN, oPoint.x, oPoint.y, this);

添加菜单后需要响应菜单:即添加该菜单ID对应的命令响应函数。

十:控制滚动条

wnd为控件或者窗口

wnd.SendMessage(WM_VSCROLL,SB_LINEDOWN)

十一:word的操作:

http://www.jizhuomi.com/software/341.html

该链接中简单操作了word

十二:文件的读取

CFile pCfile;

bool bResult=pCfile.Open(lpszPathName,CFile::modeReadWrite);

if (bResult!=FALSE)

{

pCfile.Read(m_str.GetBuffer(pCfile.GetLength()),pCfile.GetLength());

}

pCfile.Close();

三、对话框最小化最大化时,相应控件也跟着发生变化

void CLastPackageDlg::OnSysCommand(UINT nID, LPARAM lParam)

{

m_paint=TRUE;

if (nID==SC_MINIMIZE)//最小化时

{

m_paint=FALSE;

}

if ((nID & 0xFFF0) == IDM_ABOUTBOX)

{

CAboutDlg dlgAbout;

dlgAbout.DoModal();

}

else

{

CDialogEx::OnSysCommand(nID, lParam);

}

}

void CLastPackageDlg::OnSize(UINT nType, int cx, int cy)

{

CDialogEx::OnSize(nType, cx, cy);

// TODO: 在此处添加消息处理程序代码

if (m_paint == true)

{

for (int ii= IDC_STATIC_totalcode; ii<= IDC_EDIT_PassWord;ii++)

{

CWnd *pWnd;

pWnd = GetDlgItem(ii);

if(pWnd)

{

CRect rect; //获取控件变化前的大小

pWnd->GetWindowRect(&rect);

ScreenToClient(&rect);//将控件大小转换为在对话框中的区域坐标

//cx/m_rect.Width()为对话框在横向的变化比例

rect.left=rect.left*cx/m_rect.Width();//调整控件大小

rect.right=rect.right*cx/m_rect.Width();

rect.top=rect.top*cy/m_rect.Height();

rect.bottom=rect.bottom*cy/m_rect.Height();

pWnd->MoveWindow(rect);//设置控件大小

}

}

GetClientRect(&m_rect);// 将变化后的对话框大小设为旧大小

}

}

该方法改进:

void CNerseDlg::OnSize(UINT nType, int cx, int cy)

{

CDialogEx::OnSize(nType, cx, cy);

// TODO: 在此处添加消息处理程序代码

if(nType == SIZE_MINIMIZED)

{

return;

}

CWnd *pWnd;

pWnd = GetDlgItem(IDC_LIST_Data_Show); //需要变化哪些控件,就获取哪些控件的指针

if(pWnd)

{

CRect rect; //获取控件变化前的大小

pWnd->GetWindowRect(&rect);

ScreenToClient(&rect);//将控件大小转换为在对话框中的区域坐标

//相对于客服区域来说,矩形的左坐标点不变,右坐标点变化

rect.right=rect.right*cx/m_rect.Width();//cx是X轴变化的大小

rect.bottom=rect.bottom*cy/m_rect.Height();

pWnd->MoveWindow(rect);//设置控件大小

m_listDataShow.GetClientRect(&rect);

int num = m_listDataShow.GetHeaderCtrl()->GetItemCount();

for (int i = 0; i < num; ++i)

{

m_listDataShow.SetColumnWidth(i,80);

}

}

GetClientRect(&m_rect);// 将变化后的对话框大小设为旧大小

}

猜你喜欢

转载自www.cnblogs.com/chenyibin1995/p/8965191.html