⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unit1.pas

📁 用delphi编写的小程序
💻 PAS
📖 第 1 页 / 共 3 页
字号:
Unit Unit1;

Interface

Uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, StdCtrls, ComCtrls, OleCtnrs, ExtCtrls, Buttons;

Type

   TFormMain = Class(TForm)
      TabSheet1 : TTabSheet;
      Label7 : TLabel;
      EditFormula : TRichEdit;
      BtnDeleteAll1 : TButton;
      TabSheet2 : TTabSheet;
      Label1 : TLabel;
      Label2 : TLabel;
      Label3 : TLabel;
      Label4 : TLabel;
      Label5 : TLabel;
      NongDuA : TEdit;
      MassA : TEdit;
      NongDuB : TEdit;
      NongDuMixed : TEdit;
      MassMixed : TEdit;
      Memo1 : TMemo;
      BtnCalc : TButton;
      MassB : TEdit;
      BtnDeleteAll2 : TButton;
      TabSheet3 : TTabSheet;
      Label11 : TLabel;
      Button2 : TButton;
      PageControl : TPageControl;
      Label14 : TLabel;
      TabSheet4 : TTabSheet;
      Memo6 : TMemo;
      Panel1 : TPanel;
      EditReactor : TRichEdit;
      Memo2 : TMemo;
      Memo3 : TMemo;
      AddToReactor : TButton;
      DeleteIt1 : TButton;
      Panel2 : TPanel;
      EditOut : TRichEdit;
      Memo4 : TMemo;
      Memo5 : TMemo;
      Label9 : TLabel;
      Label6 : TLabel;
      Label10 : TLabel;
      BtnBalance : TButton;
      Label8 : TLabel;
      Label12 : TLabel;
      Label13 : TLabel;
      AddToOut : TButton;
      DeleteIt2 : TButton;
      BtnDelete : TButton;
      Procedure FormCreate(Sender : TObject);
      Procedure BtnDeleteAll2Click(Sender : TObject);
      Procedure BtnDeleteAll1Click(Sender : TObject);
      Procedure BtnDeleteClick(Sender : TObject);
      Procedure DeleteIt1Click(Sender : TObject);
      Procedure AddToReactorClick(Sender : TObject);
      Procedure EditFormulaKeyDown(Sender : TObject; Var Key : Word;
         Shift : TShiftState);
      Procedure TabSheet1Show(Sender : TObject);
      Procedure EditFormulaKeyPress(Sender : TObject; Var Key : Char);
      Procedure EditFormulaChange(Sender : TObject);
      Procedure Button2Click(Sender : TObject);
      Procedure BtnCalcClick(Sender : TObject);
      Procedure BtnBalanceClick(Sender : TObject);
   private
      EditFormulaShiftPress : Boolean; //记录化学式输入框是否接收到Shift
      EditFormulaWordKey : Byte; //记录化学式输入框接收到的键值
   public
      Procedure NumberOnlyEditKeyDown(Sender : TObject; Var Key : Word; Shift : TShiftState); //溶液信息编辑框只可接收数字的实现
      Procedure NumberOnlyEditEnter(Sender : TObject);
   End;

   TSolution = Record //溶液的信息
      NongDu : Single; //溶液的浓度
      Mass : Single; //溶液的体积
   End;

   IntArray = Array Of Integer; //整数组
   SingleArray = Array Of Single; //小数组

   TReactorOrOutPut = Record //反应物或生成物信息类
      IsReactor : Boolean; //是否是反应物
      Str : String; //反应物或生成物的化学式
      Mass : Single;
      EachElementCou : IntArray; //每个化学式中的每个元素的数目
      Num : Integer; //配平结果
   End;

   TEquation = Record //一元一次方程类
      Nums : IntArray; //未知数的系数
      Constant : Integer; //常数
   End;
   TEqArr = Array Of TEquation;

   TFraction = Record //模拟分数的一个类   Fraction:分数
      Numerator : Integer; //分子
      Denominator : Integer; //分母
   End;
   TResultArr = Array Of TFraction; //分数组

   TBalancer = Class
   private
      Procedure RebuildReactors; //重构各反应物与生成物,获取每种元素出现次数
      Procedure GetElementTypes; //获取所用到的各种元素
      Procedure PrepareEquations; //准备方程组
      Procedure GetNums; //通过解方程获得各反应物或生成物的系数

      ///////分数处理函数////////////////////
      Function Fraction_CreateOne(Numerator, Denominator : Integer) : TFraction; //生成一个分数
      Function Fraction_MinMultiple(Num1, Num2 : Integer) : Integer; //获得两数的最小公倍数;Multiple:倍数
      Function Fraction_MaxDivisor(Num1, Num2 : Integer) : Integer; //获得两数的最大公约数
      Function Fraction_Minus(Num1, Num2 : TFraction) : TFraction; //两分数相减,Num1-Num2
      Function Fraction_Multiplination(Num1, Num2 : TFraction) : TFraction; //两分数相乘
      Function Fraction_Division(Num1, Num2 : TFraction) : TFraction; //两分数相除,Num1/Num2
      Procedure Fraction_Simplify(Var Num : TFraction); //对分数进行化简
   public
      Elements : TStringList; //记载所有用到的元素
      Actors : Array Of TReactorOrOutPut; //反应物与生成物
      ReactorsCou, OutPutCou : Integer; //分别记载反应物与生成物的数目
      AllCou : Integer; //记载反应物与生成物的总数目
      Equations : TEqArr; //方程
      Procedure Work; //进行配平
      Procedure MyInitialization; //进行初始化
   End;

Var
   FormMain : TFormMain;
   SolutionEdits : Array[1..6] Of TEdit;
Const
   ErrInfo : String = '发生错误!';

   //一些字符集
   Alpha : Set Of Char = ['a'..'z', 'A'..'Z'];
   LowAlpha : Set Of Char = ['a'..'z'];
   HighAlpha : Set Of Char = ['A'..'Z'];
   NumberSet : Set Of Char = ['0'..'9', '.'];
   Optor : Set Of Char = ['*', '/'];

Var
   Elements : TStringList; //元素的名称列表
   MOfElements : Array[1..88] Of Single; //元素的相对原子质量

   AllElements : TStringList; // 为GetMassOfElement函数准备,被RebuildReactors调用时进行元素出现次数的统计
   ReactorOrOutPut : ^TReactorOrOutPut;


Function GetMassOfElement(ElementName : String) : Single; //获取元素的相对原子质量; Mass:n.质量 ; Element:元素
Function GetMassOfFormula(Exp : String; WorkState : Byte = 1) : String; //计算任意化学式的式量,被RebuildReactors调用时进行元素出现次数的统计; Formula:式子
Function GetEquationResult(Equation : String) : Single; //包涵 +-*/()的一元一次方程求解器,未知数只能为一个字母
Procedure Simplify(Exp : String; Unknown : Char; Var Num1, Num2 : Single); //对所给的一元一次式子进行化简,将未知数系数存入Num1,将化简的常数存入Num2; Simplify:v.化简

Implementation
{$R *.dfm}

Procedure TFormMain.NumberOnlyEditKeyDown(Sender : TObject; Var Key : Word;
   Shift : TShiftState);
Begin //溶液信息编辑框只可接收数字的实现
   If Key In [48..57, 46, 13, 8, 189, 190] Then
      TEdit(Sender).ReadOnly := False
   Else
      TEdit(Sender).ReadOnly := true;
End;

Procedure TFormMain.NumberOnlyEditEnter(Sender : TObject);
Begin
   TEdit(Sender).ReadOnly := False;
End;

Procedure TFormMain.FormCreate(Sender : TObject);
Var
   i : Integer;
Begin
   EditFormulaShiftPress := False;

   SolutionEdits[1] := NongDuA;
   SolutionEdits[2] := NongDuB;
   SolutionEdits[3] := NongDuMixed;
   SolutionEdits[4] := MassA;
   SolutionEdits[5] := MassB;
   SolutionEdits[6] := MassMixed;

   //设置溶液信息编辑框只可接收数字
   For i := 1 To 6 Do
      With SolutionEdits[i] Do Begin
         OnKeyDown := NumberOnlyEditKeyDown;
         OnEnter := NumberOnlyEditEnter;
      End;

   //化学式输入框只可输入大小写字母、数字、()
   EditFormula.OnEnter := NumberOnlyEditEnter;
End;

Procedure TFormMain.BtnDeleteAll2Click(Sender : TObject);
Begin //全部清空溶液混合计算中的输入框
   NongDuA.Text := '';
   MassA.Text := '';
   NongDuB.Text := '';
   MassB.Text := '';
   NongDuMixed.Text := '';
   MassMixed.Text := '';
End;

Procedure TFormMain.BtnDeleteAll1Click(Sender : TObject);
Begin //全部清空方程式配平中的输入框
   EditFormula.Lines.Clear;
   EditReactor.Lines.Clear;
   EditOut.Lines.Clear;
   EditReactor.Clear;
   Memo2.Clear;
   Memo3.Clear;
   Memo4.Clear;
   Memo5.Clear;
   BtnBalance.Enabled := true;
   AddToReactor.Enabled := true;
   DeleteIt1.Enabled := true;
   AddToOut.Enabled := true;
   DeleteIt2.Enabled := true;
End;

Procedure TFormMain.BtnDeleteClick(Sender : TObject);
Begin
   EditFormula.Lines.Clear; //清空化学式输入框
End;

Procedure TFormMain.DeleteIt1Click(Sender : TObject);
Var
   Edit : TRichEdit;
   i : Integer;
Begin
   Case (Sender As TComponent).tag Of //哪个Edit获得焦点
      1 : Edit := EditReactor;
      2 : Edit := EditOut;
   End;
   i := SendMessage(Edit.Handle, $0400 + 54, 0, Edit.SelStart); //用WinAPI函数获取行号
   Edit.Lines.Delete(i); //删除所选行
End;

Procedure TFormMain.AddToReactorClick(Sender : TObject);
Var
   Edit : TRichEdit;
Begin //拷贝化学式到反应物或生成物输入框
   If EditFormula.Text = '' Then Exit;
   EditFormula.SelectAll; //全选
   EditFormula.CopyToClipboard; //拷入剪切板
   Case (Sender As TComponent).tag Of //哪个Edit获得焦点
      1 : Edit := EditReactor;
      2 : Edit := EditOut;
   End;
   Edit.ReadOnly := False; //必需设为可写入才可粘贴
   Edit.PasteFromClipboard; //粘贴自剪切板
   Edit.ReadOnly := true;
End;

Procedure TFormMain.EditFormulaKeyPress(Sender : TObject; Var Key : Char);
Begin
   EditFormulaWordKey := Integer(Key); //存储按下了哪个字母
End;

Procedure TFormMain.EditFormulaChange(Sender : TObject);
Begin
   Label14.Caption := 'M=?';

   If (EditFormulaShiftPress = False) And (EditFormulaWordKey In [48..57]) Then Begin //如果输入数字
      EditFormula.SelStart := EditFormula.SelStart - 1;
      EditFormula.SelLength := 1;
      EditFormula.SelAttributes.Size := 9;
      EditFormula.SelLength := 0;
      EditFormula.SelStart := EditFormula.SelStart + 1;
      //变数字为小字体,更好看一些
   End;
   EditFormulaShiftPress := False;
   EditFormula.SelAttributes.Size := 12;
End;

Procedure TFormMain.EditFormulaKeyDown(Sender : TObject; Var Key : Word;
   Shift : TShiftState);
Begin //化学式输入框只可输入大小写字母、数字、()
   If Key In [48..57, 16, 65..90, 8, 46] Then Begin
      If ssShift In Shift Then Begin //按住Shift,再按字母键或"9","0"键时输入大写字母或"()"
         EditFormulaShiftPress := true;
         If Key In [65..90, 48, 57] Then //48为"0"键的编号,57为"9"键的编号,65..90为字母键编号
            EditFormula.ReadOnly := False //可接收此字符
         Else
            EditFormula.ReadOnly := true; //不可接收此字符
         Exit;
      End;
      EditFormula.ReadOnly := False //可接收此字符
   End Else
      EditFormula.ReadOnly := true; //不可接收此字符
End;

Procedure TFormMain.TabSheet1Show(Sender : TObject);
Var
   Sheet : TTabSheet;
Begin //方程式配平与相对原子质量计算 关于浓度的计算 共用一个化学式编辑器
   Case (Sender As TComponent).tag Of
      1 : Sheet := TabSheet1;
      2 : Sheet := TabSheet3;
   End;
   EditFormula.Parent := Sheet; //将EditFormula移入指定Sheet
   BtnDelete.Parent := Sheet; //将BtnDelete移入指定Sheet
End;

Procedure TFormMain.Button2Click(Sender : TObject);
Begin
   Try
      Label14.Caption := 'M=' + GetMassOfFormula(EditFormula.Text) //输出式量
   Except
      On E : Exception Do //发生错误,输入的化学式无法计算式量
         MessageDlg(ErrInfo, mtError, [mbOK], 0);
   End;
End;

Procedure TFormMain.BtnCalcClick(Sender : TObject);
Var
   i, t : Integer;
   RM : Single; //临时变量,存方程的解
   Formula : String;
Begin
   {
     本过程利用方程方法求解
     方程一:MassA.Text + MassB = MassMixed
     方程二:MassA.Text * NongDuA + MassB * NongDuB = MassMixed * NongDuMixed
   }
   Try
      t := 0;
      For i := 4 To 6 Do
         If SolutionEdits[i].Text = '' Then
            t := i; //得到哪个质量输入框是空的
      If t = 0 Then //哪个质量输入框是也不是空的.发生错误
         Raise Exception.Create('');

      SolutionEdits[t].Text := 'X*1';
      Formula := MassA.Text + '+' + MassB.Text + '=' + MassMixed.Text; //生成方程
      RM := GetEquationResult(Formula);
      If RM < 0 Then Raise Exception.Create('');
      SolutionEdits[t].Text := FloatToStr(RM); //输出解

      t := 0;
      For i := 1 To 3 Do
         If SolutionEdits[i].Text = '' Then
            t := i; //得到哪个浓度输入框是空的
      If t = 0 Then //哪个浓度输入框是也不是空的.发生错误
         Raise Exception.Create('');

      SolutionEdits[t].Text := 'X*1';
      Formula := NongDuA.Text + '*' + MassA.Text + '/100' + '+' + NongDuB.Text + '*' + MassB.Text +
         '/100' + '=' + NongDuMixed.Text + '*' + MassMixed.Text + '/100'; //生成方程
      RM := GetEquationResult(Formula); //求解
      If RM < 0 Then Raise Exception.Create('');
      SolutionEdits[t].Text := FormatFloat('0.00', RM); //格式化并输出解
   Except //发生错误
      On E : Exception Do Begin
         MessageDlg(ErrInfo, mtError, [mbOK], 0);
         For i := 1 To 6 Do
            SolutionEdits[i].Text := '';
      End;
   End;
End;

Procedure TFormMain.BtnBalanceClick(Sender : TObject);
Var

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -