Sign in to follow this  
Followers 0
lod3n

Dual Embedded IE objects breaks object focusing?

12 posts in this topic

Take a look at the following code demonstrating the problem. It loads two embedded IE controls, pointing them both at Google, but they could go anywhere. I've tried it with super simple local files also. Like:

<input><br><input>
You'll find that after it loads, and you press tab, the focus moves around the form elements in the second embedded object as expected.

The problem arises when you click on the first form and press tab. It changes focus to the second one and moves around in there again. Very confusing. I am trying to develop an utility that lets two sites communicate with each other by running interference between them, but this issue is tripping me up...

#include <GUIConstants.au3>
#include <IE.au3>

_IEErrorHandlerRegister ()

$winwidth = @DesktopWidth-100
$winheight = @DesktopHeight-100
$browserwidth = $winwidth - 20
$browserheight = ($winheight/2)-20

GUICreate("Embedded Web control Test", $winwidth, $winheight,50,50,$WS_OVERLAPPEDWINDOW + $WS_VISIBLE + $WS_CLIPSIBLINGS+$WS_CLIPCHILDREN)
        
$oIE = _IECreateEmbedded ()
$GUIActiveX = GUICtrlCreateObj($oIE, 10, 10, $browserwidth, $browserheight)
;GUICtrlCreateObj ( $ObjectVar, left, top [, width [, height ]] )


$oIE2 = _IECreateEmbedded ()
$GUIActiveX2 = GUICtrlCreateObj($oIE2, 10, $browserheight+30, $browserwidth, $browserheight)


GUISetState()       ;Show GUI

_IENavigate ($oIE, "http://www.google.com")
_IENavigate ($oIE2, "http://www.google.com")
;~ _IENavigate ($oIE, @scriptdir&"\simple.htm")
;~ _IENavigate ($oIE2, @scriptdir&"\simple.htm")

; Waiting for user to close the window
While 1
    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE
            ExitLoop
    EndSelect
WEnd

GUIDelete()

Exit

[font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font]

Share this post


Link to post
Share on other sites



Anyone have a theory?

Well, I tested this and reproduced it when you first posted it... I'm short on value to add.

My theory, not surprisingly, is there is an issue with keyboard focus. My thought was that the top-level GUI window was treating the first embedded window as a single control, intercepted the Tab and passed control to the second control. Somehow it allows the second control to manage keyboard focus but not the first.

It is interesting that if I use the following code to force focus to the query field in the first embedded window, the Tab key is no honored at all... focus stays in that control:

$oForm = _IEFormGetObjByName($oIE, "f")
$oInput = _IEFormElementGetObjByName($oForm, "q")
_IEAction($oInput, "focus")

My suggestion would be to try another embedded window other than IE to see if the behaviour is consistent. If so, I suspect an issue with keyboard focus with GUI embedded controls or child windows.

Dale


Free Internet Tools: DebugBar, AutoIt IE Builder, HTTP UDF, MODIV2, IE Developer Toolbar, IEDocMon, Fiddler, HTML Validator, WGet, curl

MSDN docs: InternetExplorer Object, Document Object, Overviews and Tutorials, DHTML Objects, DHTML Events, WinHttpRequest, XmlHttpRequest, Cross-Frame Scripting, Office object model

Automate input type=file (Related)

Alternative to _IECreateEmbedded? better: _IECreatePseudoEmbedded  Better Better?

IE.au3 issues with Vista - Workarounds

SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y Doesn't work needs to be ripped out of the troubleshooting lexicon. It means that what you tried did not produce the results you expected. It begs the questions 1) what did you try?, 2) what did you expect? and 3) what happened instead?

Reproducer: a small (the smallest?) piece of stand-alone code that demonstrates your trouble

Share this post


Link to post
Share on other sites

Good theory. However, it seems to be tied to IE controls specifically. Below is a test that replaces the IE objects with rich text objects, and the problem does not occur:

#include <GUIConstants.au3>
#include <IE.au3>

_IEErrorHandlerRegister ()

$winwidth = @DesktopWidth-100
$winheight = @DesktopHeight-100
$browserwidth = $winwidth - 20
$browserheight = ($winheight/2)-20

GUICreate("Embedded Richtext control Test", $winwidth, $winheight,50,50,$WS_OVERLAPPEDWINDOW + $WS_VISIBLE + $WS_CLIPSIBLINGS+$WS_CLIPCHILDREN)
       
$oIE = ObjCreate("RICHTEXT.RichtextCtrl.1")
$GUIActiveX = GUICtrlCreateObj($oIE, 10, 10, $browserwidth, $browserheight)
;GUICtrlCreateObj ( $ObjectVar, left, top [, width [, height ]] )


$oIE2 = ObjCreate("RICHTEXT.RichtextCtrl.1")
$GUIActiveX2 = GUICtrlCreateObj($oIE2, 10, $browserheight+30, $browserwidth, $browserheight)


GUISetState()       ;Show GUI

;~ _IENavigate ($oIE, "http://www.google.com")
;~ _IENavigate ($oIE2, "http://www.google.com")
;~ _IENavigate ($oIE, @scriptdir&"\simple.htm")
;~ _IENavigate ($oIE2, @scriptdir&"\simple.htm")

; Waiting for user to close the window
While 1
    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE
            ExitLoop
    EndSelect
WEnd

GUIDelete()

Exit

[font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font]

Share this post


Link to post
Share on other sites

Does the behavior change if you use just one embeded IE control? Or 3?

Dale


Free Internet Tools: DebugBar, AutoIt IE Builder, HTTP UDF, MODIV2, IE Developer Toolbar, IEDocMon, Fiddler, HTML Validator, WGet, curl

MSDN docs: InternetExplorer Object, Document Object, Overviews and Tutorials, DHTML Objects, DHTML Events, WinHttpRequest, XmlHttpRequest, Cross-Frame Scripting, Office object model

Automate input type=file (Related)

Alternative to _IECreateEmbedded? better: _IECreatePseudoEmbedded  Better Better?

IE.au3 issues with Vista - Workarounds

SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y Doesn't work needs to be ripped out of the troubleshooting lexicon. It means that what you tried did not produce the results you expected. It begs the questions 1) what did you try?, 2) what did you expect? and 3) what happened instead?

Reproducer: a small (the smallest?) piece of stand-alone code that demonstrates your trouble

Share this post


Link to post
Share on other sites

No matter how many you use, the last one bound to the gui is the one that retains control.

I did some research today, and I hear echos of this problem in other projects. One that seemed highly relevant was the IETab project for Firefox, which I think you've run into before on this board.

It seems that they had a problem similar to mine, but got it sorted out. I can't yet figure out exactly how they did it, but I my gut feeling says it lies in sending WM_SETFOCUS and WM_KILLFOCUS messages to the controls. I've experimented with this to no avail. My kung fu falters at that skill level.

Apparently, when an embedded IE ActiveX starts, it directly hooks into the keyboard (and mouse maybe) and has no way of telling when it loses focus. Something external has to notify it to stop listening to the keyboard. I will keep looking into it, as the problem is really interesting, and I really need it to work.

Let me know if you have any more good theories. :P


[font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font]

Share this post


Link to post
Share on other sites

My suspicion is that IE is not the cause of whatever trouble you are having and I suggest you try to find another embedded object that demonstrates the same issue. I know that you tried a rich text control and could not demonstrate it there, but if you can find another that does you'll have better luck getting the attention of the devs to look at the GUI control and potential keyboard focus issues.

Dale


Free Internet Tools: DebugBar, AutoIt IE Builder, HTTP UDF, MODIV2, IE Developer Toolbar, IEDocMon, Fiddler, HTML Validator, WGet, curl

MSDN docs: InternetExplorer Object, Document Object, Overviews and Tutorials, DHTML Objects, DHTML Events, WinHttpRequest, XmlHttpRequest, Cross-Frame Scripting, Office object model

Automate input type=file (Related)

Alternative to _IECreateEmbedded? better: _IECreatePseudoEmbedded  Better Better?

IE.au3 issues with Vista - Workarounds

SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y Doesn't work needs to be ripped out of the troubleshooting lexicon. It means that what you tried did not produce the results you expected. It begs the questions 1) what did you try?, 2) what did you expect? and 3) what happened instead?

Reproducer: a small (the smallest?) piece of stand-alone code that demonstrates your trouble

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

So a little progress. I found this page:

http://blogs.msdn.com/calvin_hsia/archive/.../22/441895.aspx

which seems to be talking about this exact problem and, oddly enough, comparing it to the rich text control. The dude in question seems to be a MS developer for FoxPro, and he implemented a solution which I don't understand.

What I did do is fire up Winspector, and take a look at the window messages on the sample app. I modified it and put a lot of sleeps into it, so I could see what was doing what. What I'm seeing is a WM_WINDOWPOSCHANGING event followed by a WM_WINDOWPOSCHANGED event sent to the window when the GUICtrlCreateObj runs, but for each object. Perhaps someone better than I at this stuff can derive more information out of the following than I can:

WM_WINDOWPOSCHANGING
        hwnd: 0x00590be2 (this handle corresponds to the IE control's handle)
        hwndInsertAfter: HWND_TOP
        Position: 0, 0
        Size: 0, 0
        SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE | SWP_SHOWWINDOW
        Message Sent
        Time: 15:20:10.0421

    WM_WINDOWPOSCHANGED
        hwnd: 0x00590be2
        hwndInsertAfter: HWND_TOP
        Position: 0, 0
        Size: 1032, 362
        SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE | SWP_SHOWWINDOW
        Message Sent
        Time: 15:20:10.0421

I tried using sending these same flags to the first control using SetWindowPos from user32.dll as per quaizywabbit, but to no avail. If anyone has any ideas I'd greatly appreciate it.

Edited by lod3n

[font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font]

Share this post


Link to post
Share on other sites

An update. I tried going another route, using a second .exe that creates an IE control with _IECreateEmbedded(), and then moving that window over the primary gui, and then using _IEAttach() to get the IE object and control it.

The problem is that I seem to be triggering some sort of active cross site security scripting protection, and I can't eve use _IENavigate, because it gets hung up on the error.

It's really odd: I tried peeking in to see what was happening, by just calling $oIE.navigate($url) and then ConsoleWriting $oIE.document.readyState every 100 ms, and it says loading, loading loading, Security Error! So it has privleges to read the attribute, and then it loses it.

DaleHohm, FYI, in this scenario, $IEComErrorNumber does NOT get set to 169, it's some huge negative number, so _IELoadWait() just hangs. I modified and used a copy of IE.au3 that didn't check for a value of 169, which let _IELoadWait() return, but that didn't fix the problem. The security issue still blocks me from doing anything useful with the control.

I am literally pulling my hair out on this. How the hell does Firefox manage it with IETab? I remember reading some blurb about reusing the control, something about a pool of controls or something. But that doesn't make sense either, unless there is some way to swap the objects around...


[font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font]

Share this post


Link to post
Share on other sites

If anyone has been feverishly following this saga, I've posted a hack that accomplishes my intended goal. It kind of sucks that I can't do it the way I wanted, but what'r ya gonna do?

http://www.autoitscript.com/forum/index.php?showtopic=32804

BTW, if anyone figures out how to do this using _IECreateEmbedded() instead, please let me know.


[font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font]

Share this post


Link to post
Share on other sites

I'm using dual controles both embedded.

I'm not sure how you have odne this and only briefly looked at the code.

In my case I used them to hide what is going on in the first ie window. So I hide and dissable the first ie controle and then show a second one with a progress bar done in javascript. After I extract all the data I need from the first window I then generate another page and load it into the the first ie contole. Then I hide the second controle and unhide the first one. It makes transitions between pages easier.

Also if you hide the window and also disable it then you wont hear clicks as you are loading your pages. Now judging from your code it looks like you were running something side by side(I really only looked quickly) but you could use tabs and then use the hide disable stuff I was talking about.

anyway I hope you find that usefull.

Share this post


Link to post
Share on other sites

Actually, my own project is in fact using tabs, but I wanted to produce a code sample that easily shows the issue I'm experiencing. I've done something similar to what you describe in some cases, but it really is a workaround, not a fix, and I like to find the fix when it exists. To a fault really. Even when it's no longer in my own best interest to continue burning hours on it. I guess I'm a little O.C. in that regard.


[font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font]

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0