Mat Posted June 23, 2009 Posted June 23, 2009 (edited) probably the most efficient bit of code I have ever written!! Basicly the final thing i've done after spending a long time with windows message codes. Theres some set on event for simple stuff, but most of the actual stuff is handled by message codes. I say its powerful, becouse you can use any built in autoit maths functions, as well as a few I've added, and its really easy to add them too, all you need to do is include the function in the script, and add the name to the array! I was very tempted to add an easy way to add them, but decided against it. other stuff: Options: Click on the "=" sign to bring up the options menu. options are: AllowBool (you can put 1=2 and it will return false), Allow advanced functions (when no, you can only use basic operators.), and the round value. Any oter options can be done fairly easily by editing the script I have also added mod to the basic operators (a%n). as fell as factorial (n!). != is changed to <>, ++ to +1, -- to -1. Also, 42b2 = 42 in base 2, as does 42b>2. b< does the opposite. Alternatively use the tobase and frombase functions (WBD ) Things to do: * Function/Variable adder code expandcollapse popup#NoTrayIcon Opt ("GUIOnEventMode", 1) Global Const $Pi = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132851 Global $aOps[27] = ["asin", "acos", "atan", "sin", "cos", "tan", "bitand", "bitnot", "bitor", "bitrotate", "bitshift", "fact", _ "bitxor", "ceiling", "exp", "floor", "log", "srandom", "round", "sqrt", "random", "abs", "rad", "deg", "tobase", "frombase"] Global $nBool = IniRead (@ScriptDir & "\settings.ini", "Settings", "AllowBool", 1) Global $iAdv = IniRead (@ScriptDir & "\settings.ini", "Settings", "Advanced", 1) Global $nRndVal = IniRead (@ScriptDir & "\settings.ini", "Settings", "RoundVal", 2) Global $x = IniRead (@ScriptDir & "\settings.ini", "Settings", "x", -1) Global $y = IniRead (@ScriptDir & "\settings.ini", "Settings", "y", -1) Global $sDefAng = IniRead (@ScriptDir & "\settings.ini", "Settings", "DefAng", "deg") If $sDefAng = "rad" Then $sDefAng = "" If Not FileExists (@ScriptDir & "\settings.ini") Then $hFile = FileOpen (@ScriptDir & "\settings.ini", 2) FileWrite ($hFile, "[Settings]" & @CRLF & "AllowBool=1" & @CRLF & "Advanced=1" & @CRLF & "RoundVal=2" & @CRLF & "x=-1" & _ @CRLF & "y=-1" & @CRLF & "DefAng=deg") FileFlush ($hFile) EndIf _MiniMode () Func _MiniMode () Global $hMiniUI = GUICreate ("MDiesel's Calculator!!", 205, 20, $x, $y, 0x80000000, 0x00000008 + 0x00000080) GUISetBkColor (0xDDE7FF) GUICtrlSetDefBkColor (-2) AdlibRegister ("_EmptyWorkingSet", 1000) GUICtrlCreateicon ("Shell32.dll", 28, 188, 1, 16, 17, 0x0100) GUICtrlSetCursor (-1, "IDC_HAND") GUICtrlSetOnEvent (-1, "_EventClose") GUICtrlCreateLabel ("|" & @CRLF & "||" & @CRLF & "|||" & @CRLF & "|||" & @CRLF & "|||" & @CRLF & "|||" & @CRLF & "|||" & @CRLF & "||" & @CRLF & "|", 0, 0, 5, 20, -1, 0x00100000) GUICtrlSetFont (-1, 2) GUICtrlSetCursor (-1, 9) Global $qInp = GUICtrlCreateInput ("", 7, 2, 100, 17, 2 + 16 + 128) Global $qVal = "" GUICtrlCreateLabel ("=", 109, 2, 5, 17, 0x0100) GUICtrlSetOnEvent (-1, "_Settings") Global $aInp = GUICtrlCreateInput ("", 116, 2, 70, 17, 2048) GUICtrlSetBkColor (-1, 0xFFFFFF) GUISetState (@SW_SHOW, $hMiniUI) $aPos = WinGetPos ($hMiniUI, "") Global $hSetUI = GUICreate ("Settings", 205, 172, $aPos[0], $aPos[1] + 20, 0x80880000, 0x00000088) GUIRegisterMsg (0x0047, "_Moved") GUIRegisterMsg (0x0111, "_Event") GUISetBkColor (0xDDE7FF) GUICtrlSetDefBkColor (-2) GUICtrlCreateicon ("Shell32.dll", 255, 186, 3, 16, 17, 0x0100) GUICtrlSetCursor (-1, "IDC_HAND") GUICtrlSetOnEvent (-1, "_Settings") GUICtrlCreateButton ("DirectEdit", 2, 2, 180, 20) GUICtrlSetOnEvent (-1, "_EventSettingsEdit") GUICtrlCreateGroup ("Allow Boolean Results?", 2, 24, 196, 35) GUICtrlCreateRadio ("Yes", 8, 36, 80, 20) GUICtrlSetState (-1, 1) GUICtrlCreateRadio ("No", 93, 36, 80, 20) If $nBool = 0 Then GUICtrlSetState (-1, 1) GUICtrlCreateGroup ("Allow advanced Functions?", 2, 60, 196, 35) GUICtrlCreateRadio ("Yes", 8, 72, 80, 20) GUICtrlSetState (-1, 1) GUICtrlCreateRadio ("No", 93, 72, 80, 20) If $iAdv = 0 Then GUICtrlSetState (-1, 1) GUICtrlCreateGroup ("Round to: ", 2, 96, 196, 35) Global $hDec = GUICtrlCreateInput ($nRndVal, 8, 108, 80, 17) GUICtrlSetLimit (-1, 2) GUICtrlCreateUpDown ($hDec) GUICtrlSetLimit (-1, 99) GUICtrlCreateLabel ("Decimal Places.", 93, 110, 80, 20) GUICtrlCreateGroup ("Default Angle measurement", 2, 132, 196, 35) GUICtrlCreateRadio ("Deg", 8, 144, 80, 20) GUICtrlSetState (-1, 1) GUICtrlCreateRadio ("Rad", 93, 144, 80, 20) If $sDefAng = "rad" Then GUICtrlSetState (-1, 1) While 1 Sleep (5000) WEnd EndFunc ; ==> Minimode Func _Calculate ($sCalc) $sCalc = StringStripWS ($sCalc, 8) $sCalc = StringReplace ($sCalc, "!=", "<>") $sCalc = StringReplace ($sCalc, "++", "+1") $sCalc = StringReplace ($sCalc, "--", "-1") $sCalc = StringReplace ($sCalc, "==", "=") If $iAdv Then $sCalc = StringRegExpReplace ($sCalc, "sqrt\(([^\)]*)\)", "\(\1\^0\.5\)") $sCalc = StringRegExpReplace ($sCalc, "([0-9]*)!", "fact\(\1\)") $sCalc = StringRegExpReplace ($sCalc, "([0-9]*)%([0-9]*)", "\(mod\(\1\,\2\)\)") $sCalc = StringRegExpReplace ($sCalc, "([0-9]*)b>([0-9]*)", "\(tobase\(\1\,\2\)\)") $sCalc = StringRegExpReplace ($sCalc, "([0-9]*)b([0-9]*)", "\(tobase\(\1\,\2\)\)") $sCalc = StringRegExpReplace ($sCalc, "([0-9]*)b<([0-9]*)", "\(frombase\(\1\,\2\)\)") $sCalc = StringRegExpReplace ($sCalc, "(sin\([^\)]*\))", $sDefAng & "\(\1\)") $sCalc = StringRegExpReplace ($sCalc, "(asin\([^\)]*\))", $sDefAng & "\(\1\)") $sCalc = StringRegExpReplace ($sCalc, "(cos\([^\)]*\))", $sDefAng & "\(\1\)") $sCalc = StringRegExpReplace ($sCalc, "(acos\([^\)]*\))", $sDefAng & "\(\1\)") $sCalc = StringRegExpReplace ($sCalc, "(tan\([^\)]*\))", $sDefAng & "\(\1\)") $sCalc = StringRegExpReplace ($sCalc, "(atan\([^\)]*\))", $sDefAng & "\(\1\)") For $i = 0 to UBound ($aOps) - 1 If StringRegExp ($sCalc, $aOps[$i]) <> 0 Then $n = StringRegExp ($sCalc, $aOps[$i] & "\(([^\)]*)\)", 3) For $x = 0 to UBound ($n, 1) - 1 If StringInStr ($n[$x], ",") Then $nSplit = StringSplit ($n[$x], ",") For $s = 1 to $nSplit[0] $n[$x] &= Execute ($nSplit[$s]) Next Else $n[$x] = Execute ($n[$x]) EndIf $sCalc = StringReplace ($sCalc, $aOps[$i] & "(" & $n[$x] & ")", Execute ($aOps[$i] & "(" & $n[$x] & ")")) Next ExitLoop EndIf Next If StringInStr ($sCalc, "mod") Then $n = StringRegExp ($sCalc, $aOps[$i] & "\(([^\)]*)\)", 3) For $i = 0 to UBound ($n, 1) - 1 $sCalc = StringReplace ($sCalc, $aOps[$i] & "(" & $n[$i] & ")", Execute ($aOps[$i]) & (Execute ($n[$i]))) Next EndIf $sCalc = StringReplace ($sCalc, "pi", $Pi) If StringRegExp ($sCalc, "[:alpha:]*\([^\)]*\)") Then Return SetError (1, 0, "Unknown Function") EndIf If StringinStr ($sCalc, "=") Or StringRegExp ($sCalc, "[^b][<;>]") = 1 Then ; operator used, return bool $sCalc = Execute ($sCalc) If $sCalc = 1 Then Return SetExtended (1, "True") Return SetExtended (1, "False") EndIf Return Round (Execute ($sCalc), $nRndVal) EndFunc ; ==> _Calculate Func _Event ($hWnd, $msgId, $lParam, $wParam) If $hWnd = $hMiniUI Then If $msgId = 273 And $lParam = 0x04000005 Then If StringRegExp (StringRight (GUICtrlRead ($qInp), 1), "[^0-9;\);i;!]") Then Return "GUI_RunDefMsg" If StringLen (StringRegExpReplace (GUICtrlRead ($qInp), "[^\(]", "")) <> StringLen (StringRegExpReplace (GUICtrlRead ($qInp), "[^\)]", "")) Then Return "GUI_RunDefMsg" $qVal = GUICtrlRead ($qInp) $aVal = _Calculate ($qVal) If @Error <> 0 Then MsgBox (16, "Error - " & @Error, $aVal) ElseIf @Extended <> 0 Then If $nBool Then $aVal = "BOOL: " & $aVal Else GUISetState (@SW_HIDE, $hMiniUI) GUISetState (@SW_HIDE, $hSetUI) MsgBox (16, "Error - 42", "Incorrect input value: input contained =, < or >.") GUICtrlSetData ($qInp, "") GUICtrlSetData ($aInp, "") GUISetState (@SW_SHOW, $hMiniUI) GUISetState (@SW_SHOW, $hSetUI) EndIf EndIf GUICtrlSetData ($aInp, $aVal) EndIf Else Switch $lParam Case 0x0000000B ; bool yes $nBool = 1 Case 0x0000000C ; bool no $nBool = 0 Case 0x0000000E ; adv yes $iAdv = 1 Case 0x0000000F ; adv no $iAdv = 0 Case 0x02000011 ; dec $nRndVal = GUICtrlRead ($hDec) Case 0x00000015 ; deg $sDefAng = "deg" Case 0x00000016 ; rad $sDefAng = "" EndSwitch EndIf Return "GUI_RunDefMsg" EndFunc ; ==> _Event Func _EventClose () $aPos = WinGetPos ("MDiesel's Calculator!!", "") $hFile = FileOpen (@ScriptDir & "\settings.ini", 2) FileWrite ($hFile, "[Settings]" & @CRLF & "AllowBool=" & $nBool & @CRLF & "Advanced=" & $iAdv & @CRLF & "RoundVal=" & _ $nRndVal & @CRLF & "x=" & $aPos[0] & @CRLF & "y=" & $aPos[1] & @CRLF & "DefAng=" & $sDefAng) FileFlush ($hFile) Exit EndFunc ; ==> _EventClose Func _Settings () If BitAnd (WinGetState ($hSetUI, ""), 2) Then GUISetState (@SW_HIDE, $hSetUI) Else GUISetState (@SW_SHOW, $hSetUI) EndIf EndFunc ; ==> _Settings Func _EventSettingsEdit () $aPos = WinGetPos ("MDiesel's Calculator!!", "") $hFile = FileOpen (@ScriptDir & "\settings.ini", 2) FileWrite ($hFile, "[Settings]" & @CRLF & "AllowBool=" & $nBool & @CRLF & "Advanced=" & $iAdv & @CRLF & "RoundVal=" & _ $nRndVal & @CRLF & "x=" & $aPos[0] & @CRLF & "y=" & $aPos[1] & @CRLF & "DefAng=" & $sDefAng) FileFlush ($hFile) ShellExecute (@ScriptDir & "\settings.ini") EndFunc ; ==> _EventSettingsEdit Func fact ($iNum) $x = 1 For $i = 1 to $inum $x *= $i Next Return $x EndFunc ; ==> fact Func rad ($iDeg) Return $iDeg / ($pi/180) EndFunc ; ==> rad Func deg ($iRad) Return $iRad * ($pi/180) EndFunc ; ==> deg Func tobase ($iNumber, $iBase, $iPad = 1) If $iBase < 2 And $iBase > 36 Then Return 0 Local $sRet = "", $iDigit Do $iDigit = Mod ($iNumber, $iBase) $sRet = Chr (48 + $iDigit + 7 * ($iDigit > 9)) & $sRet $iNumber = Int ($iNumber / $iBase) Until ($iNumber = 0) And (StringLen ($sRet) >= $iPad) Return $sRet EndFunc ; ==> tobase Func frombase ($sNumber, $iBase) Local $iRet = 0, $sChar Do $iRet *= $iBase $sChar = StringLeft ($sNumber, 1) $iRet += Asc ($sChar) + 7 * (Asc($sChar) < 58) - 55 $sNumber = StringMid ($sNumber, 2) Until $sNumber = "" Return $iRet EndFunc ; ==> frombase Func _Moved ($hWnd, $msgID, $lParam, $wParam) $aPos = WinGetPos ("MDiesel's Calculator!!", "") If $aPos[1] > @DesktopHeight - 220 Then $aPos[1] = $aPos[1] - 193 WinMove ($hSetUI, "", $aPos[0], $aPos[1] + 20) EndFunc ; ==> _Moved Func _EmptyWorkingSet () DllCall ("psapi.dll", "int", "EmptyWorkingSet", "long", -1) EndFunc ; ==> _EmptyWorkingSet MDiesel Edit: missed a line of code... Edited June 23, 2009 by mdiesel AutoIt Project Listing
oMBRa Posted June 23, 2009 Posted June 23, 2009 (edited) Well done its a nice script! btw I found a minor error: Func deg ($iRad) Return $iDeg * ($pi/180) EndFunc; ==> deg $iDeg should be $iRad It would be good to use degree as well and not only rad with trigonometric (spelled right?) functions EDIT: found another bugs(?) "++1" returns 11, same for --, 1++1 returns 12... and can you explain how to use tobase, frombase etc functions? Edited June 23, 2009 by oMBRa
WideBoyDixon Posted June 23, 2009 Posted June 23, 2009 tobase ($decimal, $base, $pad) $decimal = number to convert $base = base to convert to $pad = minimum number of characters in the output E.g. If tobase(255, 16, 4) = "00FF" Then MsgBox(64, "Test", "Working!") frombase($number, $base) $number = string representation of the number in base form (e.g. "00ff") $base = base that the number is encoded in E.g. If frombase("00FF", 16) = 255 Then MsgBox(64, "Test", "Working again!") HTH. WBD. [center]Wide by name, Wide by nature and Wide by girth[u]Scripts[/u]{Hot Folders} {Screen Calipers} {Screen Crosshairs} {Cross-Process Subclassing} {GDI+ Clock} {ASCII Art Signatures}{Another GDI+ Clock} {Desktop Goldfish} {Game of Life} {3D Pie Chart} {Stock Tracker}[u]UDFs[/u]{_FileReplaceText} {_ArrayCompare} {_ToBase}~ My Scripts On Google Code ~[/center]
Mat Posted June 23, 2009 Author Posted June 23, 2009 thanks for the reply. Num B base is the syntax. 42b2 = 101010 (42 in base 2) or it can be 42b>2 the > or < is a direction indicator. 101010b<2 = 42 (101010 from 2) those are wbd's functions.. I did put that in the script... yer I did. Func tobase () ; WBD radians and degrees aren't my strong point. possibly an option "default angle" and deg/rad. it will probably be: $sCalc = StringRegExpReplace ($sCalc, "(sin\([^\)]*\))", $sDefAngle & "\(\1\)") untested. will do that then! as for ++ and -- thats probably supposed to be 1++ = 2... I will have a proper look when I get back... MDiesel AutoIt Project Listing
oMBRa Posted June 23, 2009 Posted June 23, 2009 (edited) tobase ($decimal, $base, $pad) $decimal = number to convert $base = base to convert to $pad = minimum number of characters in the output E.g. If tobase(255, 16, 4) = "00FF" Then MsgBox(64, "Test", "Working!") frombase($number, $base) $number = string representation of the number in base form (e.g. "00ff") $base = base that the number is encoded in E.g. If frombase("00FF", 16) = 255 Then MsgBox(64, "Test", "Working again!") HTH. WBD.aaah, I thought I had to use it inside the input box to do the conversion, btw converting any number to any base > 9 results in a never ending loop, because it does the calc while you are typing so it does first 65 to base 1... you should modify the tobase function in order to do nothing if base is 1 Edited June 23, 2009 by oMBRa
Mat Posted June 23, 2009 Author Posted June 23, 2009 aaah yep, I have done that in other functions, but not in this one... I am really struggling with this now... but I will post when I'm done MDiesel AutoIt Project Listing
Mat Posted June 23, 2009 Author Posted June 23, 2009 (edited) done!! in the end I realised I was double converting when $sDefAngle = "rad". codeupdate in post 1 will follow shortly. (done) I've got this running permanently now, and its doing well!! MDiesel Another edit. The settings and main gui's movements are now synced. Edited June 23, 2009 by mdiesel AutoIt Project Listing
oMBRa Posted June 23, 2009 Posted June 23, 2009 the problem "tobase" is still here because if I want to convert e.g. 65 to base 16 I would type 65b1 but it says range exceeded thus I cant complete it and adding the missing "6", you should return without doing anything
dmob Posted June 23, 2009 Posted June 23, 2009 CODED:\Scripts\Calculator.au3(140,22) : WARNING: $hMiniUI: possibly used before declaration. If $hWnd = $hMiniUI Then ~~~~~~~~~~~~~~~~~~~~^ .. even though I see its declared in line 26.
oMBRa Posted June 23, 2009 Posted June 23, 2009 you should either do a beta run or declare all global variables outside the functions
Mat Posted June 23, 2009 Author Posted June 23, 2009 (edited) no error here, but I can see why. I was registering a message before the should be fixed now.????? thats really not right as I declare the message that calls the function after declaring the variable, so whatever gave you that warning is wrong in this case.MDieselEdit: didn't see:the problem "tobase" is still here because if I want to convert e.g. 65 to base 16 I would type 65b1 but it says range exceeded thus I cant complete it and adding the missing "6", you should return without doing anythingfixed Edited June 23, 2009 by mdiesel AutoIt Project Listing
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now