最新如何制作一个VB计算器.docx
《最新如何制作一个VB计算器.docx》由会员分享,可在线阅读,更多相关《最新如何制作一个VB计算器.docx(44页珍藏版)》请在冰豆网上搜索。
最新如何制作一个VB计算器
如何制作一个VB计算器
如何制作一个VB计算器
功能说明:
支持加、减、乘、除、取反、阶乘、x的y次方、括号
按键重新分配、提高了工作效率
窗口过渡动画
实时输入纠错,计算纠错
其它经典实用的小功能期待发现与添加
界面预览:
前期准备:
有MicrosoftVisualBasic开发平台,懂基本的VB语法(有明白时查资料就行了)
计算顺序为()、!
、^、*/、取反、加减
算法为:
①首先扫描出()内需要优先计算的部分,将这部分用来计算
②依照计算顺序进行计算
③用计算结果替换原()联同()内表达式
④循环①~③直至只剩下一个数据
⑤结果的处理
主要内容:
怎样扫描出各个计算符号和需要运算的数据,怎样纠错,后面会详细介绍
开始动手之窗体设计:
(1)新建工程——标准exe
Form属性:
BordStyle=1,Caption=计算器,FillStyle=1,Height=4455,Width=7995,(近似的黄金分割)Picture自己找一张图片
(2)菜单工程——部件——控件——勾选MicrosoftForms2.0ObjectLibrary——确定
(3)在新出现的控件中添加一个Textbox
名称=tb,Backstyle=0,Boardstyle=1,Height=3615,Left=0,Top=0,Width=7995,Font适当
(4)一个Image
名称=img,Height=3615,Left=0,Top=0,Width=7995(尺寸位置与Textbox相同),visibal=false,stretch=true,Picture自己找一张图片
(5)在新出现的控件中添加一个Label
将长度调整为与窗体同长,高度刚好可以填补视界中两张图片的差,放过去填补这个差,这样应该懂了用意了吧,Backstyle=0,Boardstyle=0,Caption随意,Font适当
用鼠标点选这个标签,ctrl+c,ctrl+v创建数组,放到适当位置,重复总共放置5个,包含原来的那个。
把它们依次排开吧,赋上不同的Caption作为区分,怕麻烦就12345吧,不怕麻烦就,,,,,哎呀,自己想显示啥就写啥
(6)在新出现的控件中添加再两个Label
所有Label的形状相同(为的是节约空间,简洁好看麻),visable=false,名称分别为Label2和lb3
(7)5个Timer
按下F5欣赏到效果如下:
写程序啦
本程序由标签循环显示动画、弹出按键分配动画、错误提示动画和计算部分四个部分组成,下面分别介绍如何实现上述部分。
标签循环显示动画:
首先是Label()数组及时间控件的初始化,双击窗体,添加以下程序
PrivateSubForm_Load()
Fori=0To4’//把这个标签数组重叠,初始化显示的位置
Label1(i).Visible=False
Label1(i).Top=3600
Label1(i).Left=0
Nexti
Label1(0).Visible=True
Timer1.Interval=2000’//////////显示2秒钟后显示下一条提示
Timer2.Interval=50’//////////////移动时间间隔
Timer1.Enabled=True
Timer2.Enabled=False
EndSub
要达到的效果就是。
******************************按键循环滚动动画*********************************
再添加以下程序
PrivateSubTimer1_Timer()
Ifi=5Then
Label1(0).Visible=True
Label1
(1).Visible=False
Label1
(2).Visible=False
Label1(3).Visible=False
Label1(4).Visible=False
Label1(0).Top=3600
Label1
(1).Top=3600
Label1
(2).Top=3600
Label1(3).Top=3600
Label1(4).Top=3600
i=0
EndIf
Timer2.Enabled=True
i=i+1
EndSub
PrivateSubTimer2_Timer()
Label1(i-1).Top=Label1(i-1).Top+50
Ifi=5Then
Label1(0).Visible=True
Label1(0).Top=3600
ExitSub
EndIf
Label1(i).Visible=True
EndSub
在代码窗口的顶端选——通用——声明
加上
DimiAsInteger’///////就定义了一个i的全局变量
接下来就可以按下F5看看这个动画了。
***************************************************************************
错误提示动画
添加以下程序
PrivateSubTimer5_Timer()
Iflb3.Top>tb.HeightThen
lb3.Top=lb3.Top-150
Else
lb3.Top=tb.Height
Ifc<100Then
c=c+1
Else
c=0
Timer5.Enabled=False
lb3.Visible=False
EndIf
EndIf
EndSub
不要忘了在刚才的通用声明当中多加入一个c
Dimi,cAsInteger
在Form_load事件处理中添加
Timer5.Interval=10
Timer5.Enabled=False
为了测试一下这个动画以及方便后续操作
在程序最后添加
Functionnoti(sAsString)asInteger’/////////////错误提示子程序
lb3.Top=4110
lb3.Left=0
lb3.Visible=True
Timer5.Enabled=True
lb3.Caption=s
Noti=93
EndFunction
在程序窗口的顶端选tb——KeyDown,添加以下程序
PrivateSubtb_KeyDown(KeyCodeAsMSForms.ReturnInteger,ShiftAsInteger)
noti("1前缺少运算符")
EndSub按下F5,随意按下一个键试试效果吧
************************************************************************
弹出按键分配动画
PrivateSubCommandButton1_MouseMove(ButtonAsInteger,ShiftAsInteger,XAsSingle,YAsSingle)
CommandButton1.Visible=True
EndSub
PrivateSubimg_MouseMove(ButtonAsInteger,ShiftAsInteger,XAsSingle,YAsSingle)
Label2.Visible=False
img.Top=-2800
Timer4.Enabled=True
Timer3.Enabled=False
EndSub
PrivateSubLabel1_MouseMove(IndexAsInteger,ButtonAsInteger,ShiftAsInteger,XAsSingle,YAsSingle)
Label2.Visible=True
img.Top=-800
img.Visible=True
Timer3.Enabled=True
Timer4.Enabled=False
EndSub
PrivateSubTimer3_Timer()
img.Top=img.Top+100
Ifimg.Top>0Then
Timer3.Enabled=False
img.Top=0
EndIf
EndSub
PrivateSubTimer4_Timer()
img.Top=img.Top-100
Ifimg.Top<-4000Then
Timer4.Enabled=False
EndIf
EndSub
在Form_Load中添加
Timer3.Interval=5
Timer4.Interval=5
Timer3.Enabled=False
Timer4.Enabled=False
把Label2拖放在按键循环滚支显示的区域
又可以按下F5看看这个动画了
***************************************************************************
计算过程
计算过程代码在tb_KeyDown事件处理中:
总体构架是:
PrivateSubtb_KeyDown(KeyCodeAsMSForms.ReturnInteger,ShiftAsInteger)
①禁止修改已计算过的内容;
②表达式提取;
③Selectcasekeycode
实时纠错与按键分配
Endselect
④If确定键then
计算前纠错
开始计算过程;
结果处理;
结果显示;
Endif
⑤错误处理
Endsub
计算过程的框架为:
Whilem=8
从表达式(expression)中提取计算式(inexp),已为最后计算式则m=5(退出while)
计算计算式中所有的阶乘
计算计算式中所有的x^y
从左向右计算乘除
计算计算式中所有的取反
从左向右计算计算式中的加减
用计算结果替换原表达式中的计算式
wend
先写按键重新分配,也就是图2中的布局,要保留常规的输入方法,删除原来的测试程序noti("1前缺少运算符")
*********************************************************************
PrivateSubtb_KeyDown(KeyCodeAsMSForms.ReturnInteger,ShiftAsInteger)
SelectCaseKeyCode
CasevbKeyA
KeyCode=vbKey1
CasevbKeyS
KeyCode=vbKey2
CasevbKeyD
KeyCode=vbKey3
CasevbKeyF
KeyCode=vbKey4
CasevbKeyG
KeyCode=vbKey5
CasevbKeyH
KeyCode=vbKey6
CasevbKeyJ
KeyCode=vbKey7
CasevbKeyK
KeyCode=vbKey8
CasevbKeyL
KeyCode=vbKey9
Case186
KeyCode=vbKey0
CasevbKeySpace,190
KeyCode=vbKeyDecimal
Case20
KeyCode=40
SendKeys"+9"
Case222
KeyCode=41
SendKeys"+0"
CasevbKeyW,vbKeyE,vbKeyR,vbKeyT
KeyCode=vbKeyAdd
CasevbKeyZ,vbKeyX,vbKeyC,vbKeyV,189
KeyCode=vbKeySubtract
CasevbKeyY,vbKeyU,vbKeyI,vbKeyO
KeyCode=vbKeyMultiply
CasevbKeyB,vbKeyN,vbKeyM,188,191
KeyCode=vbKeyDivide
CasevbKeyP,219,220,221
KeyCode=41
SendKeys"+6"
Case192,9,vbKeyQ
KeyCode=41
SendKeys"+1"
CasevbKey2,vbKey3,vbKey4,vbKey5,vbKey7,189,190,191,192,219,220,221,222,186
IfShift=1Then
KeyCode=93
EndIf
CasevbKeyDelete
tb.Text=""
CasevbKeyEscape
End
EndSelect
EndSub
F5试试是不是在英文输入法下只能输入这些字符了,实时纠错也就是在这些case里添加一些判断语句,如果符合一定的条件则此按键有效,反之则发出提示,作出其它处理。
***************************************************************************
接下来,一鼓作气,给出剩下全部代码和详细注释
在程序最后添加上阶乘子函数
Functionfac(nAsDouble)AsDouble
DimiAsDouble
DimansAsDouble
ans=1
Ifn>0Then
Fori=1Ton
ans=ans*i
Nexti
fac=ans
Else
fac=1
EndIf
EndFunction
完整的KeyDown程序为
PrivateSubtb_KeyDown(KeyCodeAsMSForms.ReturnInteger,ShiftAsInteger)
Dimi,j,p,q,m,flag,flag1,flag2,flag3AsInteger
DimbAsDouble
Dims,inexp,expression,temp,s1,msgAsString
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''禁止修改已计算过的内容
Iftb.SelStart+cur_lIf光标位置+补偿(光标前一个字符位置)<历史记录长度
(即光标处在历史记录位置中)
Selectcase判断是按下的什么键
有效的按键为上下左右、end、home
Del则清空tb.text,历史记录长度,光标补偿
Esc结束程序
其它则keycode=93,此code不打印,形成忽略的效果
Endselect
Else
开始整个为输入、纠错和计算过程
SelectCaseKeyCode
Case33To40
CasevbKeyDelete
tb.Text=""
store_s=0
cur_l=0
CasevbKeyEscape
End
CaseElse
KeyCode=93
EndSelect
Else
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''数据纠错************************************************
expression=Right(tb.Text,Len(tb.Text)-store_s)’/////每按下一次键就刷新表达式
dot_s=""’/////dot_s是存储操作数的变量
flag=0
Iftb.SelStart<>0Then
Fori=tb.SelStart+cur_lTo1Step-1
SelectCaseMid(tb.Text,i,1)
Case0To9,"."
dot_s=Mid(tb.Text,i,1)&dot_s
CaseElse
flag=i
i=0
EndSelect
Nexti
Fori=tb.SelStart+cur_l+1ToLen(tb.Text)
SelectCaseMid(tb.Text,i,1)
Case0To9,"."
dot_s=dot_s&Mid(tb.Text,i,1)
CaseElse
i=Len(tb.Text)
EndSelect
Nexti
EndIf
''''''''''''''''''''''''''''''''''''''''''''''''''''''按键分配与纠错
Iftb.SelStart=0Then
flag1=1
Else
flag1=0
EndIf
SelectCaseKeyCode
CasevbKeyA
如果0~9前面的字符是!
或)则表明缺少运算符
SelectCaseMid(tb.Text,tb.SelStart+cur_l+flag1,1)
Case"!
",")"
KeyCode=noti("1前缺少运算符")
CaseElse
KeyCode=vbKey1
EndSelect
CasevbKeyS
SelectCaseMid(tb.Text,tb.SelStart+cur_l+flag1,1)
Case"!
",")"
KeyCode=noti("2前缺少运算符")
CaseElse
KeyCode=vbKey2
EndSelect
CasevbKeyD
SelectCaseMid(tb.Text,tb.SelStart+cur_l+flag1,1)
Case"!
",")"
KeyCode=noti("3前缺少运算符")
CaseElse
KeyCode=vbKey3
EndSelect
CasevbKeyF
SelectCaseMid(tb.Text,tb.SelStart+cur_l+flag1,1)
Case"!
",")"
KeyCode=noti("4前缺少运算符")
CaseElse
KeyCode=vbKey4
EndSelect
CasevbKeyG
SelectCaseMid(tb.Text,tb.SelStart+cur_l+flag1,1)
Case"!
",")"
KeyCode=noti("5前缺少运算符")
CaseElse
KeyCode=vbKey5
EndSelect
CasevbKeyH
SelectCaseMid(tb.Text,tb.SelStart+cur_l+flag1,1)
Case"!
",")"
KeyCode=noti("6前缺少运算符")
CaseElse
KeyCode=vbKey6
EndSelect
CasevbKeyJ
SelectCaseMid(tb.Text,tb.SelStart+cur_l+flag1,1)
Case"!
",")"
KeyCode=noti("7前缺少运算符")
CaseElse
KeyCode=vbKey7
EndSelect
CasevbKeyK
SelectCaseMid(tb.Text,tb.SelStart+cur_l+flag1,1)
Case"!
",")"
KeyCode=noti("8前缺少运算符")
CaseElse
KeyCode=vbKey8
EndSelect
CasevbKeyL
SelectCaseMid(tb.Text,tb.SelStart+cur_l+flag1,1)
Case"!
",")"
KeyCode=noti("9前缺少运算符")
CaseElse
KeyCode=vbKey9
EndSelect
Case186
SelectCaseMid(tb.Text,tb.SelStart+cur_l+flag1,1)
Case"!
",")"
keycode=noti("0前缺少运算符")
CaseElse
KeyCode=vbKey0
EndSelect
CasevbKey8
IfShift=1Then
Iftb.SelStart=0Then
keycode=noti("*前缺少操作数")
Else
SelectCaseMid(tb.Text,tb.SelStart+cur_l,1)
Case0To9,"!
",")"
CaseElse
keycode=noti("*前缺少操作数")
EndSelect
EndIf
EndIf
CasevbKey9
IfShift=1Then
Iftb.SelStart=0Then
Else
SelectCaseMid(tb.Text,tb.SelStart+cur_l,1)
Case0To9,"!
",")"
keycode=noti("(前缺少运算符")
CaseElse
EndSelect
EndIf
EndIf
CasevbKey0
IfShift=1Then
Iftb.SelStart=0OrInStr(1,expression,"(")+store_s>tb.SelStart+cur_lOrInStr(1,expression,"(")=0Then
keycode=noti(")前无匹配的(")
Else
S