I created a webpage, and I want to access a html page's javascript variable for R/W.
...
<script>
var _ANYINT = 0;
var _ANYOBJ = 0;
</script>
...
How can I read a variable?
function ReadInt(varName) : integer
Result := webbrowser.document.all.?????????? var Name ?????
end;
r := ReadInt('_ANYINT');
And how to write into?
Thanks: dd
To get _ANYINT variable from your html sample use this code:
function Read_ANYINT: integer;
var
v: OleVariant;
begin
v := Browser.Document;
Result := v.parentWindow._ANYINT;
end;
r := Read_ANYINT;
With this html code:
<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>
You can do in delphi:
var
v: OleVariant;
...
v := Browser.Document.parentWindow;
ShowMessage(v.myVariable.name); // Will display LA LA LA
ShowMessage(v.myVariable.mul()); // Will display 15
The above code will not work if HTML page was loaded via file:///
protocol. To get it working you should use http
protocol or first navigate WebBrowser control to 'about:blank'
and after that load HTML document from string using this procedure:
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;
To access JavaScript arrays you have to deal with IDispath, here is wrapper class to handle it:
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.
Usage:
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With