Jump to page: 1 2 3
Thread overview
(help) automation on windows
Mar 09, 2005
John C
Mar 10, 2005
John C
Mar 10, 2005
John C
Mar 12, 2005
John C
Mar 13, 2005
John C
Mar 13, 2005
John C
Apr 07, 2005
Robert M. Münch
Mar 13, 2005
jicman
Re: (help) automation on windows - COMobjectsSample.zip
Mar 12, 2005
jicman
Apr 19, 2010
Petr
Mar 13, 2005
J C Calvarese
Mar 13, 2005
jicman
March 09, 2005
I fond some reference on how to do late binding and automation (it's cool when you know the right terms... at least I hope they're right...), so I have this D code right now:

//----------------------------------------
void main()
{
    wchar * prog="InternetExplorer.Application";
    wchar * member="Visible";

    LCID defaultLCID = GetUserDefaultLCID();

    HRESULT hr = CoInitialize(null);
    printf("1:%d\n",hr);

    CLSID bu;
    hr=CLSIDFromProgID(prog, &bu);
    printf("2:%d\n",hr);

    IDispatch* pIDispatch;
    hr = CoCreateInstance(&bu, null, CLSCTX_SERVER, &IID_IDispatch,cast (void**)&pIDispatch);
    printf("3:%d\n",hr);

    DISPID dispid;
    hr = pIDispatch.GetIDsOfNames(cast(REFIID) &IID_NULL, &member, 1, defaultLCID, &dispid);
    printf("4:%d\n",hr);

    VARIANTARG myArg;
    myArg.n1.n2.vt = VT_I4|VT_BYREF;
    myArg.n1.n2.n3.lVal = 1;

    DISPPARAMS param;
    param.cArgs=1;
    param.rgvarg=&myArg;

    VARIANT * result=new VARIANT;

    hr = pIDispatch.Invoke(dispid, cast(REFIID) &IID_NULL, defaultLCID, DISPATCH_METHOD,
        &param, result, null, null);
    printf("5:%d\n",hr);

    //Sleep(2000);

    CoUninitialize();
}
//----------------------------------------

The idea is to do something like (pseudo-code):

app=new InternetExplorer.Application();
app.Visible=1; //or app.Visible(1), I don't know

But the call to GetIDsOfNames (between printfs 3 and 4) produces an access violation. Any ideas?

The C++ version does a bit better: the Invoke call returns -2147024809, whatever that means.

(BTW, I'm using the core32 library for all that IDispatch stuff, even if the one I have is a bit outdated)

_______________________
Carlos Santander Bernal
March 09, 2005
"Carlos Santander B." <csantander619@gmail.com> wrote in message news:d0nuj0$eds$1@digitaldaemon.com...
>I fond some reference on how to do late binding and automation (it's cool when you know the right terms... at least I hope they're right...), so I have this D code right now:
>
> //----------------------------------------
> void main()
> {
>     wchar * prog="InternetExplorer.Application";
>     wchar * member="Visible";
>
>     LCID defaultLCID = GetUserDefaultLCID();
>
>     HRESULT hr = CoInitialize(null);
>     printf("1:%d\n",hr);
>
>     CLSID bu;
>     hr=CLSIDFromProgID(prog, &bu);
>     printf("2:%d\n",hr);
>
>     IDispatch* pIDispatch;
>     hr = CoCreateInstance(&bu, null, CLSCTX_SERVER, &IID_IDispatch,cast
> (void**)&pIDispatch);
>     printf("3:%d\n",hr);
>
>     DISPID dispid;
>     hr = pIDispatch.GetIDsOfNames(cast(REFIID) &IID_NULL, &member, 1,
> defaultLCID, &dispid);
>     printf("4:%d\n",hr);

If you create a WebBrowser object instead, with IID_IWebBrowser2, you should be able to directly call put_Visible(VARIANT_TRUE).

>
>     VARIANTARG myArg;
>     myArg.n1.n2.vt = VT_I4|VT_BYREF;
>     myArg.n1.n2.n3.lVal = 1;
>
>     DISPPARAMS param;
>     param.cArgs=1;
>     param.rgvarg=&myArg;
>
>     VARIANT * result=new VARIANT;
>
>     hr = pIDispatch.Invoke(dispid, cast(REFIID) &IID_NULL, defaultLCID,
> DISPATCH_METHOD,
>         &param, result, null, null);
>     printf("5:%d\n",hr);
>
>     //Sleep(2000);
>
>     CoUninitialize();
> }
> //----------------------------------------
>
> The idea is to do something like (pseudo-code):
>
> app=new InternetExplorer.Application();
> app.Visible=1; //or app.Visible(1), I don't know
>
> But the call to GetIDsOfNames (between printfs 3 and 4) produces an access violation. Any ideas?
>
> The C++ version does a bit better: the Invoke call returns -2147024809, whatever that means.
>
> (BTW, I'm using the core32 library for all that IDispatch stuff, even if the one I have is a bit outdated)
>
> _______________________
> Carlos Santander Bernal


March 09, 2005
John C wrote:
> 
> 
> If you create a WebBrowser object instead, with IID_IWebBrowser2, you should be able to directly call put_Visible(VARIANT_TRUE).
> 
> 

I guess I should've said that: it's supposed to be like that. I mean, if later I want to replace "InternetExplorer.Application" with something else, that's all I should change, without having to worry about GUIDs. Same for "Visible". The goal is late binding. But thanks, though.

_______________________
Carlos Santander Bernal
March 10, 2005
"Carlos Santander B." <csantander619@gmail.com> wrote in message news:d0o2ht$i82$1@digitaldaemon.com...
> John C wrote:
>>
>>
>> If you create a WebBrowser object instead, with IID_IWebBrowser2, you should be able to directly call put_Visible(VARIANT_TRUE).
>>
>>
>
> I guess I should've said that: it's supposed to be like that. I mean, if later I want to replace "InternetExplorer.Application" with something else, that's all I should change, without having to worry about GUIDs. Same for "Visible". The goal is late binding. But thanks, though.
>
> _______________________
> Carlos Santander Bernal

Could this line be the source of the problem?

    IDispatch* pIDispatch;

Change it to

    IDispatch pIDispatch;

It worked for me. By the way, when you call Invoke, try using "DISPATCH_PROPERTYPUT" instead of "DISPATCH_METHOD".

Hope this helps.


March 10, 2005
John C wrote:
> 
> Could this line be the source of the problem?
> 
>     IDispatch* pIDispatch;
> 
> Change it to
> 
>     IDispatch pIDispatch;
> 
> It worked for me. By the way, when you call Invoke, try using "DISPATCH_PROPERTYPUT" instead of "DISPATCH_METHOD".
> 
> Hope this helps. 
> 
> 

Thanks, that worked. Partially. "Invoke" returns -1073741819. It doesn't matter if I use DISPATCH_METHOD or DISPATCH_PROPERTYPUT.

Regarding that, is there a way to know (automagically, programmatically) when to use DISPATCH_PROPERTYPUT, DISPATCH_METHOD, DISPATCH_PROPERTYGET or DISPATCH_PROPERTYPUTREF? Maybe by the result of calling GetIDsOfNames?

_______________________
Carlos Santander Bernal
March 10, 2005
"Carlos Santander B." <csantander619@gmail.com> wrote in message news:d0o9va$pgh$1@digitaldaemon.com...
> John C wrote:
>>
>> Could this line be the source of the problem?
>>
>>     IDispatch* pIDispatch;
>>
>> Change it to
>>
>>     IDispatch pIDispatch;
>>
>> It worked for me. By the way, when you call Invoke, try using "DISPATCH_PROPERTYPUT" instead of "DISPATCH_METHOD".
>>
>> Hope this helps.
>
> Thanks, that worked. Partially. "Invoke" returns -1073741819. It doesn't matter if I use DISPATCH_METHOD or DISPATCH_PROPERTYPUT.
>
> Regarding that, is there a way to know (automagically, programmatically) when to use DISPATCH_PROPERTYPUT, DISPATCH_METHOD, DISPATCH_PROPERTYGET or DISPATCH_PROPERTYPUTREF? Maybe by the result of calling GetIDsOfNames?

Conveniently, IDispatch has a GetTypeInfo method that returns an ITypeInfo interface. ITypeInfo::GetFuncDesc returns a FUNCDESC structure containing an INVOKEKIND enumeration, which is defined as follows:

    typedef enum tagINVOKEKIND {
       INVOKE_FUNC = DISPATCH_METHOD,
       INVOKE_PROPERTYGET = DISPATCH_PROPERTYGET,
       INVOKE_PROPERTYPUT = DISPATCH_PROPERTYPUT,
       INVOKE_PROPERTYPUTREF = DISPATCH_PROPERTYPUTREF
    } INVOKEKIND;

That looks like what you need.

Or you could try calling Invoke() with each flag in turn until you get S_OK. If you don't get S_OK after trying all flags, then throw an exception saying the method or property doesn't exist. I think this how scripting languages do late binding for automation objects.

By the way, MSDN says "when you use IDispatch::Invoke() with DISPATCH_PROPERTYPUT you have to specially initialize the cNamedArgs and rgdispidNamedArgs elements of your DISPPARAMS structure with the following:

    DISPID dispidNamed = DISPID_PROPERTYPUT;
    dispparams.cNamedArgs = 1;
    dispparams.rgdispidNamedArgs = &dispidNamed;"

I found an example on Microsoft's support site (it's for Excel, but you can adapt it for other automation objects): http://support.microsoft.com/kb/181473/EN-US/

>
> _______________________
> Carlos Santander Bernal


March 10, 2005
John C wrote:
> 
> Conveniently, IDispatch has a GetTypeInfo method that returns an ITypeInfo interface. ITypeInfo::GetFuncDesc returns a FUNCDESC structure containing an INVOKEKIND enumeration, which is defined as follows:
> 
>     typedef enum tagINVOKEKIND {
>        INVOKE_FUNC = DISPATCH_METHOD,
>        INVOKE_PROPERTYGET = DISPATCH_PROPERTYGET,
>        INVOKE_PROPERTYPUT = DISPATCH_PROPERTYPUT,
>        INVOKE_PROPERTYPUTREF = DISPATCH_PROPERTYPUTREF
>     } INVOKEKIND;
> 
> That looks like what you need.
> 
> Or you could try calling Invoke() with each flag in turn until you get S_OK. If you don't get S_OK after trying all flags, then throw an exception saying the method or property doesn't exist. I think this how scripting languages do late binding for automation objects.
> 
> By the way, MSDN says "when you use IDispatch::Invoke() with DISPATCH_PROPERTYPUT you have to specially initialize the cNamedArgs and rgdispidNamedArgs elements of your DISPPARAMS structure with the following:
> 
>     DISPID dispidNamed = DISPID_PROPERTYPUT;
>     dispparams.cNamedArgs = 1;
>     dispparams.rgdispidNamedArgs = &dispidNamed;"
> 
> I found an example on Microsoft's support site (it's for Excel, but you can adapt it for other automation objects): http://support.microsoft.com/kb/181473/EN-US/
> 
> 
>>_______________________
>>Carlos Santander Bernal 
> 
> 
> 

It works! Thanks, again!

_______________________
Carlos Santander Bernal
March 12, 2005
Carlos Santander B. wrote:
> 
> It works! Thanks, again!
> 

(progress update and another request for help)

PROPERTYGET and PROPERTYPUT work. PROPERTYPUTREF, I don't know, because I haven't tried and I don't know how to try. METHOD without parameters also works. With parameters, however, it's not as good.

So far, this code works (adapted from Justin's code in http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/18805, I hope the URL is ok):

//----------------------------------------------------------------
    AXO ie=new AXO("InternetExplorer.Application");

    try
    {
        VARIANTARG a1, a2, a3, a4;
        a1.n1.n2.vt=20;
        a2.n1.n2.vt=6008;
        a3.n1.n2.vt=0;
        a4.n1.n2.vt=17;

        VARIANTARG myArg;
        myArg.n1.n2.vt = VT_BSTR;
        myArg.n1.n2.n3.bstrVal = "about:blank";
        ie.call("Navigate",a4,a3,a2,a1,myArg);

        myArg.n1.n2.vt = VT_UI4;
        myArg.n1.n2.n3.lVal = 850;
        ie.set("Width",myArg);
        myArg.n1.n2.n3.lVal = 710;
        ie.set("Height",myArg);
        myArg.n1.n2.n3.lVal = 10;
        ie.set("Top",myArg);
        myArg.n1.n2.n3.lVal = 10;
        ie.set("Left",myArg);

        myArg.n1.n2.vt = VT_BOOL;
        myArg.n1.n2.n3.boolVal = 0;
        ie.set("ToolBar",myArg);
        ie.set("MenuBar",myArg);
        ie.set("StatusBar",myArg);
        myArg.n1.n2.n3.boolVal = 1;
        ie.set("Visible",myArg);

        VARIANT tmp = ie.get("Visible");
        bool isVisible = cast(bool) tmp.n1.n2.n3.boolVal;
    }
    finally
        ie.call("Quit");
//----------------------------------------------------------------

Works, except for the Navigate call. Going through the parameters I found their VARTYPEs, so that's why I set them, but I have no idea what they should receive. Also, I'm aware some methods are optional (Navigate has 4, I assume the only required is the URL), but only passing one doesn't work either.

So, again, some help would be nice.

_______________________
Carlos Santander Bernal
March 12, 2005
"Carlos Santander B." <csantander619@gmail.com> wrote in message news:d0tjun$15ie$1@digitaldaemon.com...
> Carlos Santander B. wrote:
>>
>> It works! Thanks, again!
>>
>
> (progress update and another request for help)
>
> PROPERTYGET and PROPERTYPUT work. PROPERTYPUTREF, I don't know, because I haven't tried and I don't know how to try. METHOD without parameters also works. With parameters, however, it's not as good.
>
> So far, this code works (adapted from Justin's code in http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/18805, I hope the URL is ok):
>
> //----------------------------------------------------------------
>     AXO ie=new AXO("InternetExplorer.Application");
>
>     try
>     {
>         VARIANTARG a1, a2, a3, a4;
>         a1.n1.n2.vt=20;
>         a2.n1.n2.vt=6008;
>         a3.n1.n2.vt=0;
>         a4.n1.n2.vt=17;
>
>         VARIANTARG myArg;
>         myArg.n1.n2.vt = VT_BSTR;
>         myArg.n1.n2.n3.bstrVal = "about:blank";
>         ie.call("Navigate",a4,a3,a2,a1,myArg);
>
>         myArg.n1.n2.vt = VT_UI4;
>         myArg.n1.n2.n3.lVal = 850;
>         ie.set("Width",myArg);
>         myArg.n1.n2.n3.lVal = 710;
>         ie.set("Height",myArg);
>         myArg.n1.n2.n3.lVal = 10;
>         ie.set("Top",myArg);
>         myArg.n1.n2.n3.lVal = 10;
>         ie.set("Left",myArg);
>
>         myArg.n1.n2.vt = VT_BOOL;
>         myArg.n1.n2.n3.boolVal = 0;
>         ie.set("ToolBar",myArg);
>         ie.set("MenuBar",myArg);
>         ie.set("StatusBar",myArg);
>         myArg.n1.n2.n3.boolVal = 1;
>         ie.set("Visible",myArg);
>
>         VARIANT tmp = ie.get("Visible");
>         bool isVisible = cast(bool) tmp.n1.n2.n3.boolVal;
>     }
>     finally
>         ie.call("Quit");
> //----------------------------------------------------------------
>
> Works, except for the Navigate call. Going through the parameters I found their VARTYPEs, so that's why I set them, but I have no idea what they should receive. Also, I'm aware some methods are optional (Navigate has 4, I assume the only required is the URL), but only passing one doesn't work either.
>
> So, again, some help would be nice.

Documentation on this stuff is sparse (as you've no doubt gathered). But if I remember correctly, the parameters for Navigate() are as follows:

    url [VT_BSTR, bstrVal]
    flags [VT_UI4, lVal (see BrowserNavConstants)]
    targetFrameName [VT_BSTR, bstrVal]
    postData [VT_ARRAY | VT_VARIANT of VT_UI1, parray]
    headers [VT_BSTR, bstrVal]
    cancel [VT_BOOL | VT_BYREF, pboolVal]

(Note that "cancel" isn't available as a parameter in early binding.)

Without seeing the code behind your set() methods, it's difficult to know why it's failing. Your rgvarg array's elements have to be in reverse order, but I think you're doing that anyway.

>
> _______________________
> Carlos Santander Bernal


March 12, 2005
Carlos,

I am very interested in this project.  Here is a JScript program that does a lot with COMs.  It uses IE, Excel and MySQL COM calls.  I wish I can help you more but I am out of the country on business.  I will keep on watching the posts on this subject.  Thanks.

josé


Carlos Santander B. says...
>
>Carlos Santander B. wrote:
>> 
>> It works! Thanks, again!
>> 
>
>(progress update and another request for help)
>
>PROPERTYGET and PROPERTYPUT work. PROPERTYPUTREF, I don't know, because I haven't tried and I don't know how to try. METHOD without parameters also works. With parameters, however, it's not as good.
>
>So far, this code works (adapted from Justin's code in http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/18805, I hope the URL is ok):
>
>//----------------------------------------------------------------
>     AXO ie=new AXO("InternetExplorer.Application");
>
>     try
>     {
>         VARIANTARG a1, a2, a3, a4;
>         a1.n1.n2.vt=20;
>         a2.n1.n2.vt=6008;
>         a3.n1.n2.vt=0;
>         a4.n1.n2.vt=17;
>
>         VARIANTARG myArg;
>         myArg.n1.n2.vt = VT_BSTR;
>         myArg.n1.n2.n3.bstrVal = "about:blank";
>         ie.call("Navigate",a4,a3,a2,a1,myArg);
>
>         myArg.n1.n2.vt = VT_UI4;
>         myArg.n1.n2.n3.lVal = 850;
>         ie.set("Width",myArg);
>         myArg.n1.n2.n3.lVal = 710;
>         ie.set("Height",myArg);
>         myArg.n1.n2.n3.lVal = 10;
>         ie.set("Top",myArg);
>         myArg.n1.n2.n3.lVal = 10;
>         ie.set("Left",myArg);
>
>         myArg.n1.n2.vt = VT_BOOL;
>         myArg.n1.n2.n3.boolVal = 0;
>         ie.set("ToolBar",myArg);
>         ie.set("MenuBar",myArg);
>         ie.set("StatusBar",myArg);
>         myArg.n1.n2.n3.boolVal = 1;
>         ie.set("Visible",myArg);
>
>         VARIANT tmp = ie.get("Visible");
>         bool isVisible = cast(bool) tmp.n1.n2.n3.boolVal;
>     }
>     finally
>         ie.call("Quit");
>//----------------------------------------------------------------
>
>Works, except for the Navigate call. Going through the parameters I found their VARTYPEs, so that's why I set them, but I have no idea what they should receive. Also, I'm aware some methods are optional (Navigate has 4, I assume the only required is the URL), but only passing one doesn't work either.
>
>So, again, some help would be nice.
>
>_______________________
>Carlos Santander Bernal


« First   ‹ Prev
1 2 3