1 (изменено: Androgen, 2008-08-27 18:54:01)

Тема: AutoHotkey: Eval(), или вычисление динамических выражений

Поскольку в AutoHotkey переменные хранятся как символьные строки, то невозможно "простым" способом перевести символьную строку в выражение.
Иными словами, если переменная получает такое содержание 1+2*3-4, то такая строка рассматривается AHK именно как строка, а не как последовательность математических операций. Такое содержание переменная может получить, например, при чтении файла командой FileRead или кучей других способов. Главное, - что нет возможности написать ЗАРАНЕЕ:
Res := 1+2*3-4
(Вот здесь, кстати, можно посмотреть и соответствующую ситуацию и способ её решения.)

Для таких случаев, в WSH есть функция eval(). А в AutoHotkey такой функции нет. А теперь есть . Вот она.
Функция вычисляет динамическое выражение, результатом которого может быть числовое значение.
Динамическое выражение - выражение, полученное в процессе выполнения скрипта.
Эту функцию я практически целиком взял с английского форума. Только слегка её шлифанул.
Вот сама функция:

;-------------------------------------------------------------------------------
Eval( _String ) ; Функция вычисляет динамическое выражение
{
    ; В качестве параметра функция принимает строку, содержащую выражение

    pid := DllCall( "GetCurrentProcessId" )
    VarSetCapacity( buffer, 100, 1)
    pBuffer := &buffer

    ; задаём имя временного скрипта
    FormatTime, TimeString,, yyyy.MM.dd-HH.mm.ss
    TempScript = %A_Temp%\%TimeString%.ahk

    ; пишем содержимое временного скрипта
    FileAppend,
    (    LTrim
        #NoTrayIcon
        expression := %_String% ; вот, собственно, из-за чего весь огород

        ; 0x8|0x20 = PROCESS_VM_OPERATION|PROCESS_VM_WRITE
        hp_parent := DllCall( "OpenProcess"
                            , "UInt", 0x8|0x20
                            , "Int", 0
                            , "UInt", %pid% )

        ; результат вычислений - в память вызывающей функции
        ; (отвязываемся от этого временного скрипта)
        DllCall( "WriteProcessMemory"
                , "UInt", hp_parent
                , "UInt", %pBuffer%
                , "UInt", &expression
                , "UInt", StrLen( expression )+1
                , "UInt", 0 )

    ), %TempScript%

    RunWait, %TempScript% ; запускаем временный скрипт
    FileDelete, %TempScript%
    Return, buffer
}
;-------------------------------------------------------------------------------

Вот пример её применения:

#Include Eval().ahk
Str = 1+2*3-4
;~ Str := Clipboard ; если скопировать к-либо выражение в буфер обмена
value := Eval( Str )
MsgBox, %Str% = %value%

Или забрать скрипт с примером и описанием. Рекомендую:

Post's attachments

Eval().zip 1.35 kb, 446 downloads since 2008-08-27 

You don't have the permssions to download the attachments of this post.
Крокодил, крокожу и буду крокодить! (Твёрдое обещание нетрезвого кодера).