把window运行框为我所用(字符串计算器,翻译,解码,打开应用等)

简介:

由于windows自带的计算器需要手动点点点实现加减乘除计算很是不方便,而且也记不住命令行打开的命令,最近就用ahk做了一个计算器,最开始想要自己做界面,后来发现自己做的界面很丑,而且不符合我最小依赖开发的理念。由于平时习惯用windows的运行框,然后就想能不能把计算结果整合到运行框中,后来发现运行的输入框是个控件,我们只需要获取输入,然后处理,然后把输出结果写入运行框中,完全不会影响运行框既有的功能。

最开始我想调用js来计算字符串表达式的值,但是计算**(幂)的时候不太方便,而且要u32版本才支持,后来纯用ahk代码逆波兰表达式也能实现计算字符串表达式的值。

使用步骤:

  1. 用win+R 打开运行框
  2. 输入计算表达式(代码自动识别 带有数字和运算符(+加,-减 ,*乘,/除,**幂,%模))
  3. 在表达式后面输入== ,输入框中就会计算出结果值。
  4. 由于输入框中只能输入 250个字符左右,当表达式字符超过35就只会显示结果,因为输入框可见长度就35左右,前面的字符就会隐藏。

运行效果:

把window运行框为我所用(字符串计算器,翻译,解码,打开应用等)

扩展:

当然这个运行框不但可以计算一些数学表达式,还可以计算一些其它的东西,我这里只是抛砖引玉,各位同学可以发挥自己的想象,对下面代码稍加修改就可以实现很多计算功能。

我给大家列举我想到并已经完成的操作:

  1. 计算asc 码,输入 asc x 得到asc码,chr  x 得到码值对应的字符
  2. 计算汉字unicode编码,unicode编码转为汉字
  3. 进制键转换 10进制,16进制,2进制互相转换
  4. 大小写转换 up xx =大写字符, down xx =小写字符
  5. 计算字符长度 len xx=n , lenx xx=n 计算16进制长度, 由于这个字符串很长可能运行框装不下我们可以先复制,然后获取粘贴板的值len[粘贴板]=n
  6. 正则表达式测试
  7. 获取计算机的关键信息, 例如 cpuid =xxx
  8. 计算平均值 ,avg 10 20 30= xxx
  9. 时间转换,1天=xx小时,xx分,xx秒 xx毫秒  或者  72小时=xx天,xx分,xx秒,xx毫秒 等
  10. 翻译,mean 中文=英文  或者 英文=中文 ,这个直接调用搜狗翻译,爬取结果即可,不用申请百度云等接口。
  11. 直接打开某个应用,输入baidu 打开百度,输入idea运行idea,输入目录打开目录,原理:创建一个配置文件,把所有的映射关系写到配置文件,例如:baidu=http://www.baidu.com  换行,idea=idea.exe,检测运行框回车事件,获取框中值,找到映射关系,然后用执行RUN xxx  就可以运行,当然如果啥都没匹配到那么我们就发送回车,执行系统的运行框的运行,这样不会影响系统本来的功能。

还可以用来实现啥,请各位同学踊跃补充,想看完整实现的也可以在下方评论,我把完整的代码贴出来,因为现有代码实在太长了,代码多了容易眼花缭乱。

上代码:

#If WinActive(Util.decodeUtf8("\u8FD0\u884C"))
;执行强大的计算功能
:*?:==::
    ;获取输入框文本
    ControlGetText, inputCmd , Edit1,  % Constant.RUN_BOX_TITLE
    result:=RunBoxUtil.getResult(inputCmd)
    ;计算出错了,具体原因不详
    if(result=="err")
    {
        height:=A_ScreenHeight-164
        ToolTip ,% Constant.CALCULATE_ERR,235,142
        SetTimer, RemoveToolTip, 3000
        return
     }
    ControlsetText,  % Constant.RUN_BOX_CONTROL,% result, % Constant.RUN_BOX_TITLE
    ControlSend, % Constant.RUN_BOX_CONTROL, {END}, % Constant.RUN_BOX_TITLE
    ;记录日志
    Util.writeToLog(Constant.AHK_CALCULATE_LOG, RunBoxUtil.EXPRESSION ,RunBoxUtil.OPERATE) ;写入日志
    return



class RunBoxUtil
{
    ;excel计算对象
    ;static oExcel := ComObjCreate("Excel.Application")

    ;当前是什么操作
    static OPERATE:=""
    ;当前表达式
    static EXPRESSION:=""

    ;获取计算结果
    getResult(rawStr)
    {
        ;原始字符串写入日志
        logRawStr:=rawStr

        ;去掉左边空格
        rawStr:=trim(rawStr)
        ;计算数学表达式
        tempStr:=RegExReplace(rawStr,"[a-zA-Z]+","")
        if(tempStr==rawStr)
        {
          if(InStr(rawStr, "+")>0 || InStr(rawStr, "-")>0 ||  InStr(rawStr, "*")>0 ||  InStr(rawStr, "/")>0
           ||InStr(rawStr, "%")>0 || InStr(rawStr, "**")>0)
           {
               leftExpression:=RegExReplace(rawStr,"\s+","")
               ;result:=Util.calcuateExpressions(rawStr)
               result:=Util.polish_notation(rawStr) ;无需调用js,用逆波兰表达式计算值
               result:=RegExReplace(result,"\.0+$","") ;去掉 2.000这样式的
               if(InStr(result,".")>0)
                    result:=RegExReplace(result,"0+$","")   ;去掉2.1200这样的
               fullExpression:= leftExpression "=" result
               RunBoxUtil.OPERATE:=Util.decodeUtf8("\u6570\u5B66\u8868\u8FBE\u5F0F\u8BA1\u7B97")
               RunBoxUtil.EXPRESSION:=logRawStr "=" result
               if(strLen(fullExpression)>35)
                    return result
               return fullExpression
           }
        }
        return rawStr
    }

}

;自定义工具类
Util
{
       ;逆波兰表达式https://blog.csdn.net/assiduous_me/article/details/101981332:
       polish_notation(expression)
       {
           operatorlevel_map:={"(":0,"+":"1","-":1,"*":2,"/":"2","%":2,"^":3,")":4}
           operator_list:={"+":0,"-":0,"*":0,"/":0,"%":0,"^":0}

           ;去除不必要的空格
           expression:=trim(expression)
           expression:=RegExReplace(expression,"\s+","")
           ;替换立方根
           StringReplace expression,expression,**,^,all
           ;替换负数
           StringReplace expression,expression,`(-,`(0-,all
           ;msgBox % expression
           ;①.获取一个中缀表达式集合类似 100+2 -> ["100","+","2"]
           middlefix_list:=[]
           fix:=""
           loop ,parse,expression
           {
               current_value:=A_LoopField
               if(operatorlevel_map.haskey(current_value))
               {
                 if(""!=fix)
                   middlefix_list.push(fix)
                 middlefix_list.push(current_value)
                 fix:=""
               }else fix:=fix current_value
           }
           if(fix!="")
             middlefix_list.push(fix)
          if(middlefix_list[1]="-") ;处理开头为负数
          {
              middlefix_list.insertAt(1,"(")
              middlefix_list.insertAt(2,"0")
              middlefix_list.insertAt(5,")")
          }
          ;②.转换为后缀表达式(逆波兰表达式)
           operator_stack:=[]
           suffix_list:=[]
           for  index ,currentElmt in middlefix_list
           {
                if(operator_list.haskey(currentElmt))
                {
                    while(operator_stack.length()>0 && operatorlevel_map[operator_stack[operator_stack.Length()]]>=operatorlevel_map[currentElmt])
                       suffix_list.push(operator_stack.pop())
                    operator_stack.push(currentElmt)
                }else if(currentElmt="(")
                   operator_stack.push("(")
                else if(currentElmt=")")
                {
                   while(operator_stack.length()>0 && operatorlevel_map[operator_stack[operator_stack.length()]]>operatorlevel_map["("])
                      suffix_list.push(operator_stack.pop())
                   if(operator_stack.length()>0)
                       operator_stack.pop()
                }
                else
                   suffix_list.push(currentElmt)
           }
           while(operator_stack.length()>0)
               suffix_list.push(operator_stack.pop())
           ;③.计算表达式最终的值,规则数字入栈,操作符就出栈两个元素计算值并把结果入栈
           number_stack:=[]
           for key,opertor_or_number in suffix_list
           {
              if(operator_list.haskey(opertor_or_number))
              {
                   number2:=number_stack.pop()
                   number1:=number_stack.pop()
                   if(opertor_or_number="+")
                       number_stack.push(number1+number2)
                   if(opertor_or_number="-")
                       number_stack.push(number1-number2)
                   if(opertor_or_number="*")
                       number_stack.push(number1*number2)
                   if(opertor_or_number="/")
                       number_stack.push(number1/number2)
                   if(opertor_or_number="%")
                       number_stack.push(mod(number1,number2))
                   if(opertor_or_number="^")
                       number_stack.push(number1**number2)
              }else
                   number_stack.push(opertor_or_number)
           }
           result:=number_stack.pop()
           return result

       }
       ;对utf-8解码
       decodeUtf8(value)
       {
             i := 0
             while (i := InStr(value, "\",, i+1)) {
               if !(SubStr(value, i+1, 1) == "u")
                 this.ParseError("\", text, pos - StrLen(SubStr(value, i+1)))
               uffff := Abs("0x" . SubStr(value, i+2, 4))
               if (A_IsUnicode || uffff < 0x100)
                 value := SubStr(value, 1, i-1) . Chr(uffff) . SubStr(value, i+6)
             }
           Return,value
        }
}

给TA捐赠
共{{data.count}}人
人已捐赠
应用案例

ahk悬浮粘贴板内容在桌面,实现复制

2022-6-17 19:43:15

案例

【实战】OCR识别数据后自动填单

2022-6-18 16:24:31

6 条回复 A文章作者 M管理员
  1. AHK中文社区
    1河许人给您捐赠了¥5
  2. AHK中文社区

    分享的内容很不错,排版可能还需要优化,感谢分享!

  3. Tycho79

    其实可以装一个Python当计算器用,可以满足你提到的大部分需求……

    • Tmz

      就是仿照的python的idle.

  4. lixin_

    大佬,代码不全,能更新一下不

    • Tmz

      如果是数学计算的话是没啥问题了,其它功能的话代码太多了,等空了把那些补充上去。

个人中心
购物车
优惠劵
有新私信 私信列表
搜索