我创建了一个网页,我想访问一个html页面的R / W的javascript变量。
...
<script>
var _ANYINT = 0;
var _ANYOBJ = 0;
</script>
...
如何阅读变量?
function ReadInt(varName) : integer
Result := webbrowser.document.all.?????????? var Name ?????
end;
r := ReadInt('_ANYINT');
如何写入?
感谢: DD
答案 0 :(得分:7)
要从html示例中获取_ANYINT变量,请使用以下代码:
function Read_ANYINT: integer;
var
v: OleVariant;
begin
v := Browser.Document;
Result := v.parentWindow._ANYINT;
end;
r := Read_ANYINT;
使用此HTML代码:
<html>
<head>
<script>
var myVariable={name: "LA LA LA", x: 3, y: 5, mul: function () {return this.x * this.y}};
var myArray=["Yello", "Green"];
</script>
</head>
<body>
</body>
</html>
你可以在德尔福做:
var
v: OleVariant;
...
v := Browser.Document.parentWindow;
ShowMessage(v.myVariable.name); // Will display LA LA LA
ShowMessage(v.myVariable.mul()); // Will display 15
如果通过file:///
协议加载HTML页面,则上述代码将无效。要使其正常工作,您应该使用http
协议或首先将WebBrowser控件导航到'about:blank'
,然后使用此过程从字符串加载HTML文档:
procedure LoadHTML(aDocument: IDispatch; aStr: WideString);
type
TRec = packed record
Byte1,
Byte2: Byte;
end;
PRec = ^TRec;
var
lStream: IPersistStreamInit;
lMemStream: TMemoryStream;
p: Pointer;
pp: PRec absolute p;
begin
lStream := aDocument as IPersistStreamInit;
//BOM
GetMem(p, Length(aStr) * 2 + 2);
pp.Byte1 := 255;
pp.Byte2 := 254;
CopyMemory(Pointer(Integer(p)+2), Pointer(aStr), Length(aStr) * 2);
lMemStream := TMemoryStream.Create;
try
lMemStream.WriteBuffer(p^, Length(aStr) * 2 + 2);
//lMemStream.WriteBuffer(Pointer(aStr)^, Length(aStr) * 2);
lMemStream.Position := 0;
lStream.Load(TStreamadapter.Create(lMemStream));
finally
FreeMem(p);
FreeAndNil(lMemStream);
end;
end;
要访问JavaScript数组,您必须处理IDispath,这里是处理它的包装类:
unit jsobj;
interface
uses
ActiveX;
type
TJSArraySortFunc = function(elt1, elt2: OleVariant): Integer;
TJSArraySortMethod = function(elt1, elt2: OleVariant): Integer of object;
TJSArrayWrapper = class
private
FObject: OleVariant;
FObjectInterface: IDispatch;
function GetItem(Index: Integer): OleVariant;
procedure SetItem(Index: Integer; const Value: OleVariant);
function GetLength: Integer;
public
constructor Create(const AObject: OleVariant);
property AsVariant: OleVariant read FObject;
property AsInterface: IDispatch read FObjectInterface;
property Item[Index: Integer]: OleVariant read GetItem write SetItem; default;
function GetEnum: IEnumVARIANT;
property Length: Integer read GetLength;
end;
implementation
uses
Windows,
SysUtils,
ComObj;
const
NullGuid: TGuid = "{00000000-0000-0000-0000-000000000000}";
NullParams: DISPPARAMS = (rgvarg: nil; rgdispidNamedArgs: nil; cArgs: 0; cNamedArgs: 0);
{ TJSArrayWrapper }
constructor TJSArrayWrapper.Create(const AObject: OleVariant);
begin
FObject := AObject;
FObjectInterface := IDispatch(FObject);
end;
function TJSArrayWrapper.GetEnum: IEnumVARIANT;
var
Res: OleVariant;
begin
OleCheck(
FObjectInterface.Invoke(
DISPID_NEWENUM,
NullGuid,
GetSystemDefaultLCID,
DISPATCH_METHOD or DISPATCH_PROPERTYGET,
NullParams,
@Res,
nil,
nil
)
);
Result := IUnknown(Res) as IEnumVARIANT;
end;
function TJSArrayWrapper.GetItem(Index: Integer): OleVariant;
var
Member: WideString;
DispId: DWORD;
begin
Member := IntToStr(Index);
OleCheck(
FObjectInterface.GetIDsOfNames(
NullGuid,
@Member,
1,
GetSystemDefaultLCID,
@DispId
)
);
OleCheck(
FObjectInterface.Invoke(
DispId,
NullGuid,
GetSystemDefaultLCID,
DISPATCH_PROPERTYGET,
NullParams,
@Result,
nil,
nil
)
);
end;
function TJSArrayWrapper.GetLength: Integer;
begin
Result := FObject.length;
end;
procedure TJSArrayWrapper.SetItem(Index: Integer; const Value: OleVariant);
const
ParamId: TDispId = DISPID_PROPERTYPUT;
var
Member: WideString;
DispId: TDispId;
Params: DISPPARAMS;
begin
Member := IntToStr(Index);
OleCheck(
FObjectInterface.GetIDsOfNames(
NullGuid,
@Member,
1,
GetSystemDefaultLCID,
@DispId
)
);
Params.rgvarg := @Value;
Params.rgdispidNamedArgs := @ParamId;
Params.cArgs := 1;
Params.cNamedArgs := 1;
OleCheck(
FObjectInterface.Invoke(
DispId,
NullGuid,
GetSystemDefaultLCID,
DISPATCH_PROPERTYPUT or DISPATCH_PROPERTYPUTREF,
Params,
nil,
nil,
nil
)
);
end;
end.
用法:
var
v: OleVariant;
i: Integer;
v := Browser.Document.parentWindow;
lArray := TJScriptArray.Create(v.myArray);
try
for i := 0 to lArray.Count - 1 do
begin
ShowMessage(lArray[i]);
end;
finally
FreeAndNil(lArray);
end;
答案 1 :(得分:3)
您可以通过查询IHTMLWindow来检索全局定义变量的值。
让我们假设这个简单的页面:
<html>
<head>
<script>
var myVariable=42;
</script>
</head>
<body>
</body>
</html>
使用TWebBrowser
组件,您可以通过以下方式获取myVariable
的值:
uses
MSHTML, ActiveX;
// Proper error checking omitted for brevity.
var
Window: IHTMLWindow2;
DispatchIdOfProperty: Integer;
MyPropertyValue: OleVariant;
Temp: TExcepInfo;
Res: Integer;
Params:TDispParams;
begin
// get window interface
Window:= (WebBrowser1.ControlInterface.Document as IHTMLDocument2).parentWindow;
Assert(Assigned(Window));
// get dispatch ID of our variable
if (Window as IDispatchEx).GetDispID('myVariable', fdexNameCaseSensitive, DispatchIdOfProperty) = S_OK then
begin
// no parameters
ZeroMemory(@Params, SizeOf(Params));
// get value of our variable
Res:=(Window as IDispatchEx).InvokeEx(DispatchIdOfProperty, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, @Params, MyPropertyValue, Temp, nil);
if Res=S_OK then
begin
// voila - this should display the value
ShowMessage(MyPropertyValue);
end else
ShowMessage('Error reading property value');
end
else
ShowMessage('Property not found');
end;
变体MyPropertyValue
包含42以上HTML。
编写变量是类似的。只需在DISPATCH_PROPERTYPUT
电话中使用InvokeEx
:
修改:设置代码。
const
IID_NULL: TGUID = '{00000000-0000-0000-0000-000000000000}';
DISPID_PROPERTYPUT: Integer = -3;
var
NewValue, Dummy: OleVariant;
if (Window as IDispatchEx).GetDispID('myVariable', fdexNameCaseSensitive, DispatchIdOfProperty) = S_OK then
begin
NewValue:= 84;
Params.rgvarg:= @NewValue;
Params.rgdispidNamedArgs:= @DISPID_PROPERTYPUT;
Params.cArgs:= 1;
Params.cNamedArgs:= 1;
if (Window as IDispatchEx).InvokeEx(DispatchIdOfProperty, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, @Params, Dummy, Temp, nil) <> S_OK then
Showmessage('Setting property value failed');
end else
Showmessage('Property not found');
如果你想知道:一个特殊的命名属性用于覆盖自动化服务器无法区分DISPATCH_PROPERTYPUT
和DISPATCH_PROPERTYGET
的某些情况。
答案 2 :(得分:0)
HTMLWindow
接口公开了一个execScript
函数,该函数允许在WebBrowser文档中执行javascript代码。例如,请参阅http://delphi.about.com/od/adptips2006/qt/wb_execscript.htm。
不幸的是,execScript
不允许返回结果。
因此,要访问javascript数据,您需要在javascript中编写一些函数,将所需数据放入页面中的隐藏字段,然后从Delphi中通过WebBrowser访问该字段。以下是一些有关如何执行此操作的示例代码。 http://www.delphidabbler.com/articles?article=21&part=1#retval