Board index » delphi » getting Delphi to accept a passed-in VBScript 'ByRef Variant' as a file handle or similar

getting Delphi to accept a passed-in VBScript 'ByRef Variant' as a file handle or similar


2006-10-25 01:13:44 PM
delphi194
G'day all,
How do I do this? Or is it a case of DON'T!
set o = createobject( "project.class" )
Set oStream = oFSO.OpenTextFile("c:\trace.log", CONST_READ, False,
AS_SYSTEMDEFAULT )
res = o.method( oStream )
So I am passing a 'ByRef Variant' into my Delphi COM DLL. What I would like
to do is to read from that stream. How do I get Delphi to accept the
'ByRef Variant' as a file handle or similar?
Kind regards,
Bruce.
 
 

Re:getting Delphi to accept a passed-in VBScript 'ByRef Variant' as a file handle or similar

"axtens" <XXXX@XXXXX.COM>writes
Quote
set o = createobject( "project.class" )
Set oStream = oFSO.OpenTextFile("c:\trace.log", CONST_READ, False,
AS_SYSTEMDEFAULT )
res = o.method( oStream )

So I am passing a 'ByRef Variant' into my Delphi COM DLL.
All VBScript objects are themselves COM objects. They implement the
IUnknown and IDispatch interfaces, both of which are passable inside a
VARIANT. Inside your method, you need to look at the VARIANT's vt member to
know which interface is being passed to you, and then access the appropriate
member of the VARIANT to access the object accordingly.
Also, you should be accepting the VARIANT as 'ByVal' instead of 'ByRef'.
Quote
What I would like to do is to read from that stream. How do I get Delphi
to accept the 'ByRef Variant' as a file handle or similar?
You can not access the file handle. OpenTextFile() returns a TextStream
object. That is all you are going to have access to. However, TextStream
is not defined in any header file or type library, so you will have to
access its methods generically via the IDispatch::Invoke() method, either
directly or by copying the VARIANT into the VCL Variant class and then using
its OleProcedure() and/or OleFunction() method.
For example (untested):
void ProcessTextStream(IDispatch *pDisp)
{
// get the DISPID of the TextStream.Read() method...
OLECHAR *szName = L"Read";
DISPID dispID;
if( FAILED(pDisp->GetIDsOfNames(IID_NULL, &szName, 1,
LOCALE_SYSTEM_DEFAULT, &dispID)) )
return;
// prepare to call Read()...
VARIANT varParam;
V_VT(&varParam) = VT_I4;
V_I4(&varParam) = NumberOfBytesToRead;
DISPPARAMS params;
params.rgvarg = &varParam;
params.rgdispidNamedArgs = NULL;
params.cArgs = 1;
params.cNamedArgs = 0;
VARIANT varChars;
VariantInit(&varChars);
// call Read()...
if( SUCCEEDED(pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD, ¶ms, &varChars, NULL, NULL)) )
{
// process varChars as needed
// should be of type VT_BSTR...
}
VariantClear(&varChars);
}
HRESULT STDMETHODCALLTYPE TMyClassImpl::method(VARIANT value)
{
if( V_VT(&value) & VT_UNKNOWN )
{
IUnknown *pUnk;
if( V_ISBYREF(&value) )
pUnk = V_UNKNOWN(&value);
else
pUnk = V_UNKNOWNREF(&value);
IDispatch *pDisp;
if( SUCCEEDED(pUnk->QueryInterface(IID_IDispatch,
(LPVOID*)&pDisp)) )
{
ProcessTextStream(pDisp);
pDisp->Release();
}
}
else if( V_VT(&value) & VT_DISPATCH )
{
IDispatch *pUnk;
if( V_ISBYREF(&value) )
pDisp = V_DISPATCH(&value);
else
pDisp = V_DISPATCHREF(&value);
ProcessTextStream(pDisp);
}
return S_OK;
}
Gambit
 

Re:getting Delphi to accept a passed-in VBScript 'ByRef Variant' as a file handle or similar

"Remy Lebeau (TeamB)" <XXXX@XXXXX.COM>writes
Quote
For example (untested):
Whoops, forgot this was a Delphi group:
procedure ProcessTextStream(Disp: IDispatch);
var
szName: POleStr;
dispID: TDispID;
varParam, varChars: Variant;
params: DISPPARAMS;
begin
// get the DISPID of the TextStream.Read() method...
szName := 'Read';
if FAILED(Disp.GetIDsOfNames(IID_NULL, POleStrList(@szName), 1,
LOCALE_SYSTEM_DEFAULT, PDispIDList(@dispID))) then Exit;
// prepare to call Read()...
varParam := NumberOfBytesToRead;
params.rgvarg = @varParam;
params.rgdispidNamedArgs := nil;
params.cArgs := 1;
params.cNamedArgs := 0;
// call Read()...
if FAILED(Disp.Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD, params, @varChars, nil, nil)) then Exit;
// process varChars as needed
// should be of type VT_BSTR...
end;
function TMyClassImpl.method(Value: Variant): HResult; stdcall;
begin
ProcessTextStream(Value);
Result := S_OK;
end;
Gambit