直接修改内存中传递的参数的字符串

时间:2012-11-27 20:03:08

标签: memory-management com webbrowser-control autohotkey beforenavigate2

是否可以修改COM事件方法传递的函数参数的内存值?需要编辑COM对象中的属性值。

我正在尝试为ActiveX控件设置自定义用户代理,如果用户选择Refresh或打开链接页面,则使用自定义标头重新导航加载页面不成功。此外,Navigate()方法中的设置标头也不适用于带框的网页。

根据MSDN(http://msdn.microsoft.com/en-us/library/aa768326%28v=vs.85%29.aspx),标头值的参数作为ByRef传递。

所以我尝试简单地为它添加一个新值,但它没有用。

所以现在我认为如果存储在存储器中的值直接改变就可以实现。所以我尝试了以下但它不起作用。

有什么想法吗?

oWB := new WebBrowser("http://sofiablue.net/")

Class WebBrowser
{

    __New(strURL) { 

        static WB
        Gui, New, Resize 
        Gui, Add, ActiveX, vWB w780 h580 , Shell.Explorer  
        Gui, show, w800 h600

        ComObjConnect(WB, this) 

        WB.Navigate(strURL  
            , "_self"
            , null
            , null
            , "User-Agent: tester")
        Loop
           Sleep 10
        Until (WB.readyState=4 && WB.document.readyState="complete" && !WB.busy)    

    }

    BeforeNavigate2(oParams*) {
        ; oParams[6] := "User-Agent: modified" ; this does not work.
        ; StrPut("User-Agent: modified", oParams.GetAddress(6)) ; does not work     
        this.StrPutVar("User-Agent: modified", oParams[6], "utf-16")    ; does not work
    }

    StrPutVar(string, ByRef var, encoding)
    {
        ; Ensure capacity.
        VarSetCapacity( var, StrPut(string, encoding)
            ; StrPut returns char count, but VarSetCapacity needs bytes.
            * ((encoding="utf-16"||encoding="cp1200") ? 2 : 1) )
        ; Copy or convert the string.
        return StrPut(string, &var, encoding)
    }       
}

1 个答案:

答案 0 :(得分:1)

AutoHotkey对COM事件的ByRef参数的支持非常有限。

COM参数通过VARIANTARG结构数组传递。调用者通过在变量中存储其变量的地址来支持ByRef,并将类型设置为VT_BYREF和参数的var-type的按位或组合,例如VT_VARIANT

默认情况下,某些语言(例如VBScript)提供类型VT_BYREF|VT_VARIANT(0x400C)的变体;当参数的类型未知时,可能支持ByRef。因此,AutoHotkey会自动取消引用此类变体。因此,您的BeforeNavigate2方法永远不会收到引用,也无法输出到任何ByRef Variant参数。

对于更具体类型的任何ByRef参数,例如ByRef Cancel As Boolean,参数(在脚本中)应该接收表示引用的对象。例如,ComObjType(Cancel)将返回VT_BYREF|VT_BOOL(0x400B),ComObjValue(Cancel)将返回VARIANT_BOOL变量的地址,您可以在其中存储布尔值。可以使用以下内容存储 true 值:

if (ComObjType(Cancel) = 0x400B)  ; Safety check
    NumPut(-1, ComObjValue(Cancel), "short")

类型VT_DISPATCH,VT_UNKNOWN和VT_BSTR的ByRef输入/输出参数有其他要求。如果前一个值为非NULL,则必须先将其释放。对于VT_BSTR,必须使用SysAllocString(必须通过DllCall调用)分配新字符串。