📄 instruction.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 + -