实验四 MFC图形绘制编程实验

时间:2024.4.13

实验四 MFC图形绘制编程实验

一、实验目的

(1) 熟悉Visual C++ 6.0开发环境;

(2) 掌握MFC消息映射的操作步骤;

(2) 掌握MFC图形输出的方法;

(3) 理解设备环境、画笔、画刷的概念,掌握常用的绘图函数。

二、实验内容

请编写程序,要求如下:

(1) 定义一支黄色画笔,绘制一条线段;

(1) 定义一支紫色画笔,绘制一条多段线;

(3) 定义一支红色画笔,绘制一个正方形,并用适当的画刷填充图形内部;

(4) 定义一支绿色画笔,绘制一个圆,并用适当的画刷填充图形内部;

(5) 定义一支蓝色画笔,绘制一个正六边形,并用适当的画刷填充图形内部。

三、实验报告

1.列出图形绘制程序代码清单:

(1)在头文件Demo.h中:

#include "afxwin.h"

class CDemoWnd:public CFrameWnd

{

public:

       CDemoWnd();

       ~CDemoWnd();

public:

       LRESULT OnPaint(WPARAM wParam,LPARAM lParam);

       DECLARE_MESSAGE_MAP()

public:

       int m_nX0;

       int m_nY0;

       int m_nX1;

       int m_nY1;

};

class CDemoApp:public CWinApp

{

public:

       BOOL InitInstance();

};

CDemoApp ThisApp;

(2)在源文件Demo.cpp中:

#include "tpd1.h"

CDemoWnd::CDemoWnd()

{

       m_nX0 = 0;

       m_nY0 = 0;

       m_nX1 = 0;

       m_nY1 = 0;

}

CDemoWnd::~CDemoWnd()

{

}

BEGIN_MESSAGE_MAP(CDemoWnd,CFrameWnd)

ON_MESSAGE(WM_PAINT,OnPaint)      

END_MESSAGE_MAP()

LRESULT CDemoWnd::OnPaint(WPARAM wParam,LPARAM lParam)

{

CPaintDC dc(this);

CPen Pen1,*pOldPen1;

Pen1.CreatePen(PS_SOLID,10,RGB(255,255,0));

pOldPen1=dc.SelectObject(&Pen1);

dc.SelectObject(&Pen1);

dc.MoveTo(10,10);

dc.LineTo(100,100);

      

CPen Pen2,*pOldPen2;

Pen2.CreatePen(PS_SOLID,4,RGB(255,0,255));

pOldPen2=dc.SelectObject(&Pen2);

dc.SelectObject(&Pen2);

POINT pt1[]={{100,10},{10,180},{200,150}};

dc.Polyline(pt1,3);

             

CPen Pen3,*pOldPen3;

dc.SelectStockObject(BLACK_BRUSH);

Pen3.CreatePen(PS_SOLID,4,RGB(255,0,0));

pOldPen3=dc.SelectObject(&Pen3);

dc.SelectObject(&Pen3);

dc.Rectangle(300,50,400,150);

CPen Pen4,*pOldPen4;

dc.SelectStockObject(GRAY_BRUSH);

Pen4.CreatePen(PS_SOLID,4,RGB(0,255,0));

pOldPen4=dc.SelectObject(&Pen4);

dc.SelectObject(&Pen4);

dc.Ellipse(500,200,700,400);

CPen Pen5,*pOldPen5;

Pen5.CreatePen(PS_SOLID,4,RGB(0,0,255));

pOldPen5=dc.SelectObject(&Pen5);

dc.SelectStockObject(DKGRAY_BRUSH);

dc.SelectObject(&Pen5);

POINT pt2[]={{250,250},{400,250},{475,379},{400,509},{250,509},{175,379}};

dc.Polygon(pt2,6);

return 0;

}

BOOL CDemoApp::InitInstance()

{

CDemoWnd *pMainWnd = new CDemoWnd();

pMainWnd->Create(NULL,"Demo Mini-MFC");

pMainWnd->ShowWindow(m_nCmdShow);

pMainWnd->UpdateWindow();

m_pMainWnd = pMainWnd;

return TRUE;

}

2、程序运行结果:

 

3、总结在MFC 程序中绘制图形的基本操作步骤:

(1)获取图形设备接口。图形设备接口(GDI)负责系统与用户或绘图程序之间的信息交换,并控制在输出设备上显示图形或文字,是Windows 系统的重要组成部分。

(2)获取设备环境。设备描述表用来定义绘图规则,设备描述表即为设备环境的属性的集合,可以将设备描述表看成图形的“输出模板”。应用程序每一次图形操作均参照设备描述表中的属性执行。获取设备环境是应用程序输出图形的先决条件,常用的两个MFC 类是CPaintDC ,CClientDC。CPaintDC 类应用程序响应 WM_PAINT 消息进行图形刷新时,主要通过CPaintDC 类对象获取设备环境。CClientDC如果绘图工作并非由WM_PAINT 消息驱动,则使用CClientDC 类的对象获取设备环境。

(3)选择绘图工具与颜色。画笔的操作:创建画笔,将画笔选入设备环境,删除画笔。 画刷的创建与应用也包括创建、选入设备环境和删除。最后设置颜色。

(4)选择绘图函数进行绘图。设置画笔当前位置的函数;从当前位置向指定坐标点画直线的函数;从当前位置开始,依次用线段连接 lpPoints 中指定的各点;绘制矩形,并用当前画刷进行填充;绘制椭圆,并用当前画刷填充;绘制多边形,并用当前画刷填充。

#include "tpd3.h"

CDemoWnd::CDemoWnd()

{

    m_nX0 = 0;

    m_nY0 = 0;

    m_nX1 = 0;

    m_nY1 = 0;

}

CDemoWnd::~CDemoWnd()

{

}

BEGIN_MESSAGE_MAP(CDemoWnd,CFrameWnd)

ON_MESSAGE(WM_PAINT,OnPaint)   

END_MESSAGE_MAP()

LRESULT CDemoWnd::OnPaint(WPARAM wParam,LPARAM lParam)

{

CPaintDC dc(this);

CPen Pen1,*pOldPen1;

Pen1.CreatePen(PS_SOLID,10,RGB(255,255,0));

pOldPen1=dc.SelectObject(&Pen1);

dc.SelectObject(&Pen1);

dc.MoveTo(50,10);

dc.LineTo(50,210);

   

CPen Pen2,*pOldPen2;

Pen2.CreatePen(PS_SOLID,4,RGB(255,0,255));

pOldPen2=dc.SelectObject(&Pen2);

dc.SelectObject(&Pen2);

POINT pt1[]={{300,10},{100,150},{200,50},{350,10}};

dc.Polyline(pt1,3);

       

CPen Pen3,*pOldPen3;

dc.SelectStockObject(BLACK_BRUSH);

Pen3.CreatePen(PS_SOLID,4,RGB(255,0,0));

pOldPen3=dc.SelectObject(&Pen3);

dc.SelectObject(&Pen3);

dc.Rectangle(400,50,500,150);

CPen Pen4,*pOldPen4;

dc.SelectStockObject(GRAY_BRUSH);

Pen4.CreatePen(PS_SOLID,4,RGB(0,255,0));

pOldPen4=dc.SelectObject(&Pen4);

dc.SelectObject(&Pen4);

dc.Ellipse(700,50,900,250);

CPen Pen5,*pOldPen5;

Pen5.CreatePen(PS_SOLID,4,RGB(0,0,255));

pOldPen5=dc.SelectObject(&Pen5);

dc.SelectStockObject(DKGRAY_BRUSH);

dc.SelectObject(&Pen5);

POINT pt2[]={{150,200},{300,200},{375,329},{300,459},{150,459},{75,329}};

dc.Polygon(pt2,6);

return 0;

}

BOOL CDemoApp::InitInstance()

{

CDemoWnd *pMainWnd = new CDemoWnd();

pMainWnd->Create(NULL,"Demo Mini-MFC");

pMainWnd->ShowWindow(m_nCmdShow);

pMainWnd->UpdateWindow();

m_pMainWnd = pMainWnd;

return TRUE;

}


第二篇:实验四 MFC网络编程


实验四  多线程聊天室的创建

预备知识:

程序、进程和线程

n  程序是计算机指令的集合,它以文件的形式存储在磁盘上。

n  进程:通常被定义为一个正在运行的程序的实例,是一个程序在其自身的地址空间中的一次执行活动。

n  进程是资源申请、调度和独立运行的单位,因此,它使用系统中的运行资源;而程序不能申请系统资源,不能被系统调度,也不能作为独立运行的单位,因此,它不占用系统的运行资源。

n  进程由两个部分组成:

   1、操作系统用来管理进程的内核对象。内核对象也是系统用来存放关于进程的统计信息的地方。

   2、地址空间。它包含所有可执行模块或DLL模块的代码和数据。它还包含动态内存分配的空间。如线程堆栈和堆分配空间。

n  进程是不活泼的。进程从来不执行任何东西,它只是线程的容器。若要使进程完成某项操作,它必须拥有一个在它的环境中运行的线程,此线程负责执行包含在进程的地址空间中的代码。

n  单个进程可能包含若干个线程,这些线程都“同时” 执行进程地址空间中的代码。

n  每个进程至少拥有一个线程,来执行进程的地址空间中的代码。当创建一个进程时,操作系统会自动创建这个进程的第一个线程,称为主线程。此后,该线程可以创建其他的线程。

线程运行:

n  操作系统为每一个运行线程安排一定的CPU时间 —— 时间片。系统通过一种循环的方式为线程提供时间片,线程在自己的时间内运行,因时间片相当短,因此,给用户的感觉,就好像线程是同时运行的一样。

n  如果计算机拥有多个CPU,线程就能真正意义上同时运行了。

实验步骤:

1、         新建一个基于对话框、支持Window sockets的MFC可执行应用程序(exe);

2、         设计如图所示界面:

(1)  对话框控件ID设置

(2)  接收数据框架:IDC_STATIC

(3)  接收数据编辑框:IDC_EDIT_RECV

(4)  发送数据编辑框:IDC_STATIC

(5)  IP地址控件:IDC_IPADDRESS1

(6)  发送数据编辑框:IDC_EDIT_SEND

(7)  发送命令按钮:IDC_BTN_SEND

3、         在MFC中调用AfxSocketInit()加载套接字库,参考MSDN两个版本:

(1)  在CWinApp::InitInstance 中调用;

(2)  在StdAfx.h中包含Afxsock.h头文件

源码:   if(!AfxSocketInit())

           {                 AfxMessageBox("加载套接字库失败!");

                             return FALSE;

           }

4、         创建并初始化套接字,为C***Dlg类添加一个private权限SOCKET类型的变量m_socket和一个BOOL类型的InitSocket()成员函数,在OnInitDialog()函数中调用InitSocket()函数实现初始化:

函数实现代码如下:

BOOL CCHATDlg::InitSocket()

{

  m_socket=socket(AF_INET,SOCK_DGRAM,0);

  if(INVALID_SOCKET==m_socket)

  {

     MessageBox("套接字创建失败!");

     return FALSE;

  }

  SOCKADDR_IN addrSock;

  addrSock.sin_family=AF_INET;

  addrSock.sin_port=htons(6000);

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

 

  int retval;

  retval=bind(m_socket,(SOCKADDR*)&addrSock,sizeof(SOCKADDR));

  if(SOCKET_ERROR==retval)

  {

     closesocket(m_socket);

     MessageBox("绑定失败!");

     return FALSE;

  }

  return TRUE;

}

5、         实现接收端功能

接收数据的时候会有阻塞,处理方式使用一个单独的线程,采用CreateThread();

   (1)先在C***Dlg类的前面定义一个结构体:

struct RECVPARAM{

  SOCKET sock;

  HWND hwnd;

};

   (2)在OnInitDialog()函数中定义一个RECVPARAM类型的指针,然后初始化:

RECVPARAM *pRecvParam=new RECVPARAM;

  pRecvParam->sock=m_socket;

  pRecvParam->hwnd=m_hWnd;

HANDLE hThread=CreateThread(NULL,0,RecvProc,

(LPVOID)pRecvParam,0,NULL);

  CloseHandle(hThread);

(3)在C***Dlg类添加函数成员,写线程函数:

static static DWORD WINAPI RecvProc(LPVOID lpParameter);

//定义线程函数

DWORD WINAPI CCHATDlg::RecvProc(LPVOID lpParameter)

{

    SOCKET sock=((RECVPARAM*)lpParameter)->sock;

    HWND hwnd=((RECVPARAM*)lpParameter)->hwnd;

    delete lpParameter; 

 

    SOCKADDR_IN addrFrom;

    int len=sizeof(SOCKADDR);

 

    char recvBuf[200];

    char tempBuf[300];

    int retval;

    while(TRUE)

    {

       retval=recvfrom(sock,recvBuf,200,0,

(SOCKADDR*)&addrFrom,&len);

       if(SOCKET_ERROR==retval)

           break;

       sprintf(tempBuf,"%s说: %s",

inet_ntoa(addrFrom.sin_addr),recvBuf);

//利用PostMessage将消息传递给对话框。

       ::PostMessage(hwnd,WM_RECVDATA,0,(LPARAM)tempBuf);

    }

    return 0;

}

(4)在C***Dlg类上面定义消息的值:

#define WM_RECVDATA    WM_USER+1

消息响应函数原型的声明

afx_msg void OnRecvData(WPARAM wParam,LPARAM lParam);

消息映射:

ON_MESSAGE(WM_RECVDATA,OnRecvData)

消息响应函数的实现:

   void CChatDlg::OnRecvData(WPARAM wParam,LPARAM lParam)

{

    CString str=(char*)lParam;

    CString strTemp;

    GetDlgItemText(IDC_EDIT_RECV,strTemp);

    str+="\r\n";

    str+=strTemp;

    SetDlgItemText(IDC_EDIT_RECV,str);

}

6、         实现发送端

void CChatDlg::OnBtnSend()

{

  // TODO: Add your control notification handler code here

  DWORD dwIP;

  ((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1))->GetAddress(dwIP);

 

  SOCKADDR_IN addrTo;

  addrTo.sin_family=AF_INET;

  addrTo.sin_port=htons(6000);

  addrTo.sin_addr.S_un.S_addr=htonl(dwIP);

 

  CString strSend;

  GetDlgItemText(IDC_EDIT_SEND,strSend);

  sendto(m_socket,strSend,strSend.GetLength()+1,0,

     (SOCKADDR*)&addrTo,sizeof(SOCKADDR));

  SetDlgItemText(IDC_EDIT_SEND,"");

}

更多相关推荐:
工程制图实验报告

实验一AutoCAD的启动和菜单结构,基本命令练习一、实验要求;1、学习AutoCAD的基本操作,掌握AutoCAD的绘图、修改、编辑、显示、拷贝等命令的用法;2、继续熟悉屏幕菜单输入命令的方法;3、绘制简单的…

工程制图实验报告(二版)

工程制图计算机绘图上机实验报告第二版班级学号姓名长沙理工大学交通运输学院测绘工程系土木制图教研组20xx年7月工程制图计算机绘图实验上机报告23工程制图计算机绘图实验上机报告45工程制图计算机绘图实验上机报告6...

工程制图实训报告

实训报告学号姓名班级代课老师220xx20902528朱娇建筑经济管理5班马煜通过学习和自身的实践,对土木工程这一个专业又有了进一步的认识,真正知道了理论和实际的差别,激发了对这一专业的更浓厚的兴趣,也学到了一…

工程制图实验报告格式

制图基础与计算机绘图实验报告实验报告课程名称制图基础及计算机绘图学生姓名班级学号指导教师指导单位理学院20xx年6月17日至20xx年6月19日日期制图基础与计算机绘图实验报告实验一平面图形的设计班级学号姓名第...

工程制图实验报告

郑州轻工业学院现代工程制图实验报告院系专业学号姓名完成时间20xx年2月1日现代工程制图实验报告一实验目的和设计内容1了解和掌握AltiumDesigner软件的基本使用方法和使用技巧2应用AltiumDesi...

工程制图实验报告

工程制图AutoCAD三维实体造型实验报告

电子工程制图实训报告

电子工程制图实训任务书1实训内容常见户型原始平面图和平面布置图电气工程图的标准和画法元件图装配图小车流程图接线图和线扎图2实训要求前言包括总体设计思想训练的目的设计要求各种图形的定义画图过程中的创建和修改工具使...

工程制图实验三:绘制三视图

实验三绘制三视图一实验目的1掌握利用三等规律绘制三视图的方法2掌握组合体的交线投影画法3掌握常见的AutoCAD20xx的绘图命令和编辑命令4了解三视图的尺寸标注二实验仪器1AutoCAD20xx应用软件一套2...

工程图学-实验3的实验报告

宁波工程学院电信学院工程图学基础实验报告实验名称常用绘图命令练习专业班级姓名学号实验日期指导教师一实验目的学会AutoCAD的基本绘图命令二实验内容掌握点构造线圆矩形正多边形等基本绘图命令题1绘制如图34的底板...

—通信制图实验报告

淮安信息职业技术学院通信工程制图阶段一学习报告模块一通信工程制图基础模块二CAD软件设置系部计算机与通信工程学院专业通信技术姓名成绩一学习目的1理解和掌握通信工程制图的总体要求和统一规定2掌握通信工程制图中的常...

AutoCAD上机实验报告-工程制图A(2)2 - 副本

实验报告计算机类课程名称工程制图A2课程代码820xx19学生所在学院机械工程及自动化学院学生姓名江凡实验总成绩任课教师汪勇开课学院机械工程与自动化学院实验中心名称年级专业班20xx级机制卓越班学号3120xx...

20xx 工程制图实验指导

工程制图实验指导非机械类适用实验一基本练习一目的1初步掌握国家标准工程制图的有关内容熟悉制图基本规格2练习正确使用绘图工具和仪器了解制图基本步骤和方法学会绘图仪器和工具的使用方法二内容抄绘工程制图习题集中第55...

工程制图实验报告(27篇)