📄 4rdview.cpp
字号:
// 4rdView.cpp : implementation of the CMy4rdView class
//
#include "stdafx.h"
#include "4rd.h"
#include "4rdDoc.h"
#include "4rdView.h"
#include "function.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern CDialogBar m_WndDlgBar;
/////////////////////////////////////////////////////////////////////////////
// CMy4rdView
IMPLEMENT_DYNCREATE(CMy4rdView, CScrollView)
BEGIN_MESSAGE_MAP(CMy4rdView, CScrollView)
//{{AFX_MSG_MAP(CMy4rdView)
ON_COMMAND(ID_Input, OnInput)
ON_COMMAND(ID_Tree, OnTree)
ON_WM_CHAR()
ON_COMMAND(ID_Caculate, OnCaculate)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_COMMAND(ID_Example1, OnExample1)
ON_COMMAND(ID_Example2, OnExample2)
ON_COMMAND(ID_Example3, OnExample3)
ON_COMMAND(ID_Example4, OnExample4)
ON_COMMAND(ID_Example5, OnExample5)
ON_COMMAND(ID_Example6, OnExample6)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMy4rdView construction/destruction
CMy4rdView::CMy4rdView()
{
// TODO: add construction code here
input=false;
m_input=false;
m_Instring="";
m_count=1;
m_tree=false;
m_cal=false;
ptree=false;
m_x=400;
m_y=50;
m_inVar=false;
move=false;
first=false;
}
CMy4rdView::~CMy4rdView()
{
}
BOOL CMy4rdView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CScrollView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CMy4rdView drawing
void CMy4rdView::OnDraw(CDC* pDC)
{
CMy4rdDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
RECT rt;
GetWindowRect(&rt );
CRect rect;
GetClientRect(&rect);
pDC->SetTextColor(RGB(128,128,128));
pDC->TextOut(rt.top-320+rect.Width(),rt.left-20+rect.Height(),"tips:图形可以按住鼠标左键拖动");
pDC->SetTextColor(RGB(0,0,0));
///////////////输出输入字符串////////////
pDC->SetTextColor(RGB(64,64,64));
if(input==true)
pDC->TextOut(0,0,m_Instring);
pDC->SetTextColor(RGB(0,0,0));
/////////////////////////////////////////
///////////////输出语法树////////////////
if(ptree==true)
PTree(pDC);
/////////////////////////////////////////
///////////////输出单步计算//////////////
if(out_cal==true)
Caculate(pDC);
/////////////////////////////////////////
/////////////////单步计算时输出标识符的值///////////////
if(m_id==true)
{
pDC->SetTextColor(RGB(255,0,0));//设置字体颜色
CString str;
int j=1;
for(int i=1;i<=total;i++)
{
if(table[i].evaluated==true)
{
str.Format("=%.2f",table[i].value);
pDC->TextOut(5,j*20,table[i].name+str);
j++;
}
}//for
pDC->SetTextColor(RGB(0,0,0));//把字体颜色设回黑色
}
////////////////////////////////////////////////////////
if(m_result==true)
{
pDC->SetTextColor(RGB(255,0,0));
pDC->TextOut(m_x-80,m_y,"最终结果=");
pDC->SetTextColor(RGB(0,0,0));
}
}
void CMy4rdView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
CSize sizeTotal;
// TODO: calculate the total size of this view
sizeTotal.cx = 10240;
sizeTotal.cy = 8000;
SetScrollSizes(MM_TEXT, sizeTotal);
}
/////////////////////////////////////////////////////////////////////////////
// CMy4rdView printing
BOOL CMy4rdView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CMy4rdView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CMy4rdView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CMy4rdView diagnostics
#ifdef _DEBUG
void CMy4rdView::AssertValid() const
{
CScrollView::AssertValid();
}
void CMy4rdView::Dump(CDumpContext& dc) const
{
CScrollView::Dump(dc);
}
CMy4rdDoc* CMy4rdView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMy4rdDoc)));
return (CMy4rdDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CMy4rdView message handlers
void CMy4rdView::OnInput()
{
// TODO: Add your command handler code here
initial();
m_input=true;
m_Instring="请输入表达式(以#或回车键结束):";
SetScrollPos(SB_HORZ,0,TRUE);//另x轴返回最左边
SetScrollPos(SB_VERT,0,TRUE);//另y轴返回最上边
Invalidate();
TEXTMETRIC metric;
CClientDC dc(this);
dc.GetTextMetrics(&metric);
CreateSolidCaret(metric.tmAveCharWidth/8,metric.tmHeight);
CSize size=dc.GetTextExtent(m_Instring);
SetCaretPos(CPoint(size.cx,0));
ShowCaret();
m_WndDlgBar.GetDlgItem(ID_Tree)->SetWindowText("开始生成语法树(F5)");
m_WndDlgBar.GetDlgItem(ID_Caculate)->SetWindowText("开始进行计算(F8)");
this->SetFocus(); //设置焦点到输入框
}
void CMy4rdView::OnTree()
{
// TODO: Add your command handler code here
if(m_tree==true)
{
if(first==true)
{
for(int i=0;i<100;i++)
{
table[i].evaluated=false;
strcpy(table[i].name,"");
}
number=1;
position=1;
gettoken();
root=extr();
if(isok==false) //遇到错误退出
{
m_tree=false;
MessageBox("请重新输入!","编译原理");
OnInput(); //重新输入
return;
}
if(root->left==NULL||root->right==NULL) //没可能跟结点的孩子为空
{
m_tree=false;
MessageBox("输入错误!请重新输入!");
OnInput(); //重新输入
return;
}
/* if(!ErrorTest(root)) //错误检测
{
m_tree=false;
MessageBox("ErrorTest函数检测到错误!");
return;
}
*/
// if(lookahead!=0)
// MessageBox("不正常结束!");
// MessageBox("语法树生成成功!");
for(i=0;i<100;i++)
Pos[i]=NULL;
xy *p=new xy;
p->x=m_x;
p->y=m_y;
Pos[root->No]=p;
ZuoBiao(root->left,root,0); //把所以结点的坐标算出来,储存在xy[]数组中
ZuoBiao(root->right,root,0);
number=1;
first=false;
ptree=true;
Invalidate();
m_WndDlgBar.GetDlgItem(ID_Tree)->SetWindowText("扩展下一个根(F5)");
// MessageBox("语法树开始生成!按F5键继续!","编译原理");
}
else
{
number++;
Invalidate();
if(number>=root->No)
{
m_WndDlgBar.GetDlgItem(ID_Tree)->SetWindowText("开始生成语法树(F5)");
MessageBox("语法树生成完毕!","编译原理");
m_cal=true;
out_cal=true;
first2=true;
m_tree=false;
}
}
}
else
MessageBox("请先输入完整的表达式!","编译原理");
}
void CMy4rdView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
if(m_input==true)
{
if(isalpha(nChar)||isdigit(nChar)||nChar=='('||nChar==')'||nChar=='#'||
nChar=='+'||nChar=='-'||nChar=='*'||nChar=='/'||nChar=='.'||nChar=='='||
nChar==' ')
{
buffer[m_count]=nChar;
m_count++;
m_Instring+=nChar;
CClientDC dc(this);
CSize size=dc.GetTextExtent(m_Instring);
SetCaretPos(CPoint(size.cx,0)); //重设光标位置
Invalidate();
if(nChar=='#')
{
m_input=false; //输入结束
m_tree=true; //语法树可以开始生成了
first=true;
MessageBox("输入完毕","编译原理");
}
}
if(nChar==VK_RETURN) //遇到回车键的处理
{
buffer[m_count]=nChar;
m_input=false; //输入结束
m_tree=true; //语法树可以开始生成了
first=true;
MessageBox("输入完毕","编译原理");
}
if(nChar==VK_BACK) //遇到回退键的处理
{
if(m_count>1)
{
m_count--;
m_Instring="请输入表达式(以#或回车键结束):";
int i=1;
while(i<m_count)
{
m_Instring+=buffer[i];
i++;
}
CClientDC dc(this);
CSize size=dc.GetTextExtent(m_Instring);
SetCaretPos(CPoint(size.cx,0)); //重设光标位置
Invalidate();
}
}
}
CScrollView::OnChar(nChar, nRepCnt, nFlags);
}
void CMy4rdView::OnCaculate()
{
// TODO: Add your command handler code here
if(m_cal==true)
{
node *p;
if(first2==true) //按第一下
{
m_WndDlgBar.GetDlgItem(ID_Caculate)->SetWindowText("计算下一个运算(F8)");
ptree=false;
qe.EnQueue(root);
while(!qe.IsEmpty())
{
p=qe.DelQueue();
if(p->right!=NULL)
qe.EnQueue(p->right);
if(p->left!=NULL)
qe.EnQueue(p->left);
if(p->left!=NULL&&p->right!=NULL)
sl.Push(p);
}
first2=false;
p=sl.GetTop(); //先取栈顶第一个元素出来判断,如果能运算才出栈,不能就不出
if(p->left->code==8&&p->right->code==8) //左右子树都是数字,则可以立即运算
{
switch((int)p->code){
case 1:
p->value=p->left->value+p->right->value;
break;
case 2:
p->value=p->left->value-p->right->value;
break;
case 3:
p->value=p->left->value*p->right->value;
break;
case 4:
if(p->right->value>-0.00001&&p->right->value<0.00001)
{
MessageBox("错误:除法时除数为0!");
isok=false;
m_cal=false;
return;
}
p->value=p->left->value/p->right->value;
break;
case 9:
if(p->right->value>-0.00001&&p->right->value<0.00001)
{
MessageBox("错误:整除时除数为0!");
isok=false;
m_cal=false;
return;
}
if(p->left->value>=p->right->value)
p->value=(int)p->left->value/(int)p->right->value;
else
p->value=0;
break;
case 10:
if(p->right->value>-0.00001&&p->right->value<0.00001)
{
MessageBox("错误:求余时除数为0!");
isok=false;
m_cal=false;
return;
}
p->value=(int)p->left->value%(int)p->right->value;
break;
case 11:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -