www.pudn.com > 4rd.rar > 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(iSetWindowText("计算下一个运算(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: 
				case 12: 
				case 13: 
				case 14: 
					MessageBox("error!\n表达式输入有错,=+,-=,*=,/=前面只能为变量,不能为常量!"); 
					m_cal=false; 
					return; 
				} 
				p->code=8; 
				q.Delete(p->left); 
				q.Delete(p->right); 
				p->left=NULL; 
				p->right=NULL; 
				sl.Pop();		//弹出栈顶元素 
				Invalidate(); 
				if(sl.IsEmpty())	//运算完毕 
				{ 
					m_result=true; 
					Invalidate(); 
					m_cal=false; 
					MessageBox("完毕!","编译原理"); 
				} 
				return; 
			}//if 
			else 
				if(p->left->code==7||p->right->code==7) 
				{ 
					if(p->left->code==7&&table[p->left->entry].evaluated==false) 
					{ 
						CIn dlg; 
						string="请输入标识符"+(CString)table[p->left->entry].name+"的值"; 
						if(dlg.DoModal()==IDOK) 
						{ 
							table[p->left->entry].value=dlg.m_var; 
							table[p->left->entry].evaluated=true; 
						} 
						m_id=true;	//显示标识符的值 
						Invalidate(); 
					}//if 
					else 
						if(p->right->code==7&&table[p->right->entry].evaluated==false) 
						{ 
							CIn dlg; 
							string="请输入标识符"+(CString)table[p->right->entry].name+"的值"; 
							if(dlg.DoModal()==IDOK) 
							{ 
								table[p->right->entry].value=dlg.m_var; 
								table[p->right->entry].evaluated=true; 
							} 
 
							m_id=true;	//显示标识符的值 
							Invalidate(); 
						}//if 
				}//if 
		}//if first2==true 
		else	//按了第一下以后 
		{ 
			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: 
				case 12: 
				case 13: 
				case 14: 
					MessageBox("error!\n表达式输入有错,=+,-=,*=,/=前面只能为变量,不能为常量!"); 
					m_cal=false; 
					return; 
				} 
				p->code=8; 
				q.Delete(p->left); 
				q.Delete(p->right); 
				p->left=NULL; 
				p->right=NULL; 
				sl.Pop();		//弹出栈顶元素 
				Invalidate(); 
				if(sl.IsEmpty()) 
				{ 
					m_result=true; 
					Invalidate(); 
					m_cal=false; 
					MessageBox("完毕!","编译原理"); 
				}	 
			} 
			else 
				if(p->left->code==7||p->right->code==7)		//左或右孩子有标识符 
				{ 
					if(p->left->code==7&&table[p->left->entry].evaluated==false)//左标识符未赋值 
					{ 
						CIn dlg; 
						string="请输入标识符"+(CString)table[p->left->entry].name+"的值"; 
						if(dlg.DoModal()==IDOK) 
						{ 
							table[p->left->entry].value=dlg.m_var; 
							table[p->left->entry].evaluated=true; 
						} 
						m_id=true; 
						Invalidate(); 
					}//if 
					else 
						if(p->right->code==7&&table[p->right->entry].evaluated==false)//右标识符未赋值 
						{ 
							CIn dlg; 
							string="请输入标识符"+(CString)table[p->right->entry].name+"的值"; 
							if(dlg.DoModal()==IDOK) 
							{ 
								table[p->right->entry].value=dlg.m_var; 
								table[p->right->entry].evaluated=true; 
							} 
							m_id=true; 
							Invalidate(); 
						}//if 
						else 
						{ 
							double a,b; 
							if(p->left->code==7) 
								a=table[p->left->entry].value; 
							else 
								a=p->left->value; 
							if(p->right->code==7) 
								b=table[p->right->entry].value; 
							else 
								b=p->right->value; 
							switch((int)p->code){ 
							case 1: 
								p->value=a+b; 
								p->code=8; 
								break; 
							case 2: 
								p->value=a-b; 
								p->code=8; 
								break; 
							case 3: 
								p->value=a*b; 
								p->code=8; 
								break; 
							case 4: 
								if(b>-0.00001&&b<0.00001) 
								{ 
									MessageBox("错误:除法是除数为0!"); 
									isok=false; 
									m_cal=false; 
									return; 
								} 
								p->value=a/b; 
								p->code=8; 
								break; 
							case 9: 
								if(b>-0.00001&&b<0.00001) 
								{ 
									MessageBox("错误:整除时除数为0!","编译原理"); 
									isok=false; 
									m_cal=false; 
									return; 
								} 
								if(a>=b) 
									p->value=(int)a/(int)b; 
								else 
									p->value=0; 
								p->code=8; 
								break; 
							case 10: 
								if(b>-0.00001&&b<0.00001) 
								{ 
									MessageBox("错误:求余时除数为0!","编译原理"); 
									isok=false; 
									m_cal=false; 
									return; 
								} 
								p->value=(int)a%(int)b; 
								p->code=8; 
								break; 
							case 11: 
								if(p->left->code!=7) 
								{ 
									MessageBox("error!\n表达式输入有错,=+前面只能为变量,不能为常量!","编译原理"); 
									m_cal=false; 
									return; 
								} 
								p->value=a+b; 
								table[p->left->entry].value=p->value; 
								p->code=7; 
								p->entry=p->left->entry; 
								table[p->entry].evaluated=true; 
								break; 
							case 12: 
								if(p->left->code!=7) 
								{ 
									MessageBox("error!\n表达式输入有错,-=前面只能为变量,不能为常量!","编译原理"); 
									m_cal=false; 
									return; 
								} 
								p->value=a-b; 
								table[p->left->entry].value=p->value; 
								p->code=7; 
								p->entry=p->left->entry; 
								table[p->entry].evaluated=true; 
								break; 
							case 13: 
								if(p->left->code!=7) 
								{ 
									MessageBox("error!\n表达式输入有错,*=前面只能为变量,不能为常量!","编译原理"); 
									m_cal=false; 
									return; 
								} 
								p->value=a*b; 
								table[p->left->entry].value=p->value; 
								p->code=7; 
								p->entry=p->left->entry; 
								table[p->entry].evaluated=true; 
								break; 
							case 14: 
								if(p->left->code!=7) 
								{ 
									MessageBox("error!\n表达式输入有错,/=前面只能为变量,不能为常量!","编译原理"); 
									m_cal=false; 
									return; 
								} 
								p->value=a/b; 
								table[p->left->entry].value=p->value; 
								p->code=7; 
								p->entry=p->left->entry; 
								table[p->entry].evaluated=true; 
								break; 
							}//switch 
							q.Delete(p->left); 
							q.Delete(p->right); 
							p->left=NULL; 
							p->right=NULL; 
							node *result; 
							result=sl.Pop();		//弹出栈顶元素 
							Invalidate(); 
							if(sl.IsEmpty()) 
							{ 
								m_WndDlgBar.GetDlgItem(ID_Caculate)->SetWindowText("开始进行计算(F8)"); 
								m_result=true; 
								Invalidate(); 
								m_cal=false; 
								MessageBox("完毕!","编译原理"); 
							} 
						}//else 
				}//if 
		}//else 
	}//if m_cal==true 
	else 
		MessageBox("请先生成语法树!","编译原理"); 
} 
 
 
void CMy4rdView::PTree(CDC *pDC)		//画图单步输出语法树 
{ 
	listnode *p; 
	node *temp; 
	CString str; 
	p=q.front->next; 
	m_num=0; 
	while(p!=NULL) 
	{ 
		temp=p->data; 
		switch((int)temp->code){ 
		case 1: 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,"+"); 
			if(temp->left!=NULL&&temp->right!=NULL) 
			{ 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->left->No]->x+5,Pos[temp->left->No]->y); 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->right->No]->x+5,Pos[temp->right->No]->y); 
			} 
			break; 
		case 2: 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,"-"); 
			if(temp->left!=NULL&&temp->right!=NULL) 
			{ 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->left->No]->x+5,Pos[temp->left->No]->y); 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->right->No]->x+5,Pos[temp->right->No]->y); 
			} 
			break; 
		case 3: 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,"*"); 
			if(temp->left!=NULL&&temp->right!=NULL) 
			{ 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->left->No]->x+5,Pos[temp->left->No]->y); 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->right->No]->x+5,Pos[temp->right->No]->y); 
			} 
			break; 
		case 4: 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,"/"); 
			if(temp->left!=NULL&&temp->right!=NULL) 
			{ 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->left->No]->x+5,Pos[temp->left->No]->y); 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->right->No]->x+5,Pos[temp->right->No]->y); 
			} 
			break; 
		case 7: 
			pDC->SetTextColor(RGB(0,0,255)); 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,CString(table[temp->entry].name)); 
			pDC->SetTextColor(RGB(0,0,0)); 
			break; 
		case 8: 
			str.Format("%.2f",temp->value); 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,str); 
			break; 
		case 9: 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,"DIV"); 
			if(temp->left!=NULL&&temp->right!=NULL) 
			{ 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->left->No]->x+5,Pos[temp->left->No]->y); 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->right->No]->x+5,Pos[temp->right->No]->y); 
			} 
			break; 
		case 10: 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,"MOD"); 
			if(temp->left!=NULL&&temp->right!=NULL) 
			{ 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->left->No]->x+5,Pos[temp->left->No]->y); 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->right->No]->x+5,Pos[temp->right->No]->y); 
			} 
			break; 
		case 11: 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,"+="); 
			if(temp->left!=NULL&&temp->right!=NULL) 
			{ 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->left->No]->x+5,Pos[temp->left->No]->y); 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->right->No]->x+5,Pos[temp->right->No]->y); 
			} 
			break; 
		case 12: 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,"-="); 
			if(temp->left!=NULL&&temp->right!=NULL) 
			{ 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->left->No]->x+5,Pos[temp->left->No]->y); 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->right->No]->x+5,Pos[temp->right->No]->y); 
			} 
			break; 
		case 13: 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,"*="); 
			if(temp->left!=NULL&&temp->right!=NULL) 
			{ 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->left->No]->x+5,Pos[temp->left->No]->y); 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->right->No]->x+5,Pos[temp->right->No]->y); 
			} 
			break; 
		case 14: 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,"/="); 
			if(temp->left!=NULL&&temp->right!=NULL) 
			{ 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->left->No]->x+5,Pos[temp->left->No]->y); 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->right->No]->x+5,Pos[temp->right->No]->y); 
			} 
			break; 
		} 
		m_num++; 
		if(m_num>=number) 
			break; 
		p=p->next; 
	} 
} 
 
void CMy4rdView::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	move=true; 
	m_point=point; 
//	::SetCursor(AfxGetApp()->LoadCursor(IDC_HND)); 
 
	CScrollView::OnLButtonDown(nFlags, point); 
} 
 
void CMy4rdView::OnLButtonUp(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	move=false; 
 
	CScrollView::OnLButtonUp(nFlags, point); 
} 
 
void CMy4rdView::OnMouseMove(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	for(int i=0;i<100;i++) 
	{ 
		if(Pos[i]!=NULL) 
			break; 
	} 
	if(i>=100) 
		return; 
	if(move==true) 
	{ 
		m_x=m_x+point.x-m_point.x; 
		m_y=m_y+point.y-m_point.y; 
		m_point=point; 
		/////要重新计算所有结点的坐标////////////////////////////// 
		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); 
		//////////////////////////////////////////////////////////// 
		Invalidate(); 
	} 
 
	CScrollView::OnMouseMove(nFlags, point); 
} 
 
void CMy4rdView::Caculate(CDC *pDC)		//单步计算输出 
{ 
	listnode *p; 
	node *temp; 
	CString str; 
	p=q.front->next; 
	while(p!=NULL) 
	{ 
		temp=p->data; 
		switch((int)temp->code){ 
		case 1: 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,"+"); 
			if(temp->left!=NULL&&temp->right!=NULL) 
			{ 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->left->No]->x+5,Pos[temp->left->No]->y); 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->right->No]->x+5,Pos[temp->right->No]->y); 
			} 
			break; 
		case 2: 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,"-"); 
			if(temp->left!=NULL&&temp->right!=NULL) 
			{ 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->left->No]->x+5,Pos[temp->left->No]->y); 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->right->No]->x+5,Pos[temp->right->No]->y); 
			} 
			break; 
		case 3: 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,"*"); 
			if(temp->left!=NULL&&temp->right!=NULL) 
			{ 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->left->No]->x+5,Pos[temp->left->No]->y); 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->right->No]->x+5,Pos[temp->right->No]->y); 
			} 
			break; 
		case 4: 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,"/"); 
			if(temp->left!=NULL&&temp->right!=NULL) 
			{ 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->left->No]->x+5,Pos[temp->left->No]->y); 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->right->No]->x+5,Pos[temp->right->No]->y); 
			} 
			break; 
		case 7: 
			if(table[temp->entry].evaluated==true) 
			{ 
				pDC->SetTextColor(RGB(255,0,0)); 
				CString str; 
				str.Format("=%.2f",table[temp->entry].value); 
				pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,table[temp->entry].name+str); 
				pDC->SetTextColor(RGB(0,0,0)); 
			} 
			else 
			{ 
				pDC->SetTextColor(RGB(0,0,255)); 
				pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,CString(table[temp->entry].name)); 
				pDC->SetTextColor(RGB(0,0,0)); 
			} 
			break; 
		case 8: 
			str.Format("%.2f",temp->value); 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,str); 
			break; 
		case 9: 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,"DIV"); 
			if(temp->left!=NULL&&temp->right!=NULL) 
			{ 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->left->No]->x+5,Pos[temp->left->No]->y); 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->right->No]->x+5,Pos[temp->right->No]->y); 
			} 
			break; 
		case 10: 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,"MOD"); 
			if(temp->left!=NULL&&temp->right!=NULL) 
			{ 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->left->No]->x+5,Pos[temp->left->No]->y); 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->right->No]->x+5,Pos[temp->right->No]->y); 
			} 
			break; 
		case 11: 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,"+="); 
			if(temp->left!=NULL&&temp->right!=NULL) 
			{ 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->left->No]->x+5,Pos[temp->left->No]->y); 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->right->No]->x+5,Pos[temp->right->No]->y); 
			} 
			break; 
		case 12: 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,"-="); 
			if(temp->left!=NULL&&temp->right!=NULL) 
			{ 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->left->No]->x+5,Pos[temp->left->No]->y); 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->right->No]->x+5,Pos[temp->right->No]->y); 
			} 
			break; 
		case 13: 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,"*="); 
			if(temp->left!=NULL&&temp->right!=NULL) 
			{ 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->left->No]->x+5,Pos[temp->left->No]->y); 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->right->No]->x+5,Pos[temp->right->No]->y); 
			} 
			break; 
		case 14: 
			pDC->TextOut(Pos[temp->No]->x,Pos[temp->No]->y,"/="); 
			if(temp->left!=NULL&&temp->right!=NULL) 
			{ 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->left->No]->x+5,Pos[temp->left->No]->y); 
				pDC->MoveTo(Pos[temp->No]->x+3,Pos[temp->No]->y+15); 
				pDC->LineTo(Pos[temp->right->No]->x+5,Pos[temp->right->No]->y); 
			} 
			break; 
		} 
		p=p->next; 
	} 
} 
 
void CMy4rdView::initial()	//初始化各个参数 
{ 
	input=true; 
	m_count=1; 
	m_tree=false; 
	m_cal=false; 
	ptree=false; 
	m_x=400; 
	m_y=50; 
	m_inVar=false; 
	move=false; 
	first=false; 
	out_cal=false; 
	m_id=false; 
	isok=true; 
	ptree=false; 
	q.Clear(); 
	qe.Clear(); 
	sl.Clear(); 
	m_result=false; 
	for(int i=0;i<100;i++) 
		Pos[i]=NULL; 
	f_error=true; 
} 
 
void CMy4rdView::OnExample1()	//测试例子1 
{ 
	// TODO: Add your command handler code here 
	initial(); 
	m_Instring="测试例子 1:  0.85*first+(1-first)/second"; 
	m_tree=true; 
	first=true; 
	m_input=false; 
	HideCaret(); 
	Invalidate(); 
	buffer[1]='0'; 
	buffer[2]='.'; 
	buffer[3]='8'; 
	buffer[4]='5'; 
	buffer[5]='*'; 
	buffer[6]='f'; 
	buffer[7]='i'; 
	buffer[8]='r'; 
	buffer[9]='s'; 
	buffer[10]='t'; 
	buffer[11]='+'; 
	buffer[12]='('; 
	buffer[13]='1'; 
	buffer[14]='-'; 
	buffer[15]='f'; 
	buffer[16]='i'; 
	buffer[17]='r'; 
	buffer[18]='s'; 
	buffer[19]='t'; 
	buffer[20]=')'; 
	buffer[21]='/'; 
	buffer[22]='s'; 
	buffer[23]='e'; 
	buffer[24]='c'; 
	buffer[25]='o'; 
	buffer[26]='n'; 
	buffer[27]='d'; 
	buffer[28]='#'; 
} 
 
void CMy4rdView::OnExample2()	//测试例子2 
{ 
	// TODO: Add your command handler code here2*3+4*5 
	initial(); 
	m_Instring="测试例子 2:  2*3+4*5"; 
	m_tree=true; 
	first=true; 
	m_input=false; 
	HideCaret(); 
	Invalidate(); 
	buffer[1]='2'; 
	buffer[2]='*'; 
	buffer[3]='3'; 
	buffer[4]='+'; 
	buffer[5]='4'; 
	buffer[6]='*'; 
	buffer[7]='5'; 
	buffer[8]='#'; 
} 
 
void CMy4rdView::OnExample3()  
{ 
	// TODO: Add your command handler code herea+(b+3)/2*3-4 
	initial(); 
	m_Instring="测试例子 3:  a+(b+3)/2*3-4"; 
	m_tree=true; 
	first=true; 
	m_input=false; 
	HideCaret(); 
	Invalidate(); 
	buffer[1]='a'; 
	buffer[2]='+'; 
	buffer[3]='('; 
	buffer[4]='b'; 
	buffer[5]='+'; 
	buffer[6]='3'; 
	buffer[7]=')'; 
	buffer[8]='/'; 
	buffer[9]='2'; 
	buffer[10]='*'; 
	buffer[11]='3'; 
	buffer[12]='-'; 
	buffer[13]='4'; 
	buffer[14]='#'; 
} 
 
void CMy4rdView::OnExample4()  
{ 
	// TODO: Add your command handler code here 
	initial(); 
	m_Instring="测试例子 4:  2+(first+=5)/3*5-second"; 
	m_tree=true; 
	first=true; 
	m_input=false; 
	HideCaret(); 
	Invalidate(); 
	buffer[1]='2'; 
	buffer[2]='+'; 
	buffer[3]='('; 
	buffer[4]='f'; 
	buffer[5]='i'; 
	buffer[6]='r'; 
	buffer[7]='s'; 
	buffer[8]='t'; 
	buffer[9]='+'; 
	buffer[10]='='; 
	buffer[11]='5'; 
	buffer[12]=')'; 
	buffer[13]='/'; 
	buffer[14]='3'; 
	buffer[15]='*'; 
	buffer[16]='5'; 
	buffer[17]='-'; 
	buffer[18]='s'; 
	buffer[19]='e'; 
	buffer[20]='c'; 
	buffer[21]='o'; 
	buffer[22]='n'; 
	buffer[23]='d'; 
	buffer[24]='#'; 
} 
 
void CMy4rdView::OnExample5()  
{ 
	// TODO: Add your command handler code here 
	initial(); 
	m_Instring="测试例子 5:  first DIV second MOD third"; 
	m_tree=true; 
	first=true; 
	m_input=false; 
	HideCaret(); 
	Invalidate(); 
	buffer[1]='f'; 
	buffer[2]='i'; 
	buffer[3]='r'; 
	buffer[4]='s'; 
	buffer[5]='t'; 
	buffer[6]=' '; 
	buffer[7]='D'; 
	buffer[8]='I'; 
	buffer[9]='V'; 
	buffer[10]=' '; 
	buffer[11]='s'; 
	buffer[12]='e'; 
	buffer[13]='c'; 
	buffer[14]='o'; 
	buffer[15]='n'; 
	buffer[16]='d'; 
	buffer[17]=' '; 
	buffer[18]='M'; 
	buffer[19]='O'; 
	buffer[20]='D'; 
	buffer[21]=' '; 
	buffer[22]='t'; 
	buffer[23]='h'; 
	buffer[24]='i'; 
	buffer[25]='r'; 
	buffer[26]='d'; 
	buffer[27]='#'; 
} 
 
void CMy4rdView::OnExample6()  
{ 
	// TODO: Add your command handler code here 
	initial(); 
	m_Instring="测试例子 6:  1+2-3*4/5+a-b*c/d"; 
	m_tree=true; 
	first=true; 
	m_input=false; 
	HideCaret(); 
	Invalidate(); 
	buffer[1]='1'; 
	buffer[2]='+'; 
	buffer[3]='2'; 
	buffer[4]='-'; 
	buffer[5]='3'; 
	buffer[6]='*'; 
	buffer[7]='4'; 
	buffer[8]='/'; 
	buffer[9]='5'; 
	buffer[10]='+'; 
	buffer[11]='a'; 
	buffer[12]='-'; 
	buffer[13]='b'; 
	buffer[14]='*'; 
	buffer[15]='c'; 
	buffer[16]='/'; 
	buffer[17]='d'; 
	buffer[18]='#'; 
}