JohnOne Posted July 17, 2013 Posted July 17, 2013 (edited) I'm having some trouble with a project, and unsure if I', doing something correctly because of a failure. I think I might be doing something wrong, and want to know if I'm using the titled operation correctly. I'm trying to use getElementById, which is a method of IHTMLDocument6. The structure I'm using to hold the element pointer is IHTMLElement2 type, and I'm trying to determine if they are compatible with queryinterface. This completes without error, and pHTMLElement has a pointer value //IHTMLDocument6 * pHTMLDocument; //IHTMLElement2 * pHTMLElement; hRes = pHTMLDocument->QueryInterface(IID_IHTMLDocument6, (void**)&pHTMLElement); But this fails, and pHTMLElement is 0x00000000 hRes = pHTMLDocument->getElementById(L"default-p_13872472" , &pHTMLElement); I'm not hot on all this COM stuff, but I'm having a pop like, and would appreciate any insight. EDIT: I should note that the return of the latter is S_OK, but pHTMLElement is not a good pointer Edited July 17, 2013 by JohnOne AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans.
trancexx Posted July 17, 2013 Posted July 17, 2013 MSDN says "The IHTMLDocument6 interface inherits from the IDispatch interface but does not have additional members."That means you have to call it using dispatch calling sequence. That would be: pHTMLElement->GetIDsOfNames(...) and then pHTMLElement->Invoke(...). ♡♡♡ . eMyvnE
jaberwacky Posted July 17, 2013 Posted July 17, 2013 Hope this isn't a dumb question but this has me confused> (void**)&pHTMLElement Is that a reference to a pointer to a pointer to a void? If so, then why? Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum?
JohnOne Posted July 17, 2013 Author Posted July 17, 2013 MSDN says "The IHTMLDocument6 interface inherits from the IDispatch interface but does not have additional members." That means you have to call it using dispatch calling sequence. That would be: pHTMLElement->GetIDsOfNames(...) and then pHTMLElement->Invoke(...). Cheers. What I cannot get my head around is why it returns S_OK and not some error value if it's not going to give me a pointer to the interface. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans.
JohnOne Posted July 17, 2013 Author Posted July 17, 2013 Hope this isn't a dumb question but this has me confused> (void**)&pHTMLElement Is that a reference to a pointer to a pointer to a void? If so, then why? As far as I'm aware it's just casting the struct pointer to void** (a pointer to the address of the struct) AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans.
trancexx Posted July 17, 2013 Posted July 17, 2013 Cheers. What I cannot get my head around is why it returns S_OK and not some error value if it's not going to give me a pointer to the interface.You shouldn't be trying to get your head around it. Just do what documentation says....I have written code for different COM objects myself and few times I was asked to extend the definitions by making the interface dual (google the term if not familiar). Sometimes additional functions are just dummies and are there to avoid unhandled exceptions like your code could create otherwise. Also sometimes that's done for forward compatibiliy reasons. ♡♡♡ . eMyvnE
Ascend4nt Posted July 17, 2013 Posted July 17, 2013 But this fails, and pHTMLElement is 0x00000000 hRes = pHTMLDocument->getElementById(L"default-p_13872472" , &pHTMLElement); I'm not hot on all this COM stuff, but I'm having a pop like, and would appreciate any insight. EDIT: I should note that the return of the latter is S_OK, but pHTMLElement is not a good pointer JohnOne, maybe try this: BSTR pElementIdBStr = SysAllocString(L"default-p_13872472"); hRes = pHTMLDocument->getElementById(pElementIdBStr , &pHTMLElement); SysFreeString(pElementIdBStr); That's missing error checking, but that's the basic pattern for using something that takes BSTR parameters. My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code)
jaberwacky Posted July 17, 2013 Posted July 17, 2013 As far as I'm aware it's just casting the struct pointer to void** (a pointer to the address of the struct) Indeed. I don't know why I didn't see this. Thanks! Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum?
JohnOne Posted July 17, 2013 Author Posted July 17, 2013 (edited) JohnOne, maybe try this: BSTR pElementIdBStr = SysAllocString(L"default-p_13872472"); hRes = pHTMLDocument->getElementById(pElementIdBStr , &pHTMLElement); SysFreeString(pElementIdBStr); That's missing error checking, but that's the basic pattern for using something that takes BSTR parameters. Thanks for input Ascend4nt. I had tried that, I was just making my example as minimal as possible. From what I have read,in most cases, using a regular wchar_t* string works just fine for BSTR, and it works just fine for rest of code. I was using IHTMLDocument2 to begin with which never had method getElementById listed, and noticed there were several going up to IHTMLDocument7. IHTMLDocument7 failed, saying it was not compatible with IHTMLElement2, so tried 6, which never failed queryinterface. I'll explain my thinking with what I'm after. In _IE UDFs after using $obj = ObjCreate("InternetExplorer.Application") it just uses $obj.document.getelementbyid("id") So in my minimalistic brain, I thought I could be the same In C++ after Creating an IE instance and getting a pointer to its IWebBrowser2 interface, then the document. I don't know what come over me thinking it would be that easy. I had already gotten a reference to an element id on a page in another fashion and been able to act on it. But when an element is in an iFrame that fashion fails, so I thought this IHTMLDocument6 and its listed getElementById() member might have been the answer. I though that because I don't see _IEGeltElementById() trudging though frames to get at an id in it, it just gets it. Been at it for about 12 hours solid now EDIT: I'm wondering now, if it uses the web pages Javascript getElementById function, but I just tried BSTR FuncStr = L"alert('alert')"; BSTR LangStr = L"javascript"; VARIANT vEmpty = {0}; pParentWnd->execScript(FuncStr, LangStr, &vEmpty); To no effect, pParentWnd is type IHTMLWindow2 Edited July 17, 2013 by JohnOne AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans.
Ascend4nt Posted July 18, 2013 Posted July 18, 2013 I haven't messed with IE embedding in GUI's, but I would be certain to make sure to test with BSTR's that use SysAllocString, or Microsoft _bstr_t class, since the 1st 4 bytes of a BSTR are a length prefix. I assume that, if the COM calls do in fact work without that prefix (and you should verify this with debugging), there is probably a safety measure in place to decide if the length is valid. Since BSTR's are null-terminated, an invoked function can look first for a null-terminator and then decide if the first 4 bytes are valid characters if it doesn't match the actual length. Whatever the case may be, I haven't tested this myself as I've always used SysAllocString. As far as embedding the IE object and interacting with it, the links here seem a good place to start My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code)
JohnOne Posted July 18, 2013 Author Posted July 18, 2013 Thanks for your assistance, I think it probably is something to do with the strings. I'm almost at a milestone point where I can taste success, I have drilled into the iframe and gotten a reference to an element in it (it is not cross domain iframe). But having trouble acting on that element. When I used SysAllocString and SysFreeString, it just error in a different place with different code (access violation x0000005 thing) in comutil.h inline _variant_t::_variant_t() throw() { ::VariantInit(this); // <========= errord out here } Thing is, it's breaking out in different places. I probably just need to get some sleep. Cheers pal. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now