Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.


Welcome, Guest
Guest Settings
Help

Thread: How pass optional parameters to OLE method?


This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 4 - Last Post: Dec 6, 2017 5:17 AM Last Post By: Greg Reese Threads: [ Previous | Next ]
Greg Reese

Posts: 85
Registered: 7/15/05
How pass optional parameters to OLE method?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 5, 2017 8:33 AM
How do you pass optional parameters to a method of an OLE object? For example:

Variant app = CreateOleObject( L"Word.Application" );
Variant documents = app.OlePropertyGet( L"Documents" );
Variant document = documents.OleFunction( L"Open", WideString("file.docx") );


The Open method of the Documents Word object is documented at
[Open|https://msdn.microsoft.com/en-us/vba/word-vba/articles/documents-open-method-word]

The only required parameter is the file name (file.docx in the example above). If I also wanted to open the file as read-only, i.e., ReadOnly=True in the documentation for Open, how should I do that?

Thanks.
Greg Reese
Remy Lebeau (Te...


Posts: 8,950
Registered: 12/23/01
Re: How pass optional parameters to OLE method?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 5, 2017 10:03 AM   in response to: Greg Reese in response to: Greg Reese
Greg Reese wrote:

How do you pass optional parameters to a method of an OLE object?

An optional parameter is passed as a Variant whose vt field is set to
VT_ERROR and sCode field is set to DISP_E_PARAMNOTFOUND. The RTL has
an EmptyParam() function that produces such a Variant for you, eg:

Variant document = documents.OleFunction( L"Open",
WideString("file.docx"), EmptyParam(), true);


In Delphi, there is an alternative syntax for setting named parameters
directly, eg:

document := documents.Open(FileName := 'file.docx', ReadOnly := True);


But, to do that in C++, you have to call IDispatch::Invoke() directly,
eg:

LPOLESTR szNames[3] = {L"Open", L"FileName", L"ReadOnly"};
DISPID dispids[3];
 
OleCheck(documents->GetIDsOfNames(IID_NULL, szNames, 3,
LOCALE_USER_DEFAULT, dispids));
 
WideString wFilename("file.docx");
 
VARIANT rgvargs[2];
DISPID rgNamedArgs[2];
 
// OLE parameters are passed to IDispatch::Invoke() in reverse order!
rgNamedArgs[0] = dispids[2];
rgvarg[0].vt = VT_BOOL;
rgvarg[0].boolVal = VARIANT_TRUE;
rgNamedArgs[1] = dispids[1];
rgvarg[1].vt = VT_BSTR;
rgvarg[1].bstrVal = wFilename.c_bstr();
 
DISPPARAMS dispparams; 
dispparams.rgvarg = rgvargs;
dispparams.rgdispidNamedArgs = rgNamedArgs;
dispparams.cArgs = 2;
dispparams.cNamedArgs = 2;
 
VARIANT VarResult;
EXCEPINFO ExcepInfo;
UINT uArgErr;
 
OleCheck(documents->Invoke(
    dispids[0],
    IID_NULL,
    LOCALE_USER_DEFAULT,
    DISPATCH_METHOD,
    &dispparams, &VarResult, &ExcepInfo, &uArgErr));
 
document = VarResult;


--
Remy Lebeau (TeamB)
Greg Reese

Posts: 85
Registered: 7/15/05
Re: How pass optional parameters to OLE method?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 5, 2017 12:45 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
How do you pass optional parameters to a method of an OLE object?

An optional parameter is passed as a Variant whose vt field is set to
VT_ERROR and sCode field is set to DISP_E_PARAMNOTFOUND. The RTL has
an EmptyParam() function that produces such a Variant for you, eg:

What header is EmptyParam() in? The only declaration I see is in Vcl.OleCtrls.hpp, and I have a FireMonkey program. I did find Variant::NoParam() and passing it to VarIsEmptyParam results in true, so it seems that will work instead of EmptyParam().
Remy Lebeau (Te...


Posts: 8,950
Registered: 12/23/01
Re: How pass optional parameters to OLE method?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 5, 2017 3:09 PM   in response to: Greg Reese in response to: Greg Reese
Greg Reese wrote:

What header is EmptyParam() in?

The only declaration I see is in Vcl.OleCtrls.hpp

That is the one. Though I don't know why Borland/Embarcadero did that,
since EmptyParam() is implemented in the RTL's System.Variants unit,
but is omitted from being declared in the System.Variants.hpp header
file.

I have a FireMonkey program.

You should have said so to begin with. It makes a difference, since
you can't use VCL in a FMX project (without a 3rd party hack).

I did find Variant::NoParam() and passing it to VarIsEmptyParam
results in true, so it seems that will work instead of EmptyParam().

Yes, that will work. Variant::NoParam() creates the same type of
VARIANT that EmptyParam() does.

--
Remy Lebeau (TeamB)
Greg Reese

Posts: 85
Registered: 7/15/05
Re: How pass optional parameters to OLE method?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 6, 2017 5:17 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Thanks Remy.
Greg Reese
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02