Autohotkey 获取传递的ByRef变量的字符串值

Autohotkey 获取传递的ByRef变量的字符串值,autohotkey,byref,Autohotkey,Byref,假设我调用一个使用byref修饰符的函数。进入函数后,我想获取传递的变量的字符串值 myvar := "george" passit(myvar) passit(byref whatvar){ msgbox % %whatvar% ;I should see a messagebox reporting the string "myvar" } 如果我没有传递变量byref,那么获取变量的字符串值就可以了 也许我走错了方向。我想让函数知道被引用变量的字符串名称。最接近您想要的。

假设我调用一个使用
byref
修饰符的函数。进入函数后,我想获取传递的变量的字符串值

myvar := "george"
passit(myvar)

passit(byref whatvar){
    msgbox % %whatvar%    ;I should see a messagebox reporting the string "myvar"
}
如果我没有传递变量
byref
,那么获取变量的字符串值就可以了


也许我走错了方向。我想让函数知道被引用变量的字符串名称。

最接近您想要的。。。?这让我想起了我的一个问题。


这种方法使用buildinlistlines命令来访问所需的元数据

命令列表行打开当前脚本的主窗口,并显示最后执行的脚本行。 内容如下所示:

Script lines most recently executed (oldest first).  Press [F5] to refresh.  The seconds elapsed between a line and the one after it is in parentheses to the right (if not 0).  The bottommost line's elapsed time is the number of seconds since it executed.

---- D:\Eigene_Dateien\ahk scripts\test3.ahk
002: myvar := "george"
003: passit(myvar)  
007: MsgBox,GetOriginalVariableNameForSingleArgumentOfCurrentCall(A_ThisFunc)
012: lines := ListLines()

Press [F5] to refresh.
可以解析此数据以提取所需信息(传递给“passit”的内容)。 这里的一个问题是,没有以编程方式访问此信息的构建。 函数ListLines覆盖临时User32.ShowWindow和User32.SetForgroundWindow以返回true,因此可以在不显示窗口的情况下使用buildin命令ListLines(多线程脚本可能会产生问题)。从该“隐藏”窗口接收并清除其文本。函数是由Lexikos()编写的

GetOriginalVariableNameForSingleArgumentOfCurrentCall使用正则表达式提取变量名,该正则表达式搜索当前调用上方传递的函数的第一个调用(调用GetOriginalVariableNameForSingleArgumentOfCurrentCall)


乔德夫-这很接近。问题是我想将变量作为变量传递,而不是作为字符串传递。然后我希望函数能够知道传递的变量的字符串名。@BGM-Hmm我不知道是否可能。。。变量实际上是如何创建的?@BGM好的,我明白了。。。如果它绝对不能作为字符串传递,那么我真的不知道这是否可能……我认为他需要
byref
以便
passit
可以修改指定的变量。我同意,如果有一些构造可以将变量的名称作为字符串来获取,那将是很方便的,但这是针对论坛的愿望列表部分的…如果还没有人建议-我无法确定是否有。比如说,这似乎是可行的。非常感谢。那里发生了很多事情,你能解释一下发生了什么吗?为了让它更有趣,我做了以下操作:
global myvar msgbox%GetOriginalVariableNameForSingleArgumentOfCurrentCall(A_ThisFunc)。"=" . myvar
让消息框显示:
myvar=george
@BGM我添加了explanationExcellent!非常感谢-我理解,这对我来说和这段代码一样有价值。
Script lines most recently executed (oldest first).  Press [F5] to refresh.  The seconds elapsed between a line and the one after it is in parentheses to the right (if not 0).  The bottommost line's elapsed time is the number of seconds since it executed.

---- D:\Eigene_Dateien\ahk scripts\test3.ahk
002: myvar := "george"
003: passit(myvar)  
007: MsgBox,GetOriginalVariableNameForSingleArgumentOfCurrentCall(A_ThisFunc)
012: lines := ListLines()

Press [F5] to refresh.
  myvar := "george"
  passit(myvar)
return

passit(whatvar){
  msgbox % GetOriginalVariableNameForSingleArgumentOfCurrentCall(A_ThisFunc)
}

GetOriginalVariableNameForSingleArgumentOfCurrentCall(callerFuncName)
  {
  lines := ListLines()
  pattern = O)%callerFuncName%\((.*?)\).*?%A_ThisFunc%\(.*?\)
  RegExMatch(lines, pattern, match)
  return match[1]
  }

; Originally written by Lexikos / Copy of ListGlobalVars http://www.autohotkey.com/board/topic/20925-listvars/#entry156570
; with modifications from here http://www.autohotkey.com/board/topic/58110-printing-listlines-into-a-file/#entry365156
; Tested/Modified for AHK Unicode 64bit v1.1.14.03
ListLines()
{
    static hwndEdit, pSFW, pSW, bkpSFW, bkpSW
    ListLines Off

    if !hwndEdit
    {
        dhw := A_DetectHiddenWindows
        DetectHiddenWindows, On
        Process, Exist
        ControlGet, hwndEdit, Hwnd,, Edit1, ahk_class AutoHotkey ahk_pid %ErrorLevel%
        DetectHiddenWindows, %dhw%

        astr := A_IsUnicode ? "astr":"str"
        ptr := A_PtrSize=8 ? "ptr":"uint"
        hmod := DllCall("GetModuleHandle", "str", "user32.dll")
        pSFW := DllCall("GetProcAddress", ptr, hmod, astr, "SetForegroundWindow")
        pSW := DllCall("GetProcAddress", ptr, hmod, astr, "ShowWindow")
        DllCall("VirtualProtect", ptr, pSFW, ptr, 8, "uint", 0x40, "uint*", 0)
        DllCall("VirtualProtect", ptr, pSW, ptr, 8, "uint", 0x40, "uint*", 0)
        bkpSFW := NumGet(pSFW+0, 0, "int64")
        bkpSW := NumGet(pSW+0, 0, "int64")
    }

    if (A_PtrSize=8) {
        NumPut(0x0000C300000001B8, pSFW+0, 0, "int64")  ; return TRUE
        NumPut(0x0000C300000001B8, pSW+0, 0, "int64")   ; return TRUE
    } else {
        NumPut(0x0004C200000001B8, pSFW+0, 0, "int64")  ; return TRUE
        NumPut(0x0008C200000001B8, pSW+0, 0, "int64")   ; return TRUE
    }

    ListLines

    NumPut(bkpSFW, pSFW+0, 0, "int64")
    NumPut(bkpSW, pSW+0, 0, "int64")

    ; Retrieve ListLines text and strip out some unnecessary stuff:
    ControlGetText, ListLinesText,, ahk_id %hwndEdit%
    RegExMatch(ListLinesText, ".*`r`n`r`n\K[\s\S]*(?=`r`n`r`n.*$)", ListLinesText)
    StringReplace, ListLinesText, ListLinesText, `r`n, `n, All

    ListLines On
    return ListLinesText  ; This line appears in ListLines if we're called more than once.
}