⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 instruction.txt

📁 实验七 在网络中传输图像:采用C++
💻 TXT
字号:
新建MFC多文档工程,名为Draw
Step4中选择Windows Socket特点
完成
Insert|Nuw Class,保留类类型的设置为MFC Class, 在Name一栏中填入类名CMySocket,在Base Class中选择CAsyncSocket,按确定.
在类CMySocket中添加私有成员变量CDocument* m_pDoc
在类CMySocket中添加成员函数void SetParent(CDocument* pDoc)
void CMySocket::SetParent(CDocument* pDoc)
{
	//开始添加
	m_pDoc=pDoc;
	//结束添加
}

在类CMySocket中虚拟继承父类的成员函数OnAccept(),OnClose(),OnReceive(),OnSend(),
把这些函数中原来的代码删除,加入以下内容

void CMySocket::OnAccept(int nErrorCode) 
{
	// TODO: Add your specialized code here and/or call the base class
	//开始添加
	if(nErrorCode==0)
		((CDrawDoc*)m_pDoc)->OnAccept();
	//结束添加
}

void CMySocket::OnClose(int nErrorCode) 
{
	// TODO: Add your specialized code here and/or call the base class
	//开始添加
	if(nErrorCode==0)
		((CDrawDoc*)m_pDoc)->OnClose();
	//结束添加
	
}

void CMySocket::OnReceive(int nErrorCode) 
{
	// TODO: Add your specialized code here and/or call the base class
	//开始添加
	if(nErrorCode==0)
		((CDrawDoc*)m_pDoc)->OnReceive();
	//结束添加

}

void CMySocket::OnSend(int nErrorCode) 
{
	// TODO: Add your specialized code here and/or call the base class
	//开始添加
	if(nErrorCode==0)
		((CDrawDoc*)m_pDoc)->OnSend();
	//结束添加

}

在MySocket.cpp中#include "MySocket.h"下方加入一行#include "DrawDoc.h"
在DrawDoc.cpp中#include "DrawDoc.h"这一行下方加一行#include "MySocket.h"
在DrawDoc.h中class CDrawDoc : public CDocument这一行上方加一行#include "MySocket.h"
为CDrawDoc添加四个变量:私有成员CMySocket m_sListenSocket,CString m_strName,int m_iPort.公有成员CMySocket m_sConnectSocket.
修改CDrawDoc的OnNewDocument函数如下:
BOOL CDrawDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	//开始添加
	m_strName="127.0.0.1";
	m_iPort=500;
	m_sConnectSocket.SetParent(this);
	m_sListenSocket.SetParent(this);
	//结束添加
	// (SDI documents will reuse this document)

	return TRUE;
}

在菜单IDR_DRAWTYPE中加入菜单项"连接",选中选项"弹出"
在"连接"菜单下加入菜单项"监听连接",ID设定为ID_LISTEN
在"连接"菜单下加入菜单项"连接对方",ID设定为ID_CONN
在"连接"菜单下加入菜单项"关闭连接",ID设定为ID_BCLOSE

在MFC ClassWizard中,ClassName选择CDrawDoc,为ID_LISTEN,ID_CONN,ID_BCLOSE的COMMAND事件添加处理函数OnListen(),OnConn,OnBclose();
在CDrawDoc中按如下修改这三个函数的代码:
void CDrawDoc::OnConn()
{
	//开始添加
	m_sConnectSocket.Create();
	m_sConnectSocket.Connect(m_strName,m_iPort);
	//结束添加 
}

void CDrawDoc::OnListen()
{
	//开始添加
	m_sListenSocket.Create(m_iPort);
	m_sListenSocket.Listen();
	//结束添加
}
void CDrawDoc::OnBclose() 
{
	// TODO: Add your command handler code here
	//开始添加
	OnClose();
	//结束添加
}
在CDrawDoc的成员函数OnClose中添加代码如下:
void CDrawDoc::OnClose()
{
	//开始添加
	m_sConnectSocket.Close();
	AfxMessageBox("连接己被关闭!");
	//结束添加
}
在CDrawDoc的成员函数OnAccept中添加代码如下:
void CDrawDoc::OnAccept()
{
	//开始添加
 	m_sListenSocket.Accept(m_sConnectSocket);
	//结束添加
}

在CDrawDoc的成员函数OnSend中添加代码如下:
void CDrawDoc::OnSend()
{
	//开始添加
	MessageBox(NULL,"连接成功!","消息",MB_OK);
	//结束添加
	
}

编译运行程序,打开两个相同的程序,一个按下"监听连接",另一个按下"连接对方",如果跳出两个"连接成功"的对话框,则已经连接成功,可以在两个应用程序间互发消息了.

下面是创建绘图功能的过程:
创建线条类CLine:Insert|New class,Class Type选择Generic Class,Name中填写CLine,在Base Class第一行输入CObject作为基类,单击OK.有可能会跳出一个对话框如图,按OK就可以了.
为CLine类添加两个私有成员变量CPoint m_ptFrom,CPoint m_ptTo.
为CLine类添加构造函数CLine(CPoint ptFrom,CPoint ptTo)
CLine::CLine(CPoint ptFrom, CPoint ptTo)
{
	//开始添加
	m_ptFrom=ptFrom;
	m_ptTo=ptTo;
	//结束添加

}
为CLine类添加成员函数void Draw(CDC* PDC)
void CLine::Draw(CDC *PDC)
{
	//开始添加
	PDC->MoveTo(m_ptFrom);
	PDC->LineTo(m_ptTo);
	//结束添加

}
在CDrawDoc类中添加一个CObArray类型的私有成员变量m_oaLines来存放CLine对象
为CDrawDoc类添加公共成员函数CLine* AddLine(CPoint ptFrom,CPoint ptTo)
CLine* CDrawDoc::AddLine(CPoint ptFrom, CPoint ptTo)
{
	//开始添加
	CLine *pLine=new Cline(ptFrom,ptTo);
	try
	{
		m_oaLines.Add(pLine);
	}
	catch(CMemoryException* perr)
	{
		AfxMessageBox("Out of memory",MB_ICONSTOP|MB_OK);
		if(pLine)
		{
			delete pLine;
			pLine=NULL;
		}
		perr->Delete();
	}
	return pLine;
	//结束添加
}

为CDrawDoc类添加公共成员函数int GetLineCount()
int CDrawDoc::GetLineCount()
{
	//开始添加
	return m_oaLines.GetSize();
	//结束添加
}
为CDrawDoc类添加公共成员函数CLine* GetLine(int nIndex)
CLine* CDrawDoc::GetLine(int nIndex)
{
	//开始添加
	return (CLine*) m_oaLines[nIndex];
	//结束添加
}

在CDrawView类中添加一个私有成员变量CPoint m_ptPrevP,用以保存鼠标的前一个点
打开Class Wizard(建立类向导),Class Name选择CDrawView,在Message中双击WM_LBUTTONDOWN,WM_LBUTTONUP和WM_MOUSEMOVE,这样就为这三个消息添加了处理函数.
修改CDrawView的OnLButtonDown函数如下:
void CDrawView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	//开始添加
	SetCapture();
	m_ptPrevP=point;
	//结束添加

	CView::OnLButtonDown(nFlags, point);
}
修改CDrawView的OnLButtonUp函数如下:
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	//开始添加
	if(GetCapture()==this)
		ReleaseCapture();
	//结束添加

	CView::OnLButtonUp(nFlags, point);
}
修改CDrawView的OnMouseMove函数如下:
void CDrawView::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	//开始添加
	if((nflags & MK_LBUTTON)==MK_LBUTTON)
	{
		if(GetCapture()==this)
		{
			CClientDC dc(this);
			CLine* pLine=GetDocument()->AddLine(m_ptPrevP,point);
			pLine->Draw(&dc);
			m_ptPrevPos=point;
		}
	}
	//结束添加
	CView::OnMouseMove(nFlags, point);
}
修改CDrawView的OnDraw函数如下:
void CDrawView::OnDraw(CDC* pDC)
{
	CDrawDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	//开始添加
	int liCount=pDoc->GetLineCount();
	if(licount)
	{
		int liPos;
		CLine *lptLine;
		for(liPos=0;liPos<liCount;liPos++)
		{
			lptLine=pdoc->GetLine(liPos);
			lptLine->Draw(pDC);
		}
	}
	//结束添加

}
分别在DrawDoc.h,DrawDoc.cpp,DrawView.h,DrawView.cpp文件的开头加上#include "Line.h"
编译运行程序,可以看到绘图效果

下面是如何传输图像的过程:
修改CDrawView类中的OnMouseMove函数如下:
void CDrawView::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if((nFlags & MK_LBUTTON)==MK_LBUTTON)
	{
		if(GetCapture()==this)
		{
			CClientDC dc(this);
			CLine* pLine=GetDocument()->AddLine(m_ptPrevP,point);
			pLine->Draw(&dc);
			m_ptPrevP=point;

			//开始添加
			char* pBuf=new char[sizeof(CLine)];
			memcpy(pBuf,(char*)pLine,sizeof(CLine));
			GetDocument()->m_sConnectSocket.Send((LPCTSTR)(pBuf),sizeof(CLine));
			//结束添加

		}
	}
	CView::OnMouseMove(nFlags, point);
}
修改CDrawDoc类中的OnReceive函数如下:
void CDrawDoc::OnReceive()
{
	//开始添加
	char *pBuf=new char[1025];
	int iBufSize=1024;
	int iRcvd;
	CLine* pLine=new CLine;

	iRcvd=m_sConnectSocket.Receive(pBuf,iBufSize);
	if(iRcvd==SOCKET_ERROR)
	{
		AfxMessageBox("接收失败");
	}
	else
	{
		pBuf[iRcvd]=NULL;
		memcpy((char*)pLine,pBuf,sizeof(CLine));
		m_oaLines.Add(pLine);
		POSITION pos=this->GetFirstViewPosition();
		CView* pView=this->GetNextView(pos);
		CDC *hDC=pView->GetDC();
		pLine->Draw(hDC);
	}
	//结束添加
}
编译程序,运行两个程序,连接好以后在一个程序上画图,图像会同时发送到另一个程序中画出,观看效果.

下面是为程序画图添加颜色的过程:
在CLine类中添加类型为COLORREF的私有成员变量m_crColor,
修改构造函数CLine,注意头文件和.cpp文件都要改
CLine::CLine(CPoint ptFrom, CPoint ptTo,COLORREF crColor)
{
	m_ptFrom=ptFrom;
	m_ptTo=ptTo;
	//开始添加
	m_crColor=crColor;
	//结束添加

}
修改CLine类的Draw函数如下:
void CLine::Draw(CDC *PDC)
{
	//开始添加
	CPen lpen(PS_SOLID,1,m_crColor);
	CPen* pOldPen=PDC->SelectObject(&lpen);
	//结束添加

	PDC->MoveTo(m_ptFrom);
	PDC->LineTo(m_ptTo);

	//开始添加
	PDC->SelectObject(pOldPen);
	//结束添加
}

在菜单IDR_DRAWTYPE中加入菜单项"颜色",选中选项"弹出"
在"连接"菜单下加入菜单项"黑色",ID设定为ID_COLOR_BLACK
在"连接"菜单下加入菜单项"红色",ID设定为ID_COLOR_RED
在"连接"菜单下加入菜单项"绿色",ID设定为ID_COLOR_GREEN
在"连接"菜单下加入菜单项"蓝色",ID设定为ID_COLOR_BLUE
在CDrawDoc类中添加私有变量UINT m_nColor
在CDrawDoc类中添加static const COLORREF类型的私有变量m_crColors[4]
在文件DrawDoc.cpp中以下位置添加m_crColors的初始化代码.
DrawDoc.cpp
......
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

//开始添加
const COLORREF CDrawDoc::m_crColors[4]={
	RGB(0,0,0),
	RGB(255,0,0),
	RGB(0,255,0),
	RGB(0,0,255)
};
//结束添加 

/////////////////////////////////////////////////////////////////////////////
// CDrawingDoc construction/destruction

在CDrawDoc的OnNewDocument中加入代码如下
BOOL CDrawDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	//开始添加
	m_nColor=ID_COLOR_BLACK-ID_COLOR_BLACK;
	//结束添加

	......
	return TRUE;
}

将CDrawDoc类的AddLine函数中第一行	CLine *pLine=new CLine(ptFrom,ptTo)改为
CLine* pLine=new CLine(ptFrom,ptTo,m_crColors[m_nColor]);

在CDrawDoc类中添加一个公共成员函数UINT GetColor()
UINT CDrawDoc::GetColor()
{
	//开始添加
	return ID_COLOR_BLACK+m_nColor;
	//结束添加
}
打开ClassWizard,在Class Name组合框中选择CDrawDoc,为所有颜色菜单项的COMMAND和UPDATE_COMMAND_UI事件消息添加函数.

编辑CDrawDoc中的OnColorBlue和OnUpdateColorBlue函数如下:
void CDrawDoc::OnColorBlue() 
{
	// TODO: Add your command handler code here
	//开始添加
	m_nColor=ID_COLOR_BLUE-ID_COLOR_BLACK;
	//结束添加
	
}

void CDrawDoc::OnUpdateColorBlue(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	//开始添加
	pCmdUI->SetCheck(GetColor()==ID_COLOR_BLUE?1:0);
	//结束添加
	
}

其它三种颜色的消息处理函数同上修改,只是把ID_COLOR_BLUE换为相应的颜色ID.


然后就可以编译执行了

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -