MFC编程实验个人总结报告

MFC编程实验个人总结报告

MFC编程实验个人总结报告

一、MFC类、函数等知识小结:

1、SetTimer (1, m_intLevel, NULL);

在MFC程序中SetTimer被封装在CWnd类中,调用就不用指定窗口句柄了于是SetTimer函数的原型变为:

  UINT SetTimer(UINT nIDEvent,UINT nElapse,void(CALLBACK EXPORT *lpfnTimer)(HWND,UINT ,YINT ,DWORD))

  当使用SetTimer函数的时候,就会生成一个计时器。函数中nIDEvent指的是计时器的标识,也就是名字。nElapse指的是时间间隔,也就是每隔多长时间触发一次事件。第三个参数是一个回调函数,在这个函数里,放入你想要做的事情的代码,你可以将它设定为NULL,也就是使用系统默认的回调函数,系统默认认的是onTime函数。这个函数怎么生成的呢?你需要在需要计时器的类的生成onTime函数:在ClassWizard里,选择需要计时器的类,添加WM_TIME消息映射,就自动生成onTime函数了。然后在函数里添加代码,让代码实现功能。每隔一段时间就会自动执行一次。

  例:

  SetTimer(1,1000,NULL);

  1:计时器的名称;

  1000:时间间隔,单位是毫秒;

  NULL:使用onTime函数。

当不需要计时器的时候调用KillTimer(nIDEvent);

  例如:KillTimer(1);

KillTimer (1);

2、typedef struct{};

(1) struct{ int x; int y; }test1;

好,定义了 结构 test1,

test1.x 和 test1.y 可以在语句里用了。

(2) struct test {int x; int y; }test1;

定义了结构 test1,

test1.x 和 test1.y 可以在语句里用了。

与 (1) 比,省写 了 test

(3) typedef struct test

{int x; int y; }text1,text2;

此处时说了这种结构体(类型)别名 叫 text1 或叫 text2,而不是定义了结构体变量.

真正在语句里用,还要写:

text1 test1;//定义结构体变量

然后好用 test1.x test1.y

或写 text2 test1; //定义结构体变量

然后好用 test1.x test1.y

3、Invalidate ( ); //让客户区无效,即时重新绘制客户区

void Invalidate( BOOL bErase = TRUE );

该函数的作用是使整个窗口客户区无效。窗口的客户区无效意味着需要重绘,例如,如果一个被其它窗口遮住的窗口变成了前台窗口,那么原来被遮住的部分就是无效的,需要重绘。这时Windows会在应用程序的消息队列中放置WM_PAINT消息。MFC为窗口类提供了WM_PAINT的消息处理函数OnPaint,OnPaint负责重绘窗口。视图类有一些例外,在视图类的OnPaint函数中调用了OnDraw函数,实际的重绘工作由OnDraw来完成。参数bErase为TRUE时,重绘区域内的背景将被擦除,否则,背景将保持不变。

4、CDC::Rectangle(左上x,左上y,右下x,右下y); 使用该函数画一个矩形,可以用当前的画笔画矩形轮廓,用当前画刷进行填充。

函数原型:BOOL Rectangle(HDC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);

hdc:设备环境句柄。

nLeftRect:指定矩形左上角的逻辑X坐标。

  nTopRect:指定矩形左上角的逻辑Y坐标。

  nRightRect:指定矩形右下角的逻辑X坐标。

  nBottomRect:指定矩形右下角的逻辑Y坐标。

5、CBrush:: CBrush//画刷类

eg:CBrush brushStick (RGB (127, 127, 127) );

四种构造函数:

CBrush( );

  CBrush( COLORREF crColor );

  CBrush( int nIndex, COLORREF crColor );

  CBrush( CBitmap* pBitmap );

参数说明:

crColor指定画刷的前景色(RGB方式)。如果画刷是阴影线型的,则指定阴影线的颜色。

nIndex指定画刷阴影线采用的风格,取值如下:

HS_BDIAGONAL45度的向下影线(从左到右) 

HS_CROSS水平和垂直方向以网格线作出阴影

HS_DIAGCROSS 45度的网格线阴影

HS_FDIAGONAL 45度的向上阴影线(从左到右 )

HS_HORIZONTAL 水平的阴影线

HS_VERTICAL 垂直的阴影线

pBitmap指向CBitmap对象的指针,该对象指定了画刷要绘制的位图。

  构造函数说明:

类CBrush一共有四个覆盖的构造函数。不带参数的那个构造函数构造一个未初始化的CBrush对象,在使用该对象之前需要另外初始化。如果使用了不带参数的那个构造函数,则必须用CreateSolidBrush、CreateHatchBrush、CreateBrushIndirect、CreatePatternBrush或CreateDIBPatternBrush来初始化返回的CBrush对象。如果使用了带参数的构造函数,则不再需要初始化CBrush对象。带参数的构造函数在出错时会产生一个异常,而不带参数的构造函数总是成功返回。只带有一个参数COLORREF的构造函数用指定的颜色构造一个实线型的画刷。颜色是一个RGB值,可以用WINDOWS.H中的宏RGB构造出来。带两个参数的构造函数构造一个阴影线型的画刷,参数nIndex指定了阴影线模式的指数(index)。参数crColor指定了画刷的颜色。带有一个CBitmap型参数的构造函数构造一个模式化的画刷。参数指定一个位图。该位图应该是已经用CBitmap::CreateBitmap、CBitmap::CreateBitmapIndirect、CBitmap::LoadBitmap或CBitmap::CreateCompatiableBitmap建立或加载的位图。填充模式下的位图的最小尺寸为8像素×8像素。

6、MessageBox ("Game Over!");

MessageBox(NULL,"text","title",BUTTON);

参数title:string类型,指定消息对话框的标题。text:指定消息对话框中显示的消息,该参数可以是数值数据类型、字符串或boolean值。icon:Icon枚举类型,可选项,指定要在该对话框左侧显示的图标。button:Button枚举类型,可选项,指定显示在该对话框底部的按钮。default:数值型,可选项,指定作为缺省按钮的按钮编号,按钮编号自左向右依次计数,缺省值为1,如果该参数指定的编号超过了显示的按钮个数,那么MessageBox()函数将使用缺省值返回值Integer。函数执行成功时返回用户选择的按钮编号(例如1、2、3等),发生错误时返回-1。如果任何参数的值为NULL,MessageBox()函数返回NULL。

函数原型:MessageBox.Show(Text,Title,MessageBoxButtons,MessageBoxIcon ,MessageBoxDefaultButtons)

参数说明:

(1)Text:必选项,消息框的正文。

(2)Title:可选项,消息框的标题。

(3)MessageBoxButtons:可选项,消息框的按钮设置,默认只显示【确定】按钮。

  OK――确定 OKCancel――确定和取消 AbortRetryIgnore――终止、重试和忽略

  YesNoCancel――是、否和取消 YesNo――是和否 RetryCancel――重试和取消

(4)MessageBoxIcon:对话框中显示的图标样式,默认不显示任何图标。

  Question――问号 Information、Asterisk――i号 Error、Stop、Hand――错误号

  Warning、Exclamation――!号 None――不显示任何图标

(5)MessageBoxDefaultButtons:可选项,对话框中默认选中的按钮设置。

  DefaultButton1――第1个button是默认按钮

  DefaultButton2――第2个button是默认按钮

  DefaultButton3――第3个button是默认按钮

7、Memcpy(拷贝目的地,拷贝对象,拷贝长度); 包含在头文件#include <string.h>中

函数原型:

 extern void *memcpy(void *destin, void *source, unsigned n);

功能:

由source指向地址为起始地址的连续n个字节的数据复制到以destin指向地址为起始地址的空间内。

eg:

int a=5,b=9;

memcpy(a,b,sizeof(a));//将b按位拷给a;

说明:

1.source和destin所指内存区域不能重叠,函数返回指向destin的指针。

 2.与strcpy相比,memcpy并不是遇到'\0'就结束,而是一定会拷贝完n个字节。

 3.如果目标数组destin本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。如果要追加数据,则每次执行memcpy后,要将目标数组地址增加到你要追加数据的地址。

 //注意,source和destin都不一定是数组,任意的可读写的空间均可。

二、MFC个人学习心得:

1、问题的解决::

绘制窗口时会出现严重的刷屏问题,问了解决这一问题,通过改变背景位图来替代过多的部分的重绘达到更好效果。

一个满载的二维、三维数组都可以用一个足够长的一维数组来装下。

2、MFC基础细节学习:

学习了位图的使用,CBrush类,CDC类,CDialog类的基本使用,对于菜单的设置初步了解了。

3、mfc编程的初步理解:

通过自学了解到mfc编程的实现是通过建立消息映射表来实现各个函数的调用。(1)通过DECLARE_MESSAGE_MAP声明消息映射;(2)通过BEGIN_MESSAGE_MAP和宏END_MESSAGE_MAP来包含消息映射宏,创建消息映射列表;(3)为消息处理函数添加代码,实现需要的响应。通过以上三大步实现消息映射。

每种对话框的操作要通过先建立相应的CDialog类来具体进行。

MFC编程只是一种工具,而编程的核心还是代码的实现。我们在使用MFC编程时要想学得更好就要不断练习,更具体的了解其中的各种类、函数,各种工具,MFC是一个巨大的工具箱,但是如果不知道工具箱里面的工具怎么用,那在好的工具也无用武之地。所以,我认为此次编程小实习主要是让我初步接触了MFC如何实现可视化编程。未来要想真正掌握MFC编程还要不断的深入了解各种MFC工具,真正的与代码结合起来实现高效实用的编程效果。

4、这次编程实习过程中,另一点感受最深的就是团队合作,一支团队要想有好的工作效率和质量就必须有足够的队伍成员间的默契。如果仅仅靠个别人去完成,其实是很不科学的,不仅费时而且可能会白白做很多无用功,因此,在以后的小组中一定要加强团队合作意识。另一点就是一个队伍的成员可以不是特别出色,但是队伍的领导者一定要负责,领导者可以不是特别杰出的技术骨干人员,但必须懂得怎样协调、安排工作,这也是实现高效团队的关键因素。

通过这次暑期编程实验,不仅充实了暑期生活,也让我学到了一些新的知识,让我更加深刻的理解了团队合作的重要性。在以后的学习生活要积极参加类似的活动,加强知识学习,能力提高,为未来的职业生涯逐渐打下一个坚实的基础 。谢谢!

 

第二篇:MFC编程报告

成绩:

TCP/IP MFC套接字编程

姓 名 XXXXXXXXX

班 级 网络10-2

学 号 **

指导教师 **

1、实验目的:

了解MFC套接字编程

二、实验要求:

● MFC的界面设计、布局

● 实现套接字编程

三、实验内容:

设计一个MFC程序,实现两台主机之间的通信。

四、设计思路和过程:

答:使用UDP的机制来实现两台主机之间的通信,由于服务端和客户端的设计思路是相似的,因此这里只说服务器端的设计思路和过程。

1、创建一个继承CAsyncSocket类的CUDPSocket类。创建一个绑定本地IP和端口的函数BindLocatePC,主要是使用CAsyncSocket类的Create函数来实现;创建一个发送想远程主机发送数据的函数SendToRemotePC,主要使用CAsyncSocket类的函数SendTo函数来是实现。这两个方法都由窗口类来进行调用。另外,CUDPSocket的OnSend函数和OnReceive函数由窗口类来时实现。

2、

3、然后在窗口类中的初始化按钮的点击事件中调用CUDPSocket的BindLocatePC函数以实现套接字的绑定、实现OnSend函数已进行绑定套接字后的处理、在发送按钮的事件中调用CUDPSocket的SendToRemotePC函数实现向远程主机发送数据、实现OnReceive函数以进行数据接受并把接收到的数据显示到窗口中。

五、运行过程和结果:

服务器端的源代码如下:

UDPSocket.h

#pragma once

#include "afxsock.h"

class CUDPSocket :public CAsyncSocket

{

public:

CUDPSocket(void);

public:

~CUDPSocket(void);

public:

virtual void OnSend(int nErrorCode);

virtual void OnReceive(int nErrorCode);

bool BindLocatePC(DWORD m_LocateIP,int m_LocatePort);

bool SendToRemotePC(DWORD m_RemoteIP,int m_RemotePort,CString m_SendData);

public:

bool m_fConnected;

};

UDPSocket.cpp

#include "StdAfx.h"

#include "UDPSocket.h"

#include "AsyncSocketExDlg.h"

CUDPSocket::CUDPSocket(void)

{

m_fConnected = false;

}

CUDPSocket::~CUDPSocket(void)

{

}

void CUDPSocket::OnSend(int nErrorCode)

{

CAsyncSocketExDlg *pDl = CAsyncSocketExDlg::GetDialog();

pDl->OnSend(nErrorCode);

}

void CUDPSocket::OnReceive(int nErrorCode)

{

CAsyncSocketExDlg *pDl = CAsyncSocketExDlg::GetDialog();

pDl->OnReceive(nErrorCode);

}

bool CUDPSocket::BindLocatePC(DWORD m_LocateIP,int m_LocatePort)

{

in_addr tempAddr;

CString buf;

LPCTSTR p ;

//获取本地IP

tempAddr.S_un.S_addr = htonl(m_LocateIP);

buf = inet_ntoa(tempAddr);

p = (LPCTSTR) buf;

//AfxMessageBox(_T(p));

//绑定本地IP

if (!Create(htons(m_LocatePort),SOCK_DGRAM,FD_READ|FD_WRITE,p))

{

return false;

}

/*if(!Bind(0,p))

{

return false;

}*/

//设置连接标志

m_fConnected = true;

return true ;

}

bool CUDPSocket::SendToRemotePC(DWORD m_RemoteIP,int m_RemotePort,CString m_SendData)

{

in_addr tempAddr;

char send_buf[1024] ;

CString buf;

LPCTSTR p ;

//发送数据

if (m_fConnected)

{

//获取远程IP

tempAddr.S_un.S_addr = htonl(m_RemoteIP);

buf = inet_ntoa(tempAddr);

p = (LPCTSTR) buf;

strcpy(send_buf,(char *)m_SendData.GetBuffer(m_SendData.GetLength())); //获取数据

//发送数据

//int iByte = SendToEx(send_buf,strlen(send_buf)+1,htons(m_RemotePort),p);//只支持IPv6

int iByte=SendTo(send_buf,strlen(send_buf)+1,htons(m_RemotePort),p);

//判断是否发送成功

if (iByte>0)

return true ;

else

return false ;

}

return false;

}

AsyncSocketExDlg.h

// AsyncSocketExDlg.h : 头文件

#pragma once

#include "UDPSocket.h"

#include "resource.h"

// CAsyncSocketExDlg 对话框

class CAsyncSocketExDlg : public CDialog

{

// 构造

public:

CAsyncSocketExDlg(CWnd* pParent = NULL); // 标准构造函数

// 对话框数据

enum { IDD = IDD_ASYNCSOCKETEX_DIALOG };

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持

// 实现

public:

void OnSend(int nErrorCode);

void OnReceive(int nErrorCode);

static CAsyncSocketExDlg *GetDialog();

CUDPSocket* m_pSocket;

protected:

HICON m_hIcon;

// 生成的消息映射函数

virtual BOOL OnInitDialog();

afx_msg void OnPaint();

afx_msg HCURSOR OnQueryDragIcon();

DECLARE_MESSAGE_MAP()

public:

afx_msg void OnBnClickedButtonExit();

public:

DWORD m_LocateIP;

public:

DWORD m_RemoteIP;

public:

int m_LocatePort;

public:

int m_RemotePort;

public:

CString m_SendData;

public:

CString m_ReceiveData;

public:

afx_msg void OnBnClickedButtonSetup();

public:

afx_msg void OnBnClickedButtonSend();

};

AsyncSocketEx.cpp

// AsyncSocketExDlg.cpp : 实现文件

//

#include "stdafx.h"

#include "AsyncSocketEx.h"

#include "AsyncSocketExDlg.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

const int DATA_BUFFER_LENGHT = 1024;

// CAsyncSocketExDlg 对话框

CAsyncSocketExDlg::CAsyncSocketExDlg(CWnd* pParent /*=NULL*/)

: CDialog(CAsyncSocketExDlg::IDD, pParent)

, m_LocateIP(0)

, m_RemoteIP(0)

, m_LocatePort(0)

, m_RemotePort(0)

, m_SendData(_T(""))

, m_ReceiveData(_T(""))

{

m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

m_LocateIP = ntohl(inet_addr("10.10.210.6"));

m_RemoteIP = ntohl(inet_addr("10.10.210.6"));

m_pSocket = NULL;

}

void CAsyncSocketExDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

DDX_IPAddress(pDX, IDC_IPADDRESS_LOCATEIP, m_LocateIP);//把ip控件IDC_IPADDRESS_LOCATEIP和m_LocateIP关联,m_LocateIP改变,控件的值也改变

DDX_IPAddress(pDX, IDC_IPADDRESS_REMOTEIP, m_RemoteIP);

DDX_Text(pDX, IDC_EDIT_LOCATEPORT, m_LocatePort);//把文本框控件IDC_EDIT_LOCATEPORT和m_LocatePort关联

DDX_Text(pDX, IDC_EDIT_REMTEPORT, m_RemotePort);

DDX_Text(pDX, IDC_EDIT_SENDDATA, m_SendData);

DDX_Text(pDX, IDC_EDIT_RECEIVEDATA, m_ReceiveData);

}

BEGIN_MESSAGE_MAP(CAsyncSocketExDlg, CDialog)

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

//}}AFX_MSG_MAP

ON_BN_CLICKED(IDC_BUTTON_EXIT, &CAsyncSocketExDlg::OnBnClickedButtonExit)

ON_BN_CLICKED(IDC_BUTTON_SETUP, &CAsyncSocketExDlg::OnBnClickedButtonSetup)

ON_BN_CLICKED(IDC_BUTTON_SEND,

END_MESSAGE_MAP()

// CAsyncSocketExDlg 消息处理程序

BOOL CAsyncSocketExDlg::OnInitDialog()

{

CDialog::OnInitDialog();

// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动

// 执行此操作

SetIcon(m_hIcon, TRUE); // 设置大图标

SetIcon(m_hIcon, FALSE); // 设置小图标

// TODO: 在此添加额外的初始化代码

return TRUE; // 除非将焦点设置到控件,否则返回 TRUE

}

// 如果向对话框添加最小化按钮,则需要下面的代码

// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,

// 这将由框架自动完成。

void CAsyncSocketExDlg::OnPaint()

{

if (IsIconic())

{

CPaintDC dc(this); // 用于绘制的设备上下文

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

// 使图标在工作矩形中居中

int cxIcon = GetSystemMetrics(SM_CXICON);

int cyIcon = GetSystemMetrics(SM_CYICON);

CRect rect;

GetClientRect(&rect);

int x = (rect.Width() - cxIcon + 1) / 2;

int y = (rect.Height() - cyIcon + 1) / 2;

// 绘制图标

dc.DrawIcon(x, y, m_hIcon);

}

else

{

CDialog::OnPaint();

}

}

//当用户拖动最小化窗口时系统调用此函数取得光标显示。

//

HCURSOR CAsyncSocketExDlg::OnQueryDragIcon()

{

return static_cast<HCURSOR>(m_hIcon);

}

void CAsyncSocketExDlg::OnBnClickedButtonExit()

{

// TODO: 在此添加控件通知处理程序代码

//关闭对话框,退出系统

EndDialog(0);

}

void CAsyncSocketExDlg::OnBnClickedButtonSetup()

{

// 检查套接字是否为空

if (m_pSocket != NULL)

{

delete m_pSocket;

m_pSocket = NULL;

}

// 创建新的套接字指针

m_pSocket = new CUDPSocket();

UpdateData(1);

//绑定本地IP

if (!m_pSocket->BindLocatePC(m_LocateIP,m_LocatePort) )//绑定套接字后,OnSend事件自动响应

{

AfxMessageBox(_T("Socket创建失败!"));

return;

}

}

void CAsyncSocketExDlg::OnBnClickedButtonSend()

{

//发送数据

if (m_pSocket != NULL)

{

UpdateData(1);

if (!m_pSocket->SendToRemotePC(m_RemoteIP,m_RemotePort,m_SendData))

{

AfxMessageBox(_T("发送数据失败!"));

return;

}

else

{

AfxMessageBox(_T("发送数据成功!"));

}

}

}

CAsyncSocketExDlg * CAsyncSocketExDlg::GetDialog()

{

CAsyncSocketExDlg *pDl = (CAsyncSocketExDlg *)(AfxGetApp()->m_pMainWnd);

if (!pDl)

return NULL;

return (pDl);

}

//

void CAsyncSocketExDlg::OnSend(int nErrorCode)

{

in_addr buf;

buf.S_un.S_addr = htonl(m_RemoteIP);

m_ReceiveData.Append("\r\n");

m_ReceiveData.Append(m_SendData);

m_ReceiveData.Append(" Have sent to ");

m_ReceiveData.Append(inet_ntoa(buf));

//刷新显示

UpdateData(0);

}

//

void CAsyncSocketExDlg::OnReceive(int nErrorCode)

{

in_addr tempAddr;

tempAddr.S_un.S_addr = htonl(m_RemoteIP);

CString m_rAddr=inet_ntoa(tempAddr);

UINT m_rPort=(UINT)m_RemotePort;

char receive_buf[DATA_BUFFER_LENGHT] ;

if (m_pSocket != NULL)

{

//清空缓冲区,不清空就会出现乱码

memset(receive_buf, 0,DATA_BUFFER_LENGHT*sizeof(char));

//接收消息

//int nBytes = m_pSocket->ReceiveFromEx(receive_buf,DATA_BUFFER_LENGHT,m_rAddr,m_rPort,0);

int nBytes = m_pSocket->ReceiveFrom(receive_buf,sizeof(receive_buf),m_rAddr,m_rPort,0);

if (nBytes == SOCKET_ERROR)

{

AfxMessageBox(_T("数据接收失败Client!"));

return;

}

//整理接收信息

receive_buf[nBytes] = '\0';

strcat(receive_buf," From:") ;

strcat(receive_buf,(char *)m_rAddr.GetBuffer(m_rAddr.GetLength())) ;

char buf[100];

itoa(ntohs(m_rPort),buf,10);

strcat(receive_buf," :") ;

strcat(receive_buf,buf) ;

m_ReceiveData.Append("\r\n");

m_ReceiveData.Append(receive_buf);

//刷新显示

UpdateData(0);

}

}

运行过程如下:

1、两方主机都点击初始化按钮,系统绑定本地IP和端口

2、点击发送按钮对远程主机进行数据发送,远程主机自动接收对端的数据并显示,若接收失败,则会显示数据接受失败。

3、数据发送完毕,点击退出按钮退出程序。

运行结果如图所示:

MFC编程报告

MFC编程报告

6、分析结果

1、当点击初始化按钮时、窗口类调用CUDPSocket的BindLocatePC绑定本地IP和端口,绑定后自动调用OnSend函数把发送的数据显示在窗口类中,因此可以看见“你好 Have sent to 10.10.210.6”。

2、当点击发送时,窗口类向CUDPSocket的SendToRemotePC函数传递远程主机IP和端口和发送数据参数来向远程主机发送数据,数据发送完毕后自动调用OnReceive接受远程主机的数据,并显示在窗口类中。

3、远程主机工作过程相同。

相关推荐