ComObjectArray how to Topic is solved

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
Yfreet
Posts: 4
Joined: 19 Mar 2024, 05:02

ComObjectArray how to

Post by Yfreet » 17 May 2024, 02:57

Hi. I've searched the forum already but found nothing to the topic, so, apologies if repeated.
I need help with ComObjectArray. I managed to send POST and GET requests to a webpage and get answers with .responseText. I can process it, since it's a string formatted as JSON, but I thought it would be more convenient to process .responseBody, which is ComObjectArray, to get relevant parts by key names. But - I couldn't find anything about it's methods, AHK docs are not really helpful here.

teadrinker
Posts: 4410
Joined: 29 Mar 2015, 09:41
Contact:

Re: ComObjectArray how to  Topic is solved

Post by teadrinker » 17 May 2024, 03:52

The object returned by the ResponseBody method is not what you are assuming. It is a SafeArray, which is an array of bytes.
However, if the site returns a JSON string, you may well be able to turn it into an AHK object using libraries, of which there are several on our site.

Code: Select all

#Requires AutoHotkey v2

ahkReleaseUrl := 'https://api.github.com/repos/AutoHotkey/AutoHotkey/releases'

MsgBox json := WebRequest(ahkReleaseUrl)
ahkObj := JsonToAhk(json)
MsgBox ahkObj[1]['assets'][1]['browser_download_url']

WebRequest(url, method := 'GET', HeadersMap := '', binary := false, body?, &status?) {
    Whr := ComObject('WinHttp.WinHttpRequest.5.1')
    Whr.Open(method, url, true)
    if HeadersMap is Map {
        for name, value in HeadersMap
            Whr.SetRequestHeader(name, value)
    }
    Whr.Send(body ?? '')
    Whr.WaitForResponse()
    status := Whr.status
    SafeArray := Whr.responseBody
    pData := NumGet(ComObjValue(SafeArray) + 8 + A_PtrSize, 'Ptr')
    length := SafeArray.MaxIndex() + 1
    if !binary {
        return StrGet(pData, length, 'UTF-8')
    }
    DllCall('RtlMoveMemory', 'Ptr', data := Buffer(length), 'Ptr', pData, 'Ptr', length)
    return data
}

JsonToAhk(json, objIsMap := true, _rec?) {
    static fn := %A_ThisFunc%, document := '', JS
    if !document {
        document := ComObject('HTMLFILE')
        document.write('<meta http-equiv="X-UA-Compatible" content="IE=9">')
        JS := document.parentWindow
        (document.documentMode < 9 && JS.execScript())
    }
    switch {
        case !IsSet(_rec)    : obj := fn(JS.JSON.parse(json), objIsMap, true)
        case !IsObject(json) : obj := json
        case JS.Object.prototype.toString.call(json) == '[object Array]':
            obj := []
            Loop json.length {
                obj.Push(fn(json.%A_Index - 1%, objIsMap, true))
            }
        default:
            obj := objIsMap ? Map() : {}
            keys := JS.Object.keys(json)
            Loop keys.length {
                k := keys.%A_Index - 1%
                objIsMap ? obj[k]  := fn(json.%k%, true , true)
                         : obj.%k% := fn(json.%k%, false, true)
            }
    }
    return obj
}

Yfreet
Posts: 4
Joined: 19 Mar 2024, 05:02

Re: ComObjectArray how to

Post by Yfreet » 17 May 2024, 04:13

Thanks for explanation. I was able to convert the string with JXON library and access the relevant parts. I thought I'm doing a workaround, because I don't know better, but went accidentally in right direction from the beginning (◠‿◠)

Post Reply

Return to “Ask for Help (v2)”