Thread overview | |||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 09, 2005 (help) automation on windows | ||||
---|---|---|---|---|
| ||||
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, ¶m, 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 Re: (help) automation on windows | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carlos Santander B. | "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, > ¶m, 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 Re: (help) automation on windows | ||||
---|---|---|---|---|
| ||||
Posted in reply to John C | 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 Re: (help) automation on windows | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carlos Santander B. | "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 Re: (help) automation on windows | ||||
---|---|---|---|---|
| ||||
Posted in reply to John C | 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 Re: (help) automation on windows | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carlos Santander B. | "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 Re: (help) automation on windows | ||||
---|---|---|---|---|
| ||||
Posted in reply to John C | 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 Re: (help) automation on windows | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carlos Santander B. | 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 Re: (help) automation on windows | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carlos Santander B. | "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 Re: (help) automation on windows - COMobjectsSample.zip | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carlos Santander B. Attachments: |
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
|
Copyright © 1999-2021 by the D Language Foundation