随笔-68  评论-10  文章-0  trackbacks-0
刚学编程的时候写的,留下来做个纪念。

一、初步设计
1、新建工程slidwindow,在MFC的向导第一步选择Single Document,按Finish结束。
2、选择ResourceView窗口,打开菜单编辑器,在顶层菜单上添加开始单步菜单,其ID分别为ID_START_SLIDWINDID_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==0return true;
    
else return false;
}


bool CSlidwindowView::drop()
{
    
int a=rand()%200;
    
if(a==100return 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 阅读(1447) 评论(0)  编辑 收藏 引用 所属分类: 其它

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理