make this Reverse Polish Notation (RPN) calculator. There are some good freeware RPN
calculators or HP emulators available on the internet but I like the
simplicity of this.
; RPN calculator - proof of concept (HugoV) ; Very basic RPN calculator using SimpleArray v3 by Infogulch ; see http://www.autohotkey.com/forum/viewtopic.php?p=216134#216134 ; More about RPN http://en.wikipedia.org/wiki/Reverse_Polish_notation ; can only add/substract/divide/multiply ; If there is only one item on the stack that value will be used as "second" stack item ; so typing 5 Numpad+ will place 10 on the stack 5 Numpad* 25 etc ; example, to add 4 + 7 type: ; 4 ENTER 7 [ENTER] Numpad+ (no need for the second enter but is optional) #NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. SendMode Input ; Recommended for new scripts due to its superior speed and reliability. SetBatchLines, -1 help= ( RPN HOTKEYS: (Numpad)Enter: add value to stack or duplicate last stack item if empty Numpad+ add Numpad- substract Numpad* multiply Numpad/ divide ^Numpad/ Inverse value (5 -> 0.2, 0.2 -> 5) ^Numpad- toggle +/- value (5 becomes -5 or -5 becomes 5) ^Numpad+ toggle +/- value (5 becomes -5 or -5 becomes 5) ^DEL, ^BS or ^NumpadDot(.) remove last item from stack Del backspace in Edit ^Up/^Down swap last stack items UP/DOWN+Enter Select item from stack with up/down keys, pressing enter moves item to last position in stack ^c copy last item from stack to clipboard (usualy the answer of your calculation) ^e edit last stack ^s save stack.txt ^l load stack.txt LIB: SimpleArray v3 by Infogulch http://www.autohotkey.com/forum/viewtopic.php?p=216134#216134 ) Gui, Add, Listbox, x5 y5 w195 h120, Gui, Add, Edit, +Right x5 yp+115 w195 h25 vEntry, Gui, Add, Text, x5 yp+30 w195 h20 vSize, Stack size: 0 Gui, Show, w205 h170, RPN ControlFocus, Edit1, RPN Return #IfWinActive RPN Enter:: NumpadEnter:: Gui, Submit, NoHide If (Entry = "") Entry:=SA_Get(Stack, -1) ; here we check if the focus is on the listbox to see if we need to move it SendMessage, 0x188, 0, 0, ListBox1, RPN ; 0x188 is LB_GETCURSEL (for a ListBox). ChoicePos = %ErrorLevel% ; It will be -1 if there is no item selected. ChoicePos += 1 ; Convert from 0-based to 1-based, i.e. so that the first item is known as 1, not 0. If (ChoicePos = 4294967296) ; focus is not on listbox1 ChoicePos=0 If (ChoicePos > 0) ; focus was is on listbox1, move selected item to bottom of stack { Entry:=SA_Get(Stack, ChoicePos) Stack:=SA_Del(Stack, ChoicePos) } Stack:=SA_Set(Stack, Entry) Entry= Gosub, UpdateGui Return NumpadAdd:: Gui, Submit, Nohide If (Entry <> "") Stack:=SA_Set(Stack, Entry) UpdateStack(2,SA_Get(Stack, -2) + SA_Get(Stack, -1)) Gosub, UpdateGui Return ^NumpadDiv:: Gui, Submit, Nohide If (Entry <> "") Stack:=SA_Set(Stack, Entry) UpdateStack(1,1 / SA_Get(Stack, -1)) Gosub, UpdateGui Return NumpadDiv:: Gui, Submit, Nohide If (Entry <> "") Stack:=SA_Set(Stack, Entry) UpdateStack(2,SA_Get(Stack, -2) / SA_Get(Stack, -1)) Gosub, UpdateGui Return ^NumpadSub:: ^NumpadAdd:: Gui, Submit, Nohide If (Entry <> "") Stack:=SA_Set(Stack, Entry) UpdateStack(1,SA_Get(Stack, -1) * -1) Gosub, UpdateGui Return NumpadSub:: Gui, Submit, Nohide If (Entry <> "") Stack:=SA_Set(Stack, Entry) UpdateStack(2,SA_Get(Stack, -2) - SA_Get(Stack, -1)) Gosub, UpdateGui Return NumpadMult:: Gui, Submit, Nohide If (Entry <> "") Stack:=SA_Set(Stack, Entry) UpdateStack(2,SA_Get(Stack, -2) * SA_Get(Stack, -1)) Gosub, UpdateGui Return ^c:: Clipboard:=SA_Get(Stack, -1) Return ^e:: Store:=SA_Get(Stack, -1) Stack:=SA_Del(Stack, -1) Gosub, UpdateGui GuiControl, , Edit1, %store% ControlFocus, Edit1, RPN ControlSend, Edit1, {end}, RPN Store= Return ^s:: FileDelete, %A_ScriptDir%\stack.txt FileAppend, %Stack%, %A_ScriptDir%\stack.txt Return ^l:: FileRead, Stack, %A_ScriptDir%\stack.txt Gosub, UpdateGui Return Down:: ControlSend, ListBox1, {Down}, RPN ControlFocus, ListBox, RPN Return Up:: ControlSend, ListBox1, {Up}, RPN ControlFocus, ListBox, RPN Return Del::Send {BS} ^Del:: ^BS:: ^NumpadDot:: Stack:=SA_Del(Stack, -1) Gosub, UpdateGui Return ^Down:: ^Up:: Gui, Submit, Nohide If (Entry <> "") Stack:=SA_Set(Stack, Entry) Entry:=SA_Get(Stack, -1) Stack:=SA_Del(Stack, -1) Store:=SA_Get(Stack, -1) Stack:=SA_Del(Stack, -1) Stack:=SA_Set(Stack, Entry) Stack:=SA_Set(Stack, Store) Store= Gosub, UpdateGui Return F1:: MsgBox % Help Return #IfWinActive UpdateStack(Entries, Answer) { Global Stack Loop, % Entries Stack:=SA_Del(Stack, -1) Stack:=SA_Set(Stack, Answer) Return } UpdateGui: Size:=SA_Len(Stack) GuiControl,, Size, Stack size: %Size% StringReplace, StackList, Stack, , |, All GuiControl, , Listbox1, |%StackList% ; crude fix to keep last stack item in view ControlGet, ChildHWND, Hwnd,, ListBox1, RPN ; scrollbar to end of listbox http://www.autohotkey.com/forum/post-196306.html#196306 Loop { PreviousScrollPos:=DllCall("GetScrollPos", "UInt", ChildHWND, "Int", 1) ; Last parameter is 1 for SB_VERT, 0 for SB_HORZ. SendMessage, 0x115, 1, 0, ListBox1, RPN ; Scroll down (0x115 is WM_VSCROLL). CurrentScrollPos:=DllCall("GetScrollPos", "UInt", ChildHWND, "Int", 1) ; Last parameter is 1 for SB_VERT, 0 for SB_HORZ. If (CurrentScrollPos = PreviousScrollPos) Break } GuiControl, , Edit1, ControlFocus, Edit1, RPN Answer= Size= Stacklist= Return GuiEscape: ; ESC GuiClose: ; Program is closed ExitApp
Edit: needs SA.AHK included or in your lib, see <!-- m -->http://www.autohotke... ... 134#216134<!-- m -->
Edit2: Cleaned up version, added some new hotkeys. F1 displays help