刚学编程的时候写的,留下来做个纪念。
一、初步设计
1、
新建工程slidwindow,在MFC的向导第一步选择Single Document,按Finish结束。
2、选择ResourceView窗口,打开菜单编辑器,在顶层菜单上添加“开始”和“单步”菜单,其ID分别为ID_START_SLIDWIND和ID_TRACE_SLIDWIND,在 Message 中选择COMMAND,分别添加消息处理函数,函数名默认。
3、 在Class Wizard中定时器消息添加处理函数。打开ClassWizard,选中Message Maps页。在Class Name中选择CslidwindowView,在Object ID 中选择CslidwindowView,在Message中选择WM_Timer,添加处理函数。
二、详细代码
1、
选择FileView|slidwindow files|Header Files:slidwindowView.h,添加如下成员变量。并添加头文件:
#include<Afxtempl.h>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
typedef struct
{
int x;
int y;
bool flag;
int time;
}sendBuf;
typedef struct
{
int x;
int y;
}resBuf;
class CSlidwindowView : public CView
{
public:
CSlidwindowDoc* GetDocument();
void Iniwind();
bool delay();
bool drop();
int findRePacket(resBuf pkt);
void sortRePacket();
int findSePacket(sendBuf pkt);
void sortSePacket();
private:
int m_nLeft,m_nTop;
int m_nWidth,m_nHeight,m_nSize;
int Current_s;
CPoint m_nSlidSws,m_nSlidRws;
CArray<CPoint,CPoint> Mess,Ack;
CPoint uPoint,aPoint;
vector<sendBuf> SBuf;
vector<resBuf> RBuf;
2、在
slidwindowView.cpp中添加如下宏定义:
#define _SWS 5
#define _RWS 5
#define maxn(_SWS,_RWS) ((_SWS>_RWS)?(_SWS):(_RWS))
3、
在slidwindowView.cpp中添加成员函数void Iniwind() , bool delay() , bool drop(), int findRePacket(resBuf pkt), void sortRePacket(),int findSePacket(sendBuf pkt), void sortSePacket()。
void CSlidwindowView::Iniwind()
{
m_nLeft=20;
m_nTop=20;
m_nWidth=32;
m_nHeight=13;
m_nSize=13;
m_nSlidSws=CPoint(m_nLeft,m_nTop);
m_nSlidRws=CPoint(m_nLeft,m_nTop+m_nHeight*m_nSize-m_nSize);
Current_s=m_nLeft;
Mess.RemoveAll();
Ack.RemoveAll();
SBuf.clear();
RBuf.clear();
}
bool CSlidwindowView::delay()
{
int a=rand()%100;
if(a%30==0) return true;
else return false;
}
bool CSlidwindowView::drop()
{
int a=rand()%200;
if(a==100) return true;
else return false;
}
int CSlidwindowView::findRePacket(resBuf pkt)
{
for(int i=0;i<RBuf.size();i++)
if(pkt.x==RBuf[i].x&&pkt.y==RBuf[i].y)
return i;
return -1;
}
void CSlidwindowView::sortRePacket()
{
resBuf temp;
int max=RBuf.size();
for(int i=0;i<max-1;i++)
for(int j=i+1;j<max;j++)
{
if(RBuf[i].x>RBuf[j].x)
{
temp.x=RBuf[i].x;
temp.y=RBuf[i].y;
RBuf[i].x=RBuf[j].x;
RBuf[i].y=RBuf[j].y;
RBuf[j].x=temp.x;
RBuf[j].y=temp.y;
}
}
}
int CSlidwindowView::findSePacket(sendBuf pkt)
{
for(int i=0;i<SBuf.size();i++)
if(pkt.x==SBuf[i].x&&pkt.y==SBuf[i].y)
return i;
return -1;
}
void CSlidwindowView::sortSePacket()
{
sendBuf temp;
int max=SBuf.size();
for(int i=0;i<max-1;i++)
for(int j=i+1;j<max;j++)
{
if(SBuf[i].x>SBuf[j].x)
{
temp.x=SBuf[i].x;
temp.y=SBuf[i].y;
temp.flag=SBuf[i].flag;
temp.time=SBuf[i].time;
SBuf[i].x=SBuf[j].x;
SBuf[i].y=SBuf[j].y;
SBuf[i].flag=SBuf[j].flag;
SBuf[i].time=SBuf[j].time;
SBuf[j].x=temp.x;
SBuf[j].y=temp.y;
SBuf[j].flag=temp.flag;
SBuf[j].time=temp.flag;
}
}
}
4、修改CslidwindowView的构造函数,完成初始化:
CSlidwindowView::CSlidwindowView()
{
// TODO: add construction code here
Iniwind();
}
5、为“开始”菜单的消息映射函数添加代码:
void CSlidwindowView::OnStartSlidwind()
{
// TODO: Add your command handler code here
Iniwind();
SetTimer(1,1000,NULL);
Invalidate();
}
6、为“单步”菜单的映射函数添加代码:
void CSlidwindowView::OnTraceSlidwind()
{
// TODO: Add your command handler code here
if(Current_s<m_nSlidSws.x+_SWS*m_nSize&&Current_s<m_nLeft+m_nWidth*m_nSize)
{
Current_s+=m_nSize; //last frame send
Mess.Add(CPoint(Current_s-m_nSize,m_nTop)); //未确认的消息
sendBuf spkt;
spkt.x=Current_s-m_nSize;
spkt.y=m_nTop;
spkt.flag=false;
spkt.time=28;
SBuf.push_back(spkt);
}
}
7、为定时器消息处理函数添加代码:
void CSlidwindowView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
int i;
for(i=0;i<=Mess.GetUpperBound();i++)
{
if(drop()) Mess.RemoveAt(i);
else if(delay()) continue;
else
{
uPoint=Mess.GetAt(i);
uPoint.y=uPoint.y+m_nSize;
Mess.RemoveAt(i);
Mess.InsertAt(i,uPoint);
if(uPoint.y>=m_nTop+m_nHeight*m_nSize-m_nSize)
{
if(uPoint.x>=m_nSlidRws.x+_RWS*m_nSize)
Mess.RemoveAt(i);
else
{
if(uPoint.x>=m_nSlidRws.x)
{
resBuf rpakt;
rpakt.x=uPoint.x;
rpakt.y=uPoint.y;
if(findRePacket(rpakt)==-1) RBuf.push_back(rpakt);
}
Mess.RemoveAt(i); //删除该点
Ack.Add(CPoint(uPoint.x,uPoint.y-m_nSize));
}
}
}
}
sortRePacket();
while(!RBuf.empty()&&m_nSlidRws.x==RBuf[0].x)
{
m_nSlidRws.x+=m_nSize;
RBuf.erase(RBuf.begin());
}
for(i=0;i<=Ack.GetUpperBound();i++)
{
if(drop()) Ack.RemoveAt(i);
else if(delay()) continue;
else
{
aPoint=Ack.GetAt(i);
aPoint.y-=m_nSize;
Ack.RemoveAt(i);
Ack.InsertAt(i,aPoint);
if(aPoint.y<=m_nTop)
{
if(aPoint.x>=m_nSlidSws.x && aPoint.x<m_nSlidSws.x+_SWS*m_nSize)
{
sendBuf spakt;
spakt.x=aPoint.x;
spakt.y=aPoint.y;
if(findSePacket(spakt)!=-1)
{
int vv=findSePacket(spakt);
SBuf[vv].flag=true;
}
}
Ack.RemoveAt(i);
}
}
}
sortSePacket();
while(!SBuf.empty()&&m_nSlidSws.x==SBuf[0].x&&SBuf[0].flag==true)
{
m_nSlidSws.x+=m_nSize;
SBuf.erase(SBuf.begin());
}
for(i=0;i<SBuf.size();i++)
{
if(SBuf[i].flag==false)
{
SBuf[i].time--;
if(SBuf[i].time==0)
{
SBuf[i].time=28;
SBuf[i].flag=false;
Mess.Add(CPoint(SBuf[i].x,SBuf[i].y));
}
}
}
InvalidateRect(CRect(m_nLeft-1,m_nTop-10,m_nLeft+(m_nWidth+maxn(_SWS,_RWS))*m_nSize,m_nTop+m_nHeight*m_nSize+10));
CView::OnTimer(nIDEvent);
}
8、 在OnDraw中加入代码:
void CSlidwindowView::OnDraw(CDC* pDC)
{
CSlidwindowDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
pDC->SelectStockObject(WHITE_BRUSH);
pDC->Rectangle(CRect(m_nLeft-1,m_nTop-1,m_nLeft+m_nWidth*m_nSize+1,m_nTop+m_nHeight*m_nSize+1));
CString uStr;
uStr.Format("SWS=5");
pDC->TextOut(m_nLeft+m_nWidth*m_nSize+150,60,uStr);
uStr.Format("RWS=5");
pDC->TextOut(m_nLeft+m_nWidth*m_nSize+150,80,uStr);
uStr.Format("上排绿色代表发送了但还没有收到ACK.");
pDC->TextOut(m_nLeft+m_nWidth*m_nSize+150,100,uStr);
uStr.Format("上排蓝色代表发送了并且已经收到ACK.");
pDC->TextOut(m_nLeft+m_nWidth*m_nSize+150,120,uStr);
uStr.Format("使用说明:先按‘开始’,然后再‘单步’执行。");
pDC->TextOut(m_nLeft+m_nWidth*m_nSize+150,140,uStr);
pDC->SelectStockObject(WHITE_BRUSH);
pDC->Rectangle(CRect(m_nLeft,m_nTop,m_nLeft+m_nWidth*m_nSize,m_nTop+m_nSize));
pDC->Rectangle(CRect(m_nLeft,m_nTop+m_nHeight*m_nSize-m_nSize,m_nLeft+m_nWidth*m_nSize,m_nTop+m_nHeight*m_nSize));
pDC->SelectStockObject(NULL_BRUSH);
pDC->Rectangle(CRect(m_nSlidSws.x,m_nSlidSws.y-5,m_nSlidSws.x+_SWS*m_nSize,m_nSlidSws.y+m_nSize+5));
pDC->Rectangle(CRect(m_nSlidRws.x,m_nSlidRws.y-5,m_nSlidRws.x+_RWS*m_nSize,m_nSlidRws.y+m_nSize+5));
CBrush brush(RGB(0,255,0)); //绿色
pDC->SelectObject(&brush);
pDC->Rectangle(CRect(m_nLeft,m_nTop,Current_s,m_nTop+m_nSize));
pDC->Rectangle(CRect(m_nLeft,m_nTop+m_nHeight*m_nSize-m_nSize,m_nSlidRws.x,m_nTop+m_nHeight*m_nSize));
int i;
for(i=0;i<RBuf.size();i++)
pDC->Rectangle(CRect(RBuf[i].x,RBuf[i].y,RBuf[i].x+m_nSize,RBuf[i].y+m_nSize));
for(i=0;i<=Mess.GetUpperBound();i++)
{
CPoint m=Mess.GetAt(i);
pDC->Rectangle(CRect(m.x,m.y,m.x+m_nSize,m.y+m_nSize));
}
CBrush br(RGB(0,0,225)); //蓝色
pDC->SelectObject(&br);
pDC->Rectangle(CRect(m_nLeft,m_nTop, m_nSlidSws.x,m_nTop+m_nSize));
for(i=0;i<SBuf.size();i++)
if(SBuf[i].flag==true)
pDC->Rectangle(CRect(SBuf[i].x,SBuf[i].y,SBuf[i].x+m_nSize,SBuf[i].y+m_nSize));
for(i=0;i<=Ack.GetUpperBound();i++)
{
CPoint a=Ack.GetAt(i);
pDC->Rectangle(CRect(a.x,a.y,a.x+m_nSize,a.y+m_nSize));
}
}
posted on 2010-08-10 00:20
wuxu 阅读(1446)
评论(0) 编辑 收藏 引用 所属分类:
其它