📄 form1.cs
字号:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml.Serialization;
using System.IO;
using System.Reflection;
using System.CodeDom.Compiler;
using System.Collections.Specialized;
namespace ProgramCalculator
{
public partial class FormMain : Form
{
private PanelLayoutButtons panelLayoutBtn = new PanelLayoutButtons();
private Button currentRightClickButton = null;//记录最后被右击的按钮
//用于保存表达式,表达式中的一个小单位为一个元素
//比如sin(53+6)的小单位分别为sin, (, 5, 3, +, 6, )
StringCollection cSharpMathExpressCollection = new StringCollection();
public FormMain()
{
InitializeComponent();
}
#region-------------------自定义函数-----------------------
//加载函数面板中的函数按钮
//从文件读取函数列表,
//被成功审核的函数将生成一个对应的按钮在函数面板中
private void LoadFunctionButtions()
{
//添加一个按钮布局面板到窗口
this.panelFunctionButtons.Controls.Add(this.panelLayoutBtn);
this.panelLayoutBtn.Dock = DockStyle.Fill;
//反序列化列表文件
XmlSerializer serializer = new XmlSerializer(typeof(FunctionInfoCollection));
StreamReader sr = new StreamReader(Function.PathOfFunctionsListFile);
FunctionInfoCollection fc = null;
try
{
fc = (FunctionInfoCollection)serializer.Deserialize(sr);
}
catch (Exception ex)
{
MessageBox.Show("在反序列化函数列表时发生错误:\n" + ex);
return;
}
finally
{
sr.Close();
}
foreach (FunctionInfo fi in fc)
{
Function.CollectionOfFunctionInfo.Add(fi);
this.AddFunctionButtonToForm(fi);
}
}
/// <summary>
/// 更新函数dll
/// </summary>
private void UpdateFunctionDll()
{
if(!File.Exists(Function.GetPathOfFunctionDll()))
{
CompilerResults res;
CompilerUnit.BuildFunctionDll(out res);
if(res.Errors.Count != 0)
{
MessageBox.Show("生成函数失败");
}
}
if (File.Exists(Function.GetPathOfNewFunctionDll()))
{
File.Copy(Function.GetPathOfNewFunctionDll(), Function.GetPathOfFunctionDll(), true);
File.Delete(Function.GetPathOfNewFunctionDll());
}
}
/// <summary>
/// 按照FunctionInfo添加函数按钮到窗口
/// </summary>
/// <param name="fi">该按钮关联的FunctionInfo对象</param>
public void AddFunctionButtonToForm(FunctionInfo fi)
{
//添加按钮------------------------
Button functionButton = new Button();
functionButton.Tag = fi;//重要:按钮的tag记录了对应的functionInfo
functionButton.Text = fi.Name;
functionButton.MouseDown += new MouseEventHandler(functionButton_MouseDown);
this.panelLayoutBtn.AddButton(ref functionButton);
}
/// <summary>
/// 设置数学表达式对应的CSharp表达式
/// </summary>
/// <param name="txt">文本</param>
/// <param name="append">追加吗,false则覆盖</param>
private void SetCSharpMathExpress(string txt, bool append)
{
if (!append)
{
this.cSharpMathExpressCollection.Clear();
}
this.cSharpMathExpressCollection.Add(txt);
}
/// <summary>
/// 向输入文本框添加文本
/// </summary>
/// <param name="txt">文本</param>
/// <param name="append">追加吗,false则覆盖</param>
/// <param name="txtColor">文本颜色</param>
private void Input(string txt, bool append, Color txtColor)
{
if (!append)
{
this.richTextBoxInput.Clear();
}
int oldPos = this.richTextBoxInput.SelectionStart;
this.richTextBoxInput.AppendText(txt);
int newPos = this.richTextBoxInput.SelectionStart;
this.richTextBoxInput.SelectionStart = oldPos;
this.richTextBoxInput.SelectionLength = txt.Length;
this.richTextBoxInput.SelectionColor = txtColor;
this.richTextBoxInput.SelectionStart = newPos;
}
/// <summary>
/// 向输出文本框添加文本
/// </summary>
/// <param name="txt">文本</param>
/// <param name="append">追加吗,false则覆盖</param>
/// <param name="txtColor">文本颜色</param>
private void Output(string txt, bool append, Color txtColor)
{
if (!append)
{
this.richTextBoxOutput.Clear();
}
int oldPos = this.richTextBoxOutput.SelectionStart;
this.richTextBoxOutput.AppendText(txt);
int newPos = this.richTextBoxInput.SelectionStart;
this.richTextBoxOutput.SelectionStart = oldPos;
this.richTextBoxOutput.SelectionLength = txt.Length;
this.richTextBoxOutput.SelectionColor = txtColor;
this.richTextBoxOutput.SelectionStart = newPos;
}
#endregion-------------------------------------------------
#region-------------------事件处理函数---------------------
private void FormMain_Load(object sender, EventArgs e)
{
this.LoadFunctionButtions();
this.UpdateFunctionDll();
this.Closing += new CancelEventHandler(FormMain_Closing);
}
void FormMain_Closing(object sender, CancelEventArgs e)
{
}
//函数按钮事件
void functionButton_MouseDown(object sender, MouseEventArgs e)
{
Button bt = (Button)sender;
FunctionInfo fInfo = (FunctionInfo)bt.Tag;
if (e.Button == MouseButtons.Left)
{
this.Input(fInfo.Name, true, Color.Green);//添加到输入文本框
this.SetCSharpMathExpress(Function.FunctionClassName + "." + fInfo.Name, true);//添加到cSharp表达式
//利用反射取得函数原型,并添加到输出文本框
string dll = Function.GetPathOfFunctionDll();
if (File.Exists(dll))
{
try
{
Assembly ass = Assembly.LoadFile(dll);
Type t = ass.GetType("FunctionNameSpace.FunctionClass");
MethodInfo mi = t.GetMethod(fInfo.Name);
this.Output(mi.ToString(), false, Color.Green);
}
catch { }
}
//显示提示信息
this.Output(Environment.NewLine + fInfo.ExplainInfo, true, Color.Green);
}
else if (e.Button == MouseButtons.Right)
{
this.currentRightClickButton = (Button)sender;
this.contextMenuStripOfFunctionButton.Show(bt, e.Location);
}
}
//上下文菜单: 编辑此函数
private void ToolStripMenuItemEditFunction_Click(object sender, EventArgs e)
{
if (this.currentRightClickButton != null)
{
FunctionInfo fInfo = this.currentRightClickButton.Tag as FunctionInfo;
if (fInfo != null)
{
FormFunctionCoding fc = new FormFunctionCoding(fInfo, false);
fc.ShowDialog(this);
}
}
}
//上下文菜单: 删除此函数
private void ToolStripMenuItemDeleteFunction_Click(object sender, EventArgs e)
{
if (this.currentRightClickButton != null)
{
FunctionInfo fInfo = this.currentRightClickButton.Tag as FunctionInfo;
if (fInfo != null)
{
string warning = "注意! 此操作将删除函数: " + fInfo.Name + "\n" +
"及其关联的代码文件: " + Function.DirectoryOfFunctions + fInfo.RelativePathOfCodeFile + "\n" +
"确实要删除吗?";
if (MessageBox.Show(warning, "删除函数", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2)
!= DialogResult.OK)
{
return;
}
//删除
try
{
Function.CollectionOfFunctionInfo.Remove(fInfo);
File.Delete(Function.DirectoryOfFunctions + fInfo.RelativePathOfCodeFile);
}
catch { }
//保存
Function.SaveFunctionsToList();
//重新绘制函数按钮
this.panelLayoutBtn.Controls.Clear();
for (int i = 0; i < Function.CollectionOfFunctionInfo.Count; i++ )
{
FunctionInfo fi = Function.CollectionOfFunctionInfo[i];
this.AddFunctionButtonToForm(fi);
}
}
}
}
//添加函数
private void buttonAddFunction_Click(object sender, EventArgs e)
{
FormAddFunctionGuide frmGuide = new FormAddFunctionGuide();
if (frmGuide.ShowDialog(this) != DialogResult.OK)
{
return;
}
string functionName = frmGuide.FunctionName;
string pathOfCodeFile = Function.GetRelativePathOfFunctionCodeFile(functionName);
string info = frmGuide.ExplainInfo;
FunctionInfo fInfo = new FunctionInfo(functionName, pathOfCodeFile,info);
FormFunctionCoding frmCode = new FormFunctionCoding(fInfo,true);
frmCode.ShowDialog(this);
}
//数字按钮事件处理
private void digitalButtonDown(object sender, MouseEventArgs e)
{
Button bt = (Button)sender;
if (e.Button == MouseButtons.Left)
{
this.Input(bt.Text,true,Color.Blue);
this.SetCSharpMathExpress(bt.Text, true);
}
}
//操作符按钮事件处理
private void operatorButtonDown(object sender, MouseEventArgs e)
{
Button bt = (Button)sender;
if (e.Button == MouseButtons.Left)
{
this.Input(" "+bt.Text+" ", true, Color.Red);
this.SetCSharpMathExpress(" " +bt.Text+" ", true);
}
}
//等于
private void buttonIs_Click(object sender, EventArgs e)
{
//表达式
string express = "";
foreach (string s in this.cSharpMathExpressCollection)
{
express += s;
}
string source = TranslateUnit.TranslateToCSharp(express);
//这里加载了函数dll
string[] dlls = new string[1];
dlls[0] = Function.GetPathOfFunctionDll();
CompilerResults results = CompilerUnit.Compile(source, false,true, dlls,null);
//重要:利用反射获取计算结果
if (results.Errors.Count == 0)
{
Assembly ass = results.CompiledAssembly;
Type tp = ass.GetType("ComputeUnit.Compute");//ass.GetType("MyNamespace.MyClass");
// 获取方法
MethodInfo mi = tp.GetMethod("GetResult");//tp.GetMethod("MyMethodl");
// 创建实例
Object obj = System.Activator.CreateInstance(tp);
//执行方法
try
{
object res = mi.Invoke(obj, null);
this.Output(res.ToString(), false, Color.Blue);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
else
{
string errMsg = "表达式错误:" + Environment.NewLine;
foreach(CompilerError err in results.Errors)
{
errMsg += err.ErrorText + Environment.NewLine;
}
this.Output(errMsg, false, Color.Red);
}
}
//BackSpace
private void buttonBackspace_Click(object sender, EventArgs e)
{
//undo输入框中最近操作
//这里的richTextBoxInput.Undo次数取决于Input()函数中对richTextInput的操作次数
this.richTextBoxInput.Undo();
this.richTextBoxInput.Undo();
//移出表达式中最近加入的元素
if (this.cSharpMathExpressCollection.Count > 0)
{
this.cSharpMathExpressCollection.RemoveAt(this.cSharpMathExpressCollection.Count - 1);
}
}
//清除
private void buttonClear_Click(object sender, EventArgs e)
{
this.Input("", false, Color.Black);
this.Output("", false, Color.Black);
this.SetCSharpMathExpress("", false);
}
private void buttonPI_Click(object sender, EventArgs e)
{
this.Input(" " + Math.PI + "", true, Color.Blue);
this.SetCSharpMathExpress(" " + Math.PI + " ", true);
}
private void buttonE_Click(object sender, EventArgs e)
{
this.Input(" E ", true, Color.Purple);
this.SetCSharpMathExpress("E", true);
}
private void labelAbout_Click(object sender, EventArgs e)
{
FormAbout fa = new FormAbout();
fa.ShowDialog(this);
}
#endregion-------------------------------------------------
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -