📄 毕业设计数字逻辑电子仿真器view.cpp
字号:
{
//判断两个物件是否能连接
//这两个物件分别由pNodeStart和pNodeCurrent指向
//两个触点分别由startput和currentput标识
//若所指同一物件
if(pNodeStart==pNodeCurrent)
{
MessageBox("连接错误!自身物件不能相互连接");
return FALSE;
}
//输出直接结输出
if(startput==Output_1 && currentput==Output_1)
{
MessageBox("连接错误!输出端不能相互连接");
return FALSE;
}
//输入直接连接输入
if( (startput==Input_1 || startput==Input_2)
&& (currentput==Input_1||currentput==Input_2) )
{
MessageBox("连接错误!输入端不能相互连接");
return FALSE;
}
//循环连接
if( (startput==Output_1)
&&(currentput==Input_1||currentput==Input_2) )
{
if(pNodeCurrent->output1 ==pNodeStart)
{
MessageBox("连接错误!不能循环连接");
return FALSE;
}
}
if( (startput==Input_1||startput==Input_2)
&&(currentput==Output_1) )
{
if(pNodeStart->output1 ==pNodeCurrent)
{
MessageBox("连接错误!不能循环连接");
return FALSE;
}
}
//如果以上情况都不发生,表示可以连接
return TRUE;
}
void CMyView::LineLink()
{
//画两个物件之间的连接线
//记录两个物件之间的连接线经过的关键点
recordLine();
}
void CMyView::recordLine ()
{
//记录两个物件之间的连接线经过的关键点
//先动态生成一个数组CArray<CPoint,CPoint>之对象
//记录下连接线的关键点,然后将这个数组对象之地址加入到
//CList<CArray<CPoint,CPoint>*,CArray<CPoint,CPoint>*> MyPointList中
int x0,y0,x1,y1,delta_x,delta_y;
//(x0,y0)用于记录输出端起始点坐标
//(x1,y1)用于记录输入端终点坐标
//delta_x,delta_y用于记录x和y的偏移量
//一定是从输出端向输入端画线
if(startput==Output_1)
{
x0=startpoint.x;
y0=startpoint.y;
x1=currentpoint.x;
y1=currentpoint.y;
}
else
{
x1=startpoint.x;
y1=startpoint.y;
x0=currentpoint.x;
y0=currentpoint.y;
}
delta_x=5;
//动态生成数组对象
CArray<CPoint,CPoint>* pPointArray=new CArray<CPoint,CPoint>;
//根据点的位置分为三种情况:2个点,4个点,5个点
if(x0<x1)
{
if(y0==y1)
{
//两个点情况
pPointArray->Add (CPoint(x0,y0));
pPointArray->Add (CPoint(x1,y1));
}
else
{
//4个点情况
pPointArray->Add (CPoint(x0,y0));
pPointArray->Add (CPoint(x0+delta_x,y0));
pPointArray->Add (CPoint(x0+delta_x,y1));
pPointArray->Add (CPoint(x1,y1));
}
}
else if(x0==x1)
{
//两个点情况
pPointArray->Add (CPoint(x0,y0));
pPointArray->Add (CPoint(x1,y1));
}
else //x0>x1
{
//5个点情况
if(y0<y1)
{
delta_y=20;
}
else
{
delta_y=-20;
}
pPointArray->Add (CPoint(x0,y0));
pPointArray->Add (CPoint(x0,y0+delta_y));
pPointArray->Add (CPoint(x1-delta_x,y0+delta_y));
pPointArray->Add (CPoint(x1-delta_x,y1));
pPointArray->Add (CPoint(x1,y1));
}
//加入当前数组对象地址到MyPointList
MyPointList.AddTail (pPointArray);
//用数组中的点画线
DrawLinkLine(pPointArray);
}
//用数组中的点画线
void CMyView::DrawLinkLine(CArray<CPoint,CPoint>* pPointArray)
{
CClientDC dc(this);
for(int i=0;i<pPointArray->GetSize ()-1;i++)
{
dc.MoveTo (pPointArray->GetAt (i));
dc.LineTo (pPointArray->GetAt (i+1));
}
}
//真正的两个物件之间的连接:指针连接
void CMyView::RealLink()
{
//一定是输入连接输出 或 输出连接输入
if(startput==Input_1||startput==Input_2)
{
//输入连接输出
if(startput==Input_1)
{
pNodeStart->input1 =pNodeCurrent;
}
else
{
pNodeStart->input2 =pNodeCurrent;
}
pNodeCurrent->output1 =pNodeStart;
}
else//startput==Output_1
{
pNodeStart->output1 =pNodeCurrent;
if(currentput==Input_1)
{
pNodeCurrent->input1 =pNodeStart;
}
else
{
pNodeCurrent->input2 =pNodeStart;
}
}
}
//重绘连接线
void CMyView::LinkLineRedraw(CPoint startpoint, CPoint point)
{
//将起点startpoint到终点point扩充成一个矩形drawrect
CRect drawrect(startpoint,point);
//rect用于产生连接线最大矩形
CRect rect;
//rectInter用于计算两个矩形的相交区域
CRect rectInter;
//point1和point2用于产生连接线最大矩形
CPoint point1;
CPoint point2;
drawrect.NormalizeRect ();
drawrect.InflateRect (1,1);
//遍历MyPointList链表
POSITION pos=MyPointList.GetHeadPosition ();
while(pos!=0)
{
//pPointArray用于指向点数组对象首址
CArray<CPoint,CPoint>* pPointArray=MyPointList.GetNext (pos);
point1=pPointArray->GetAt (0);
switch(pPointArray->GetSize ())
{
//分两种情况 :2个点和4,5个点的情况
case 2:
//2个点时
point2=pPointArray->GetAt (1);
break;
default:
//4,5个点时
point2=pPointArray->GetAt (3);
}
//用point1和point2设置矩形rect
rect.left =point1.x ;
rect.top =point1.y;
rect.right =point2.x;
rect.bottom =point2.y;
rect.NormalizeRect ();
rect.InflateRect (1,1);
//如果两个矩形相交,则要重绘
if(rectInter.IntersectRect (&drawrect,&rect))
{
DrawLinkLine(pPointArray);
}
}
}
void CMyView::redrawnum()
{
CClientDC dc(this);
char buffer[20];
CPoint point;
//重绘所有Input前的序号
for(int i=0;i<numpoint.GetSize ();i++)
{
//将数字转换成字符,存于buffer中
_itoa(i+1,buffer,10);
point=numpoint.GetAt (i);
dc.TextOut (point.x ,point.y ,buffer);
}
}
void CMyView::moveoutredrawline()
{
int x,y;
x=pNodeNow->Orgpoint .x +circlepoint.x;
y=pNodeNow->Orgpoint .y +circlepoint.y;
CPoint point1;
CPoint point2;
point1.x=x-4;
point1.y=y-4;
point2.x=x+4;
point2.y=y+4;
LinkLineRedraw(point1,point2);
}
void CMyView::OnBegin()
{
//开始计算,输出真值表
// TODO: Add your command handler code here
//判断是否能够连接
if(CalculateResult()==-1)
{
MessageBox("连接线路失败!请检查线路");
}
else
{
//可以连接
//调用函数计算
beginCalculate();
//生成对话框对象
CMyDialog MyDialog;
MyDialog.DoModal ();
}
}
int CMyView::CalculateResult()
{
//用于从输入端开始计算输出端结果
//遍历所有输入结点
MyNode* pNode;
MyNode* pNodeNext;
POSITION pos=MyList.GetHeadPosition ();
while(pos!=0)
{
pNode=MyList.GetNext (pos);
//判断当前结点是否是输入结点
if(pNode->Subtype ==Input)
{
for(;;)
{
//判断当前的输入结点的输出端指向的结点是否为空
//如果为空,表示连接失败
if(pNode->output1 ==0)
{
//连接失败,返回-1
return -1;
}
//否则不为空
//输出到它指向结点的输入端
//此时要判断输入到哪个输入端:input1 OR input2;
pNodeNext=pNode->output1 ;
if(pNodeNext->input1 ==pNode)
{
//如果是输入到input1
pNodeNext->input1value =pNode->output1value ;
//输入的值++,如果到了2,就可以计算进位了
pNodeNext->inputs ++;
}
else
{
//如果是输入到input2
pNodeNext->input2value =pNode->output1value ;
pNodeNext->inputs ++;
}
//指针跳向下一个结点
pNode=pNodeNext;
//判断此时是否是输出结点,如果是返回输出结点的值input1value;
if(pNode->Subtype ==Output)
{
return pNode->input1value ;
}
//判断是否可以进位,对于非门,只要有一个输入值即可inputs==1
//对于其他门,要两个输入值inputs==2
if(pNode->Subtype==NOTGate)
{
//非门
if(pNode->inputs==1)
{
//可以进位
pNode->output1value =gatefunction(pNode);
}
else
{
//不能进位
break;//跳出for(;;)
}
}
else
{
//其他门
if(pNode->inputs ==2)
{
pNode->output1value =gatefunction(pNode);
}
else
{
//不能进位
break;//跳出for(;;)
}
}
//请空输入值个数inputs,以便下次计算
pNode->inputs =0;
}//for(;;)
}//判断当前结点是否是输入结点
}//while(pos!=0)
//遍历完后若没有返回,说明连接失败
return -1;
}
UINT CMyView::gatefunction(MyNode *pNode)
{
UINT result;
switch(pNode->Subtype )
{
case ANDGate:
result=pNode->input1value & pNode->input2value ;
break;
case ORGate:
result=pNode->input1value | pNode->input2value ;
break;
case NOTGate:
result=pNode->input1value ;
result=1-result;
break;
case NORGate:
result=pNode->input1value | pNode->input2value ;
result=1-result;
break;
case NANDGate:
result=pNode->input1value & pNode->input2value ;
result=1-result;
break;
case XORGate:
result=pNode->input1value ^ pNode->input2value ;
}
return result;
}
void CMyView::beginCalculate()
{
//计算输入结点的个数,输出真值表
n=numpoint.GetSize ();
//计算要进行循环的次数
int i;
x=1;
for(i=1;i<=n;i++)
{
x=x*2;
}
//动态生成x个字符串保存真值表
//用一个字符串格式化数据
CString str;
//用一个数组I[1]~I[n]记录每个输入结点值
UINT* I=new UINT[n+1];
//用数组J[1]~J[n]辅助计算
UINT* J=new UINT[n+1];
//初始化J[1]~J[n]
J[1]=1;
for(i=2;i<=n;i++)
{
J[i]=J[i-1]*2;
}
//进行x次循环,计算真值表
for(i=0;i<x;i++)
{
//增加数组元素:加入一个字符串
strs.Add (CString());
for(int k=1;k<=n;k++)
{
I[k]=i & J[k];
//向右移位
I[k]=I[k]>>(k-1);
//将输入端1~n的值加入字符串
str.Format ("%d ",I[k]);
//
//连接起来
strs[i]=strs[i]+str;
}
//给输入结点1~n初始化值
POSITION pos=MyList.GetHeadPosition ();
MyNode* pNode;
while(pos!=0)
{
pNode=MyList.GetNext (pos);
//如果结点是输入结点
if(pNode->Subtype ==Input)
{
//结点中的pNode->number 记录了结点序号
//给结点初始化值
pNode->output1value =I[pNode->number ];
}
}
//调用函数计算,将计算结果保存
int result=CalculateResult();
//生成字符串以便输出
str.Format ("%10d",result);
strs[i]+=str;
}
}
void CMyView::SetInputValue()
{
//给输入结点1~n初始化值
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -