I am experiencing a most peculiar behaviour with
regards to a window.onresize event handler I've placed
onto Internet Explorer:
IF I resize IE (by dragging a border) AND the mouse is
still down when the handler fires (even with a
window.setTimeout interposed) AND I pop up a UI
element within the handler, then AFTER I dismiss the
MsgBox (or popup), IE's window will revert to its
previous size.
C'mon Csaba, you will say, you are just asking for
trouble because the mouse is down and focus is being
stolen from IE (sorta, kinda, maybe?), the mouse
action cannot be completed and IE is clever enough to
realize this and revert itself to its previous setting.
So what's the big deal?
Well, the thing is, that it also happens if there is no
MsgBox, but instead I create another ie (not even
visible) and immediately dismiss the new ie! In other
words, just the brazen act of creating a new ie will
revert the old ie's size. And that is a big deal
because I want to use that new IE to store a local
cookie (by virtue of it reading an empty .htm file -
for details see my 3rd post in the March 4th thread
http://groups.google.com/group/micro...380268eda09de/
titled Setting cookies on InternetExplorer.Application)
Admittedly, I should be able to work around this by
placing an onmouseup handler onto the window object,
but then what is the point of the onresize handler - why
not just check the size each time the mouse moves?
Grouse, grouse, grouse.
Here's the .vbScript which demos the issue. There are
anyways a few interesting things to note about the code,
chiefly having to do with the way the callback works.
This is explained underneath the code.
Comments welcome,
Csaba Gabor from Vienna
'Demo of onResize issue
Set ie = CreateObject("InternetExplorer.Application")
Initialize ie
'vbScript must stick around so ResizeHandler can be called
On Error Resume Next
Do while ie.visible 'When we force a quit, this errors
If ie.document.parentWindow.doneP Then ie.Quit
If Err Then Exit Do 'And is caught by this line
WScript.Sleep 10
Loop
WScript.echo "Done with " & WScript.ScriptFullName
Sub ResizeHandler()
' MsgBox "ResizeHandler MsgBox"
Set tmpie=CreateObject("InternetExplorer.Application")
tmpie.Quit
End Sub
Sub Initialize(ie)
'Basic configuration
ie.Navigate2 "about:blank"
ie.visible = true
ie.document.title = "onResize Testing"
Set window = ie.document.parentWindow
'Escape handling
window.opener = "me"
window.execScript "window.doneP=false"
window.execScript _
"document.onkeypress=function(){ " & _
"if (window.event.keyCode==27) " & _
"window.doneP=true;}"
'Resize handling
window.execScript "window.onResizeCnt=0"
window.execScript "window.myHandler=false"
window.myHandler = GetRef("ResizeHandler")
window.execScript "window.onresize=" & _
"function() { " & _
"window.setTimeout( " & vbcrlf & _
"function(cnt) { " & _
"return function() { " & vbcrlf & _
"if (cnt==window.onResizeCnt) " & _
"window.setTimeout(window.myHandler,0); } }" & _
"(++window.onResizeCnt), 2000); }"
End Sub
How to run the code:
Plunk it into a .vbs file and press enter on it. A new
instance of IE will come up. Drag one of its borders (to
resize it) and keep the mouse down for at least two
seconds. You'll see that IE jumps back to it's previous
size. This does not happen if you let the mouse up
within 2 seconds.
Variation: In the ResizeHandler subroutine, comment
out the last two lines and uncomment the MsgBox.
The same type of behaviour will result (only it will be
more visible). Finally, comment out all the lines of
ResizeHandler to see it work as expected.
Explanation of the Resize handling section at the
bottom of Initialize(). First of all, I wanted
ResizeHandler to fire with a window.setTimeout to
ensure that being in the actual event handler was
not an issue. Secondly, when you resize the window,
there are a boatload of resize events (e.g I counted
14 for a minimal movement). That's just wasteful
making so many subroutine calls (especially in light
of the eventual goal of having IE slurp in an empty file).
Thus, the idea is to have a counter (window.onResizeCnt)
that gets incremented each time the .onresize event
handler gets called. Inside that .onreisze event handler
call, a setTimeout is kicked off to a (local javascript)
function after incrementing the counter and associating
the current value with the setTimeout call (by means
of a closure).
When the setTimeout fires its function, the (old) stored
value of the counter (cnt) is checked against the current
value. If they don't match, then this callback has been
superceded by a more recent one, so this one just goes
away quietly. In the event that this callback is the most
recent one, then it should call the vbscript function
ResizeHandler. Unfortunately, just now I don't recollect
whether or how it's possible to get javascript to call into
vbscript directly, even if you store a GetRef("subroutineName")
of the routine onto the window object. Fortunately,
window.setTimeout knows how to deal with it, so that is
the reason for the innermost window.setTimeout.


