Board index » delphi » getting Delphi to accept a passed-in VBScript 'ByRef Variant' as a file handle or similar
axtens
![]() Delphi Developer |
axtens
![]() Delphi Developer |
getting Delphi to accept a passed-in VBScript 'ByRef Variant' as a file handle or similar2006-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. |
Remy Lebeau (TeamB)
![]() Delphi Developer |
2006-10-25 03:11:09 PM
Re:getting Delphi to accept a passed-in VBScript 'ByRef Variant' as a file handle or similar
"axtens" <XXXX@XXXXX.COM>writes
Quoteset o = createobject( "project.class" ) 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'. QuoteWhat I would like to do is to read from that stream. How do I get Delphi 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 |
Remy Lebeau (TeamB)
![]() Delphi Developer |
2006-10-25 03:21:24 PM
Re:getting Delphi to accept a passed-in VBScript 'ByRef Variant' as a file handle or similar
"Remy Lebeau (TeamB)" <XXXX@XXXXX.COM>writes
QuoteFor example (untested): 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 |