数学计算是算是编程的基本功了。这一关就来写一个创意计算器吧!
任务
写一款计算器,至少能运算加减乘除。
示例代码
这是一款创意计算器,从网络上收集过来分享给大家,仅供大家把玩研究!
源代码(需要图片资源支持,完整版下载地址:蜂巢计算器 密码:k203):
; #Warn ; Enable warnings to assist with detecting common errors. #NoEnv SendMode Input SetWorkingDir %A_ScriptDir% #SingleInstance, Force DetectHiddenWindows, On DetectHiddenText, On Gui, Margin, 5, 5 Gui, Color, aabbcc Gui, Font, cBlack s12, Tahoma Gui, -Caption +AlwaysOnTop +LastFound SetTitleMatchMode 2 DetectHiddenWindows, On DetectHiddenText, On Gui, Add, Pic, x105 y47 w31 h31 +0x800000 gmove, move.png Gui, Add, Edit, x155 y47 w190 Right vedit1, Gui, Add, Pic, x360 y47 w31 h31 +0x800000 gExit, exit.png Gui, Add, Button, x155 y75 w50 h25 ghelp, Help Gui, Add, Button, x295 y75 w50 h25 gclear, Clear WinSet, TransColor, aabbcc, Hex Calc Gui, Show, w500 h500 , Hex Calc GoSub, win2 GoSub, win3 GoSub, win15 GoSub, win16 GoSub, win5 GoSub, win9 GoSub, win8 GoSub, win4 GoSub, win14 GoSub, win18 GoSub, win21 GoSub, win19 GoSub, win20 GoSub, win17 GoSub, win6 GoSub, win10 GoSub, win13 GoSub, win12 GoSub, win11 GoSub, win7 GoSub, docks GuiControl, 1:Focus, Edit1 Return win2: ; 6 WinGetPos, PX, PY, Width, Height, Hex Calc ecks := PX+215 wi := PY+222 GUI_ID:=WinExist() Gui, 2:Font, s20 Gui, 2:+AlwaysOnTop -Caption +LastFound +Owner1 Gui, 2:Add, Pic, x0 y0 w72 h70 vb6 gb6, oct.png Gui, 2:Add, Text, x30 y20 BackgroundTrans gb6, 6 Gui, 2:Show, w72 h72 x%ecks% y%wi%, win2 Gui, 2:Color, aabbcc WinSet, TransColor, aabbcc, win2 Return win3: WinGetPos, PX, PY, Width, Height, Hex Calc ecks := PX+215 wi := PY+150 GUI_ID:=WinExist() Gui, 3:Font, s20 Gui, 3:+AlwaysOnTop -Caption +LastFound +Owner1 Gui, 3:Add, Pic, x0 y0 w72 h70 vb9 gb9, oct.png Gui, 3:Add, Text, x30 y20 BackgroundTrans gb9, 9 Gui, 3:Show, w72 h72 x%ecks% y%wi%, win3 Gui, 3:Color, aabbcc WinSet, TransColor, aabbcc, win3 Return win4: WinGetPos, PX, PY, Width, Height, Hex Calc ecks := PX+215 wi := PY+78 GUI_ID:=WinExist() Gui, 4:Font, s20 Gui, 4:+AlwaysOnTop -Caption +LastFound +Owner1 +E0x08000000 Gui, 4:Add, Pic, x0 y0 w72 h70 vbdel gbdel, oct.png Gui, 4:Add, Text, x15 y20 BackgroundTrans gbdel, Del Gui, 4:Show, w72 h72 x%ecks% y%wi%, win4 Gui, 4:Color, aabbcc WinSet, TransColor, aabbcc, win4 Return win5: WinGetPos, PX, PY, Width, Height, Hex Calc ecks := PX+215 wi := PY+294 GUI_ID:=WinExist() Gui, 5:Font, s20 Gui, 5:+AlwaysOnTop -Caption +LastFound +Owner1 Gui, 5:Add, Pic, x0 y0 w72 h70 vb3 gb3, oct.png Gui, 5:Add, Text, x30 y20 BackgroundTrans gb3, 3 Gui, 5:Show, w72 h72 x%ecks% y%wi%, win5 Gui, 5:Color, aabbcc WinSet, TransColor, aabbcc, win5 Return win6: WinGetPos, PX, PY, Width, Height, Hex Calc ecks := PX+215 wi := PY+366 GUI_ID:=WinExist() Gui, 6:Font, s20 Gui, 6:+AlwaysOnTop -Caption +LastFound +Owner1 Gui, 6:Add, Pic, x0 y0 w72 h70 vb0 gb0, oct.png Gui, 6:Add, Text, x30 y20 BackgroundTrans gb0, 0 Gui, 6:Show, w72 h72 x%ecks% y%wi%, win6 Gui, 6:Color, aabbcc WinSet, TransColor, aabbcc, win6 Return win7: WinGetPos, PX, PY, Width, Height, Hex Calc ecks := PX+157 wi := PY+114 GUI_ID:=WinExist() Gui, 7:Font, s20 Gui, 7:+AlwaysOnTop -Caption +LastFound +Owner1 +E0x08000000 Gui, 7:Add, Pic, x0 y0 w72 h70 vbbs gbbs, oct.png Gui, 7:Add, Text, x17 y20 BackgroundTrans gbbs, BS Gui, 7:Show, w72 h72 x%ecks% y%wi% NoActivate, win7 Gui, 7:Color, aabbcc WinSet, TransColor, aabbcc, win7 Return win8: WinGetPos, PX, PY, Width, Height, Hex Calc ecks := PX+157 wi := PY+186 GUI_ID:=WinExist() Gui, 8:Font, s20 Gui, 8:+AlwaysOnTop -Caption +LastFound +Owner1 Gui, 8:Add, Pic, x0 y0 w72 h70 vb8 gb8, oct.png Gui, 8:Add, Text, x30 y20 BackgroundTrans gb8, 8 Gui, 8:Show, w72 h72 x%ecks% y%wi%, win8 Gui, 8:Color, aabbcc WinSet, TransColor, aabbcc, win8 Return win9: WinGetPos, PX, PY, Width, Height, Hex Calc ecks := PX+157 wi := PY+258 GUI_ID:=WinExist() Gui, 9:Font, s20 Gui, 9:+AlwaysOnTop -Caption +LastFound +Owner1 Gui, 9:Add, Pic, x0 y0 w72 h70 vb5 gb5, oct.png Gui, 9:Add, Text, x30 y20 BackgroundTrans gb5, 5 Gui, 9:Show, w72 h72 x%ecks% y%wi%, win9 Gui, 9:Color, aabbcc WinSet, TransColor, aabbcc, win9 Return win10: WinGetPos, PX, PY, Width, Height, Hex Calc ecks := PX+157 wi := PY+330 GUI_ID:=WinExist() Gui, 10:Font, s20 Gui, 10:+AlwaysOnTop -Caption +LastFound +Owner1 Gui, 10:Add, Pic, x0 y0 w72 h70 vb2 gb2, oct.png Gui, 10:Add, Text, x30 y20 BackgroundTrans gb2, 2 Gui, 10:Show, w72 h72 x%ecks% y%wi%, win10 Gui, 10:Color, aabbcc WinSet, TransColor, aabbcc, win10 Return win11: WinGetPos, PX, PY, Width, Height, Hex Calc ecks := PX+99 wi := PY+150 GUI_ID:=WinExist() Gui, 11:Font, s20 Gui, 11:+AlwaysOnTop -Caption +LastFound +Owner1 Gui, 11:Add, Pic, x0 y0 w72 h70 vb7 gb7, oct.png Gui, 11:Add, Text, x30 y20 BackgroundTrans gb7, 7 Gui, 11:Show, w72 h72 x%ecks% y%wi%, win11 Gui, 11:Color, aabbcc WinSet, TransColor, aabbcc, win11 Return win12: WinGetPos, PX, PY, Width, Height, Hex Calc ecks := PX+99 wi := PY+222 GUI_ID:=WinExist() Gui, 12:Font, s20 Gui, 12:+AlwaysOnTop -Caption +LastFound +Owner1 Gui, 12:Add, Pic, x0 y0 w72 h70 vb4 gb4, oct.png Gui, 12:Add, Text, x30 y20 BackgroundTrans gb4, 4 Gui, 12:Show, w72 h72 x%ecks% y%wi%, win12 Gui, 12:Color, aabbcc WinSet, TransColor, aabbcc, win12 Return win13: WinGetPos, PX, PY, Width, Height, Hex Calc ecks := PX+99 wi := PY+294 GUI_ID:=WinExist() Gui, 13:Font, s20 Gui, 13:+AlwaysOnTop -Caption +LastFound +Owner1 Gui, 13:Add, Pic, x0 y0 w72 h70 vb1 gb1, oct.png Gui, 13:Add, Text, x30 y20 BackgroundTrans gb1, 1 Gui, 13:Show, w72 h72 x%ecks% y%wi%, win13 Gui, 13:Color, aabbcc WinSet, TransColor, aabbcc, win13 Return win14: WinGetPos, PX, PY, Width, Height, Hex Calc ecks := PX+273 wi := PY+114 GUI_ID:=WinExist() Gui, 14:Font, s20 Gui, 14:+AlwaysOnTop -Caption +LastFound +Owner1 Gui, 14:Add, Pic, x0 y0 w72 h70 vbdiv gbdiv, oct.png Gui, 14:Add, Text, x32 y20 BackgroundTrans gbdiv, / Gui, 14:Show, w72 h72 x%ecks% y%wi%, win14 Gui, 14:Color, aabbcc WinSet, TransColor, aabbcc, win14 Return win15: WinGetPos, PX, PY, Width, Height, Hex Calc ecks := PX+273 wi := PY+186 GUI_ID:=WinExist() Gui, 15:Font, s20 Gui, 15:+AlwaysOnTop -Caption +LastFound +Owner1 Gui, 15:Add, Pic, x0 y0 w72 h70 vbtimes gbtimes, oct.png Gui, 15:Add, Text, x32 y27 BackgroundTrans gbtimes, * Gui, 15:Show, w72 h72 x%ecks% y%wi%, win15 Gui, 15:Color, aabbcc WinSet, TransColor, aabbcc, win15 Return win16: WinGetPos, PX, PY, Width, Height, Hex Calc ecks := PX+273 wi := PY+258 GUI_ID:=WinExist() Gui, 16:Font, s20 Gui, 16:+AlwaysOnTop -Caption +LastFound +Owner1 Gui, 16:Add, Pic, x0 y0 w72 h70 vbmin gbmin, oct.png Gui, 16:Add, Text, x32 y20 BackgroundTrans gbmin, - Gui, 16:Show, w72 h72 x%ecks% y%wi%, win16 Gui, 16:Color, aabbcc WinSet, TransColor, aabbcc, win16 Return win17: WinGetPos, PX, PY, Width, Height, Hex Calc ecks := PX+273 wi := PY+330 GUI_ID:=WinExist() Gui, 17:Font, s20 Gui, 17:+AlwaysOnTop -Caption +LastFound +Owner1 Gui, 17:Add, Pic, x0 y0 w72 h70 vbadd gbadd, oct.png Gui, 17:Add, Text, x30 y22 BackgroundTrans gbadd, + Gui, 17:Show, w72 h72 x%ecks% y%wi%, win17 Gui, 17:Color, aabbcc WinSet, TransColor, aabbcc, win17 Return win18: WinGetPos, PX, PY, Width, Height, Hex Calc ecks := PX+331 wi := PY+150 GUI_ID:=WinExist() Gui, 18:Font, s20 Gui, 18:+AlwaysOnTop -Caption +LastFound +Owner1 Gui, 18:Add, Pic, x0 y0 w36 h70 vbpl gbpl, octl.png Gui, 18:Add, Text, x20 y20 BackgroundTrans gbpl, ( Gui, 18:Show, w36 h72 x%ecks% y%wi%, win18 Gui, 18:Color, aabbcc WinSet, TransColor, aabbcc, win18 Return win19: WinGetPos, PX, PY, Width, Height, Hex Calc ecks := PX+331 wi := PY+222 GUI_ID:=WinExist() Gui, 19:Font, s20 Gui, 19:+AlwaysOnTop -Caption +LastFound +Owner1 Gui, 19:Add, Pic, x0 y0 w72 h70 vbdot gbdot, oct.png Gui, 19:Add, Text, x32 y15 BackgroundTrans gbdot, . Gui, 19:Show, w72 h72 x%ecks% y%wi%, win19 Gui, 19:Color, aabbcc WinSet, TransColor, aabbcc, win19 Return win20: WinGetPos, PX, PY, Width, Height, Hex Calc ecks := PX+331 wi := PY+294 GUI_ID:=WinExist() Gui, 20:Font, s20 Gui, 20:+AlwaysOnTop -Caption +LastFound +Owner1 Gui, 20:Add, Pic, x0 y0 w72 h70 vbent gbent, oct.png Gui, 20:Add, Text, x30 y22 BackgroundTrans gbent, = Gui, 20:Show, w72 h72 x%ecks% y%wi%, win020 Gui, 20:Color, aabbcc WinSet, TransColor, aabbcc, win020 Return win21: WinGetPos, PX, PY, Width, Height, Hex Calc ecks := PX+366 wi := PY+150 GUI_ID:=WinExist() Gui, 21:Font, s20 Gui, 21:+AlwaysOnTop -Caption +LastFound +Owner1 Gui, 21:Add, Pic, x0 y0 w36 h70 vbpr gbpr, octr.png Gui, 21:Add, Text, x10 y20 BackgroundTrans gbpr, ) Gui, 21:Show, w36 h72 x%ecks% y%wi%, win021 Gui, 21:Color, aabbcc WinSet, TransColor, aabbcc, win021 Return clear: GuiControl, 1:, Edit1, Return help: IfWinExist, Hex Calc Help WinClose, Hex Calc Help Else, Run, Hex Calc Help.ahk Return b6: ; win2 Gui, 1:Submit, NoHide OnPress("b6") GuiControl, 1:, Edit1, %Edit1%6 Return b9: ; win3 Gui, 1:Submit, NoHide OnPress("b9") GuiControl, 1:, Edit1, %Edit1%9 Return bdel: ; win4 Gui, 1:Submit, NoHide OnPress("bdel") GuiControl, 1:Focus, Edit1 Send, {Del} Return b3: ; win5 Gui, 1:Submit, NoHide OnPress("b3") GuiControl, 1:, Edit1, %Edit1%3 Return b0: ; win6 Gui, 1:Submit, NoHide OnPress("b0") GuiControl, 1:, Edit1, %Edit1%0 Return bbs: ; win7 Gui, 1:Submit, NoHide OnPress("bbs") GuiControl, 1:Focus, Edit1 Send, {BS} Return b8: ; win8 Gui, 1:Submit, NoHide OnPress("b8") GuiControl, 1:, Edit1, %Edit1%8 Return b5: ; win9 Gui, 1:Submit, NoHide OnPress("b5") GuiControl, 1:, Edit1, %Edit1%5 Return b2: ; win10 Gui, 1:Submit, NoHide OnPress("b2") GuiControl, 1:, Edit1, %Edit1%2 Return b7: ; win11 Gui, 1:Submit, NoHide OnPress("b7") GuiControl, 1:, Edit1, %Edit1%7 Return b4: ; win12 Gui, 1:Submit, NoHide OnPress("b4") GuiControl, 1:, Edit1, %Edit1%4 Return b1: ; win13 Gui, 1:Submit, NoHide OnPress("b1") GuiControl, 1:, Edit1, %Edit1%1 Return bdiv: ;win14 Gui, 1:Submit, NoHide OnPress("bdiv") GuiControl, 1:, Edit1, %Edit1%/ Return btimes: ;win15 Gui, 1:Submit, NoHide OnPress("btimes") GuiControl, 1:, Edit1, %Edit1%* Return bmin: ;win16 Gui, 1:Submit, NoHide OnPress("bmin") GuiControl, 1:, Edit1, %Edit1%- Return badd: ;win17 Gui, 1:Submit, NoHide OnPress("badd") GuiControl, 1:, Edit1, %Edit1%+ Return bpl: ;win18 Gui, 1:Submit, NoHide GuiControl, , bpl, octld.png Sleep, 100 GuiControl, , bpl, octl.png GuiControl, 1:, Edit1, %Edit1%( Return bdot: ;win19 Gui, 1:Submit, NoHide OnPress("bdot") GuiControl, 1:, Edit1, %Edit1%. Return bent: ;win20 Gui, 1:Submit, NoHide OnPress("bent") total := Eval(edit1) GuiControl, 1:, Edit1, %total% Return bpr: ;win21 Gui, 1:Submit, NoHide GuiControl, , bpr, octrd.png Sleep, 100 GuiControl, , bpr, octr.png GuiControl, 1:, Edit1, %Edit1%) Return docks: WinGet, IDG1, ID, Hex Calc WinGet, IDG2, ID, win2 DockA(IDG1, IDG2, "x(.43) y(.445) w() h()") WinGet, IDG3, ID, win3 DockA(IDG1, IDG3, "x(.43) y(.3) w() h()") WinGet, IDG4, ID, win4 DockA(IDG1, IDG4, "x(.43) y(.157) w() h()") WinGet, IDG5, ID, win5 DockA(IDG1, IDG5, "x(.43) y(.589) w() h()") WinGet, IDG6, ID, win6 DockA(IDG1, IDG6, "x(.43) y(.733) w() h()") WinGet, IDG7, ID, win7 DockA(IDG1, IDG7, "x(.315) y(.229) w() h()") WinGet, IDG8, ID, win8 DockA(IDG1, IDG8, "x(.315) y(.373) w() h()") WinGet, IDG9, ID, win9 DockA(IDG1, IDG9, "x(.315) y(.517) w() h()") WinGet, IDG10, ID, win10 DockA(IDG1, IDG10, "x(.315) y(.661) w() h()") WinGet, IDG11, ID, win11 DockA(IDG1, IDG11, "x(.199) y(.3) w() h()") WinGet, IDG12, ID, win12 DockA(IDG1, IDG12, "x(.199) y(.445) w() h()") WinGet, IDG13, ID, win13 DockA(IDG1, IDG13, "x(.199) y(.589) w() h()") WinGet, IDG14, ID, win14 DockA(IDG1, IDG14, "x(.547) y(.229) w() h()") WinGet, IDG15, ID, win15 DockA(IDG1, IDG15, "x(.547) y(.373) w() h()") WinGet, IDG16, ID, win16 DockA(IDG1, IDG16, "x(.547) y(.517) w() h()") WinGet, IDG17, ID, win17 DockA(IDG1, IDG17, "x(.547) y(.661) w() h()") WinGet, IDG18, ID, win18 DockA(IDG1, IDG18, "x(.663) y(.3) w() h()") WinGet, IDG19, ID, win19 DockA(IDG1, IDG19, "x(.663) y(.445) w() h()") WinGet, IDG020, ID, win020 DockA(IDG1, IDG020, "x(.663) y(.589) w() h()") WinGet, IDG21, ID, win021 DockA(IDG1, IDG21, "x(.733) y(.3) w() h()") Return move: PostMessage, 0xA1, 2,,, A Return Exit: GuiEscape: GuiClose: Sleep, 100 Gui, Destroy ExitApp Return OnPress(dDown) { GuiControl, , %dDown%, octd.png Sleep, 100 GuiControl, , %dDown%, oct.png } ; ; eval() v1.0 - Dynamic expression evaluation for AutoHotkey_L ; ; Crazily written by fincs - IT MAY CRASH ; The expression parsing code is translated from the AHK sources. If you need ; to know how it works, refer to the original code. ; ; WARNING - THIS LIBRARY ABUSES INTERNAL AHK STRUCTURES - IT IS GUARANTEED ; TO BE BROKEN BY A FUTURE AHK VERSION - Written for AutoHotkey v1.1.08 ; ; Search this file for 'TODO' and 'HACK' in order to know what's to be done ; ; https://github.com/fincs/ahk-eval/blob/master/Lib/eval.ahk Eval(x) { ; non-recursive PRE/POST PROCESSING: I/O forms, numbers, ops, ";" Local FORM, FormF, FormI, i, W, y, y1, y2, y3, y4 FormI := A_FormatInteger, FormF := A_FormatFloat SetFormat Integer, D ; decimal intermediate results! RegExMatch(x, "\$(b|h|x|)(\d*[eEgG]?)", y) FORM := y1, W := y2 ; HeX, Bin, .{digits} output format SetFormat FLOAT, 0.16e ; Full intermediate float precision StringReplace x, x, %y% ; remove $.. Loop If RegExMatch(x, "i)(.*)(0x[a-f\d]*)(.*)", y) x := y1 . y2+0 . y3 ; convert hex numbers to decimal Else Break Loop If RegExMatch(x, "(.*)'([01]*)(.*)", y) x := y1 . FromBin(y2) . y3 ; convert binary numbers to decimal: sign = first bit Else Break x := RegExReplace(x,"(^|[^.\d])(\d+)(e|E)","$1$2.$3") ; add missing '.' before E (1e3 -> 1.e3) ; literal scientific numbers between ‘ and ’ chars x := RegExReplace(x,"(\d*\.\d*|\d)([eE][+-]?\d+)","‘$1$2’") StringReplace x, x,`%, \, All ; % -> \ (= MOD) StringReplace x, x, **,@, All ; ** -> @ for easier process StringReplace x, x, +, ±, All ; ± is addition x := RegExReplace(x,"(‘[^’]*)±","$1+") ; ...not inside literal numbers StringReplace x, x, -, ¬, All ; ¬ is subtraction x := RegExReplace(x,"(‘[^’]*)¬","$1-") ; ...not inside literal numbers Loop Parse, x, `; y := Eval1(A_LoopField) ; work on pre-processed sub expressions ; return result of last sub-expression (numeric) If FORM = b ; convert output to binary y := W ? ToBinW(Round(y),W) : ToBin(Round(y)) Else If (FORM="h" or FORM="x") { SetFormat Integer, Hex ; convert output to hex y := Round(y) + 0 } Else { W := W="" ? "0.6g" : "0." . W ; Set output form, Default = 6 decimal places SetFormat FLOAT, %W% y += 0.0 } SetFormat Integer, %FormI% ; restore original formats SetFormat FLOAT, %FormF% Return y } Eval1(x) { ; recursive PREPROCESSING of :=, vars, (..) [decimal, no ";"] Local i, y, y1, y2, y3 ; save function definition: f(x) := expr If RegExMatch(x, "(\S*?)\((.*?)\)\s*:=\s*(.*)", y) { f%y1%__X := y2, f%y1%__F := y3 Return } ; execute leftmost ":=" operator of a := b := ... If RegExMatch(x, "(\S*?)\s*:=\s*(.*)", y) { y := "x" . y1 ; user vars internally start with x to avoid name conflicts Return %y% := Eval1(y2) } ; here: no variable to the left of last ":=" x := RegExReplace(x,"([\)’.\w]\s+|[\)’])([a-z_A-Z]+)","$1«$2»") ; op -> «op» x := RegExReplace(x,"\s+") ; remove spaces, tabs, newlines x := RegExReplace(x,"([a-z_A-Z]\w*)\(","'$1'(") ; func( -> 'func'( to avoid atan|tan conflicts x := RegExReplace(x,"([a-z_A-Z]\w*)([^\w'»’]|$)","%x$1%$2") ; VAR -> %xVAR% x := RegExReplace(x,"(‘[^’]*)%x[eE]%","$1e") ; in numbers %xe% -> e x := RegExReplace(x,"‘|’") ; no more need for number markers Transform x, Deref, %x% ; dereference all right-hand-side %var%-s Loop { ; find last innermost (..) If RegExMatch(x, "(.*)\(([^\(\)]*)\)(.*)", y) x := y1 . Eval@(y2) . y3 ; replace (x) with value of x Else Break } Return Eval@(x) } Eval@(x) { ; EVALUATE PRE-PROCESSED EXPRESSIONS [decimal, NO space, vars, (..), ";", ":="] Local i, y, y1, y2, y3, y4 If x is number ; no more operators left Return x ; execute rightmost ?,: operator RegExMatch(x, "(.*)(\?|:)(.*)", y) IfEqual y2,?, Return Eval@(y1) ? Eval@(y3) : "" IfEqual y2,:, Return ((y := Eval@(y1)) = "" ? Eval@(y3) : y) StringGetPos i, x, ||, R ; execute rightmost || operator IfGreaterOrEqual i,0, Return Eval@(SubStr(x,1,i)) || Eval@(SubStr(x,3+i)) StringGetPos i, x, &&, R ; execute rightmost && operator IfGreaterOrEqual i,0, Return Eval@(SubStr(x,1,i)) && Eval@(SubStr(x,3+i)) ; execute rightmost =, <> operator RegExMatch(x, "(.*)(?<![\<\>])(\<\>|=)(.*)", y) IfEqual y2,=, Return Eval@(y1) = Eval@(y3) IfEqual y2,<>, Return Eval@(y1) <> Eval@(y3) ; execute rightmost <,>,<=,>= operator RegExMatch(x, "(.*)(?<![\<\>])(\<=?|\>=?)(?![\<\>])(.*)", y) IfEqual y2,<, Return Eval@(y1) < Eval@(y3) IfEqual y2,>, Return Eval@(y1) > Eval@(y3) IfEqual y2,<=, Return Eval@(y1) <= Eval@(y3) IfEqual y2,>=, Return Eval@(y1) >= Eval@(y3) ; execute rightmost user operator (low precedence) RegExMatch(x, "i)(.*)«(.*?)»(.*)", y) If IsFunc(y2) Return %y2%(Eval@(y1),Eval@(y3)) ; predefined relational ops StringGetPos i, x, |, R ; execute rightmost | operator IfGreaterOrEqual i,0, Return Eval@(SubStr(x,1,i)) | Eval@(SubStr(x,2+i)) StringGetPos i, x, ^, R ; execute rightmost ^ operator IfGreaterOrEqual i,0, Return Eval@(SubStr(x,1,i)) ^ Eval@(SubStr(x,2+i)) StringGetPos i, x, &, R ; execute rightmost & operator IfGreaterOrEqual i,0, Return Eval@(SubStr(x,1,i)) & Eval@(SubStr(x,2+i)) ; execute rightmost <<, >> operator RegExMatch(x, "(.*)(\<\<|\>\>)(.*)", y) IfEqual y2,<<, Return Eval@(y1) << Eval@(y3) IfEqual y2,>>, Return Eval@(y1) >> Eval@(y3) ; execute rightmost +- (not unary) operator RegExMatch(x, "(.*[^!\~±¬\@\*/\\])(±|¬)(.*)", y) ; lower precedence ops already handled IfEqual y2,±, Return Eval@(y1) + Eval@(y3) IfEqual y2,¬, Return Eval@(y1) - Eval@(y3) ; execute rightmost */% operator RegExMatch(x, "(.*)(\*|/|\\)(.*)", y) IfEqual y2,*, Return Eval@(y1) * Eval@(y3) IfEqual y2,/, Return Eval@(y1) / Eval@(y3) IfEqual y2,\, Return Mod(Eval@(y1),Eval@(y3)) ; execute rightmost power StringGetPos i, x, @, R IfGreaterOrEqual i,0, Return Eval@(SubStr(x,1,i)) ** Eval@(SubStr(x,2+i)) ; execute rightmost function, unary operator If !RegExMatch(x,"(.*)(!|±|¬|~|'(.*)')(.*)", y) Return x ; no more function (y1 <> "" only at multiple unaries: --+-) IfEqual y2,!,Return Eval@(y1 . !y4) ; unary ! IfEqual y2,±,Return Eval@(y1 . y4) ; unary + IfEqual y2,¬,Return Eval@(y1 . -y4) ; unary - (they behave like functions) IfEqual y2,~,Return Eval@(y1 . ~y4) ; unary ~ If IsFunc(y3) Return Eval@(y1 . %y3%(y4)) ; built-in and predefined functions(y4) Return Eval@(y1 . Eval1(RegExReplace(f%y3%__F, f%y3%__X, y4))) ; LAST: user defined functions } ToBin(n) { ; Binary representation of n. 1st bit is SIGN: -8 -> 1000, -1 -> 1, 0 -> 0, 8 -> 01000 Return n=0||n=-1 ? -n : ToBin(n>>1) . n&1 } ToBinW(n,W=8) { ; LS W-bits of Binary representation of n Loop %W% ; Recursive (slower): Return W=1 ? n&1 : ToBinW(n>>1,W-1) . n&1 b := n&1 . b, n >>= 1 Return b } FromBin(bits) { ; Number converted from the binary "bits" string, 1st bit is SIGN n = 0 Loop Parse, bits n += n + A_LoopField Return n - (SubStr(bits,1,1)<<StrLen(bits)) } Sgn(x) { Return (x>0)-(x<0) } MIN(a,b) { Return a<b ? a : b } MAX(a,b) { Return a<b ? b : a } GCD(a,b) { ; Euclidean GCD Return b=0 ? Abs(a) : GCD(b, mod(a,b)) } Choose(n,k) { ; Binomial coefficient p := 1, i := 0, k := k < n-k ? k : n-k Loop %k% ; Recursive (slower): Return k = 0 ? 1 : Choose(n-1,k-1)*n//k p *= (n-i)/(k-i), i+=1 ; FOR INTEGERS: p *= n-i, p //= ++i Return Round(p) } Fib(n) { ; n-th Fibonacci number (n < 0 OK, iterative to avoid globals) a := 0, b := 1 Loop % abs(n)-1 c := b, b += a, a := c Return n=0 ? 0 : n>0 || n&1 ? b : -b } fac(n) { ; n! Return n<2 ? 1 : n*fac(n-1) } /* Title: DockA Dock AutoHotkey windows. Using dock module you can glue windows to an AHK window. Docked windows are called Clients and the window that keeps their position relative to itself is called the Host. Once Clients are connected to the Host, this group of windows will behave like single window - moving, sizing, focusing, hiding and other OS events will be handled by the module so that the "composite window" behaves like the single window. This module is version of Dock module that supports only AHK hosts (hence "A" in the name). Unlike Dock module, it doesnt'uses system hook to monitor windows changes. Function: DockA Parameters: hHost - Handle of the host GUI. This window must be AHK window. hClient - Handle of the client GUI. This window can be any window. DockDef - Dock definition, see below. To remove dock client pass "-". If you pass empty string, client will be docked to the host according to its current position relative to the host. Dock definition: Dock definition is white space separated combination of parameters which describe Client's position relative to the Host. Parameters are grouped into 4 classes - x, y, w & h parameters. Classes and their parameters are optional. Syntax: x(hw,cw,dx) y(hh,ch,dy) w(hw,dw) h(hh,dh) * The *x* coordinate of the top, left corner of the client window is computed as x(hw,cw,dx) = HostX + hw*HostWidth + cw*ClientWidth + dx * The *Y* coordinate of the top, left corner of the client window is computed as y(hh,ch,dy) = HostY + hh*HostHeight + ch*ClientHeight + dy * The width *W* of the client window is computed as w(hw,dw) = hw*HostWidth + dw * The height *H* of the client window is computed as h(hh,dh) = hh*HostHeight + dh If you omit any of the class parameters it will default to 0. So, the following expressions all have the same effect: (start code) x(0,0,0) = x(0,0) = x(0,0,) = x(0) = x(0,)= x(0,,) = x() = x(0,,0) = x(,0,0) = x(,,0) = ... y(0,1,0) = y(0,1) = y(,1) = y(,1,) = y(,1,0) = ... (end) Notice that x() is not the same as omitting x entirely. First case is equal to x(0,0,0) so it will set Client's X coordinate to be equal as Host's. In second case, x coordinate of the client will not be affected by the module (client will keep whatever x it has). Remarks: You can monitor WM_WINDOWPOSCHANGED=0x47 to detect when user move clients (if they are movable) in order to update dock properties About: o Original by majkinetor (no version number) o Minor changes to work with all versions of AutoHotkey, including x64 */ DockA(hHost="",hClient="",DockDef="") { DockA_(hHost+0,hClient+0,DockDef,"") } DockA_(hHost,hClient,DockDef,hWnd) { Static ;-- Assume static for all variables Static Dummy6580 ;-- Get/SetWindowLong flags ,GWL_HWNDPARENT:=-8 ;-- Note: For the "SetWindowLong" function, this constant name ; is a bit mislabeled. The function sets or removes the ; owner of a window. It does not set/remove the parent of the ; window. ;-- Messages ,WM_MOVE:=0x03 ;-- Developer call? if hClient and (DockDef<>WM_MOVE) { if not init ;-- First call { ;-- Workaround for AutoHotkey Basic PtrType:=(A_PtrSize=8) ? "Ptr":"UInt" ;-- Monitor WM_MOVE message ; Note: This monitor is never turned off. It stays on until the ; script ends. init:=OnMessage(WM_MOVE,A_ThisFunc) } hHost+=0 hClient+=0 if (DockDef="-") ;-- Undock { ;-- Relinquish ownership if attached if InStr(%hHost%,hClient) { StringReplace,%hHost%,%hHost%,%A_Space%%hClient% DllCall("SetWindowLong" . (A_PtrSize=8 ? "Ptr":"") ,PtrType,hClient ,"Int",GWL_HWNDPARENT ,PtrType,%hClient%_oldparent) } return } ;-- Pin to the current relative position if (DockDef="") { WinGetPos hX,hY,,,ahk_id %hHost% WinGetPos cX,cY,,,ahk_id %hClient% DockDef:="x(0,0," cX - hX ") y(0,0," cY - hY ")" } %hClient%_x1:=%hClient%_x2:=%hClient%_y1:=%hClient%_y2:=%hClient%_h1:=%hClient%_w1:=%hClient%_x3:=%hClient%_y3:=%hClient%_h2:=%hClient%_w2:="" Loop Parse,DockDef,%A_Space%%A_Tab% { if A_LoopField is Space Continue t:=A_LoopField c:=SubStr(t,1,1) t:=SubStr(t,3,-1) StringReplace,t,t,`,,|,UseErrorLevel t.=!ErrorLevel ? "||":(ErrorLevel=1 ? "|":"") Loop Parse,t,|,%A_Space%%A_Tab% %hClient%_%c%%A_Index%:=A_LoopField ? A_LoopField:0 } ;-- Assign ownership %hClient%_oldparent:=DllCall("SetWindowLong" . (A_PtrSize=8 ? "Ptr":""),PtrType,hClient,"Int",GWL_HWNDPARENT,PtrType,hHost) %hHost% .=(%hHost%="" ? A_Space:"") . hClient . A_Space } if (hHost=0) hHost:=hWnd if (%hHost%="") return oldDelay :=A_WinDelay oldCritical:=A_IsCritical SetWinDelay -1 Critical 100 ;-- Move/Reposition the client with the host window WinGetPos hX,hY,hW,hH,ahk_id %hHost% Loop Parse,%hHost%,%A_Space% { if A_LoopField is Space Continue j:=A_LoopField WinGetPos cX,cY,cW,cH,ahk_id %j% w:=%j%_w1*hW+%j%_w2 h:=%j%_h1*hH+%j%_h2 x:=hX+%j%_x1*hW+%j%_x2*(w ? w:cW)+%j%_x3 y:=hY+%j%_y1*hH+%j%_y2*(h ? h:cH)+%j%_y3 WinMove ahk_id %j%,,x,y,w ? w:"",h ? h:"" } SetWinDelay %oldDelay% Critical %oldCritical% }
想了一下,这个外观ID拿来改为一个带搜索框的蜂巢菜单,或许不错
嗯,有道理!欢迎修改!
感谢分享,有点意思,下来看看