受複雑なjavascriptの値を外部インタフェース
-
06-09-2019 - |
質問
私ものを受信しようとしているお送り複雑な価値をTWebBrowser(TEmbeddedWB)と外部オブジェクトです。例えば;javascriptの使いようによって使用されている方法で配列としてのパラメータ:
var test = [123, 'abc'];
external.someFunction(test);
//Or something more complex
var complexObject = {
someMethod : function(){ return 1; },
someProperty : 123,
someArray : ['xyz', 3.14]
}
external.someFunction(complexObject);
チェックのVarTypeの両方のこれらの事例からでIDispatch.
function TSomeClass.someFunction(var Param : OleVariant) : OleVariant;
var
vType : Integer;
begin
vType := (VarType(Param) and VarTypeMask); //Says 9 (varDispatch)
Result := true;
end;
私は完全に馴染みのテレビジョンカメラとライトをなんなのかなどです。
の手によりお願い申し上げます。
解決
あなたは、他のOleVariant COMオブジェクトとしてJScriptのオブジェクトを扱うことができます。そこにいくつかの落とし穴は、配列の点である(及びわずか約任意のJScriptオブジェクトは、本質的に疎行列である)。
OleVariantにJScriptのオブジェクトを取得した後、あなたは単にあなたが(もちろんチェックをコンパイル時なし)任意の通常のコードと同じようにそれを呼び出すことができます。
ここで配列を扱うためのいくつかのコードがあります:
type
TJScriptArray = class
private
FArray: IDispatchEx;
FCount: Integer;
function GetProperty( const AName: String ): OleVariant;
function GetItem(Index: Integer): OleVariant;
public
constructor Create( AObj: OleVariant );
destructor Destroy; override;
public
property Count: Integer read FCount;
property Item[Index: Integer]: OleVariant read GetItem; default;
end;
function VarToDispatchEx( const AObject: OleVariant ): IDispatchEx;
begin
Result := nil;
if VarType( AObject ) <> varDispatch then
Exit;
Supports( IDispatch(AObject), IDispatchEx, Result );
end;
function IsJScriptArray( const AObject: OleVariant ): Boolean;
var
temp: IDispatchEx;
begin
temp := VarToDispatchEx( AObject );
Result := temp <> nil;
end;
constructor TJScriptArray.Create(AObj: OleVariant);
begin
inherited Create;
FArray := VarToDispatchEx( AObj );
if FArray = nil then
raise Exception.Create( 'TJscriptArray called with invalid parameters.' );
FCount := GetProperty( 'length' );
end;
destructor TJScriptArray.Destroy;
begin
inherited Destroy;
end;
function TJScriptArray.GetItem(Index: Integer): OleVariant;
begin
if Index > FCount then
raise Exception.Create( 'Index out of bounds.' );
Result := GetProperty( IntToStr( Index ) );
end;
function TJScriptArray.GetProperty(const AName: String): OleVariant;
var
sz: WideString;
id: Integer;
res: Variant;
ei: TExcepInfo;
params: TDispParams;
hr: HResult;
begin
{
ACTION: return the specified property from the jscript array
NOTE: since a jscript array is a sparse array there may be
gaps. In that case a null variant is returned. This is
signalled by the name (id) not existing.
}
sz := AName;
hr := FArray.GetDispID( PWideChar(sz), 0, id );
if hr = disp_e_UnknownName then begin
Result := Null;
Exit;
end
else
OleCheck( hr );
VarClear( res );
FillChar( ei, sizeof(ei), 0 );
FillChar( params, sizeof(params), 0 );
OleCheck( FArray.InvokeEx( id, 0, dispatch_PropertyGet, @params, @res, @ei, nil ) );
Result := res;
end;
他のヒント
私は直接あなたがしようとしているものを行っていないもののます。
バリアントであなたは、あなたが実際に動的にメソッドとプロパティにアクセスすることができます。
基本的に私は、あなたが直接すべてにアクセスすることができるはず疑います。
Param.Someproperty
Param.SomeArray[1]
Param.SomeMethod();
あなたは物事が間違っているので注意してください取得する場合の時間のコンパイルエラーを取得することはできません。
たとえば、次のコードはコンパイルされますが、動的にその変数に割り当てられているものはないとして、無効なバリアント操作の実行時エラーになります。
var
vo : OleVariant;
v : Variant;
begin
v.DoThis;
vo.DoThat;
end;
いま考え直列化さのおの複雑なデータをJavaScript Object Notation(JSON)?ることもできるのでserialize任意のJavaScriptオブジェクトを、パンとしての単純な文字列の文字を再構成してデコードです。
デ2009年にかけての支援のためのJSONが付着していることを想定せず、DataSnap(などの使いやす単体).また、インターネットで提供JSONの実装であることが役立つことが示される:
精算 lkjson や JSON-SuperObject
私の専門でJSONできるように相対的簡単で効率的なソリューションのための多言語データicです。
David
オブジェクト連想配列をしています、プロパティ名がキーであると:obj.prop
はobj['prop']
と同等です。
レギュラーアレイは単にプロパティとしてのインデックスを格納するオブジェクトであり、それらは疎な配列のように振る舞う。
DelphiのOLEVariantといったプロパティに直接アクセスできますが、その名前はデルファイの識別子が有効な場合にのみ、 に、それは(すなわちobj.0
はコンパイルされません)プロパティ名として数値インデックスを使用して好きではないので。
無効な識別子名を持つプロパティのライアンの応答するのようDISPATCH_PROPERTYGET
を呼び出す読み取ることができます。
しかしDelphiは直接これを行うにはComObj
unitに適切なルーチンが含まれます:
uses ComObj;
...
function TSomeClass.someFunction(var Param : OleVariant) : OleVariant;
begin
ShowMessage(Param.someProperty); // 123
ShowMessage(GetDispatchPropValue(Param, 'someProperty')); // 123
ShowMessage(Param.someArray.length); // 2
ShowMessage(GetDispatchPropValue(Param.someArray, '0')); // xyz
Result := true;
end;