Windows Vista Forums
Vista Forums Home Join Vista Forums Windows 7 Forum Vista Tutorials Tags
Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks.

Go Back   Vista Forums > Misc Newsgroups > VB Script

Vista - COM equality testing

Reply
 
Old 02-17-2009   #1 (permalink)
Csaba Gabor


 
 

COM equality testing

I am getting some whacked out results when I am testing
COM objects for equality.

If you run the code below then the document object differs
from everything but itself (including ie.document is not
the same thing as ie.document.parentWindow.document)

On the other hand, the window object shows the same
as everything else except ie and ie.document.

I've tested this against both JSscript and VBScript
methods, shown below, and the results are
consistent. Can anyone explain this behaviour,
please?

Thanks,
Csaba Gabor from Vienna

'COM comparisons
Dim ie, com1, com2, doc, wnd, div, out
Set ie = CreateObject("InternetExplorer.Application")
ie.Navigate2 "about:blank"
ie.document.body.innerHTML = "<div id=foo></div>"

Set doc = ie.document
Set wnd = doc.parentWindow
Set div = ie.document.getElementById("foo")

out = compare(doc, ie.document, "doc/doc: ")
out = out & compare(doc, wnd.document, "doc/doc 2: ")
out = out & compare(doc, wnd, "doc/window: ")
out = out & compare(doc, ie, "doc/ie: ")
out = out & compare(doc, doc.body, "doc/body: ")
out = out & compare(doc, div, "doc/div: ") & vbCrLf

out = out & compare(wnd, doc, "window/doc: ")
out = out & compare(wnd, wnd.document, "window/doc 2: ")
out = out & compare(wnd, wnd.document.parentWindow, _
"window/window: ")
out = out & compare(wnd, ie, "window/ie: ")
out = out & compare(wnd, doc.body, "window/body: ")
out = out & compare(wnd, div, "window/div: ") & vbCrLf

ie.Quit()
MsgBox out

Function compare(com1, com2, txt)
If COMeqVB(com1,com2) _
Then compare = txt & "same" & vbCrLf _
Else compare = txt & "different" & vbCrLf
End Function

Function COMeqVB (com1, com2)
COMeqVB = (com1 Is com2)
End Function

Function COMeqJS (com1, com2)
Dim code
Set oScript = CreateObject("MSScriptControl.ScriptControl")
oScript.Language = "JScript"
code = "function comeq(com1,com2) { return (com1==com2); }"
oScript.AddCode code
oScript.addObject "com1", com1
oScript.addObject "com2", com2
COMeqJS = oScript.Eval("comeq(com1,com2)")
End Function

'Actual results are (under IE 6 / Win XP Pro):
' doc: same, diff, diff, diff, diff, diff
' window: diff, same, same, diff, same, same
'Expected results are:
' First two same in the doc section,
' Third one the same in the window section
' All the rest should be different

My System SpecsSystem Spec
Old 02-18-2009   #2 (permalink)
Csaba Gabor


 
 

Not all typename calls are the same!

Suppose you're noodling around in VBScript, and you
become unhappy with VBScript reporting False for
ie.document.parentWindow IS ie.document
and reporting True for
ie.document.parentWindow IS ie.document.body

In that case you might think to roll your own
com_eq(com1, com2). Although we can take fast
shortcuts with DOM objects (see sourceIndex or
uniqueId), in the generice case, one would iterate
through all the properties on the two objects (This
is a big if as I suspect most COM objects are not
iterable in this fashion. IE is not but you could
test ie.hwnd. The point being that when you don't
have an iterable object you either need to know a
unique property or fall back to the IS test. Bummer).

If the number/type of each property match, then
the two objects might be equal. Of course, as we
have seen earlier, it is insufficient to test each of
the properties for equality when these properties
are objects because then you are back in the same
boat. So here's my down and dirty engineer's
approach:

Make sure property indeces match, and that for each
property the types match. If it's a simple type (string,
number, boolean) then the values should match, too.
If it's an object, then the object types should match.
JScript is not so helpful in reporting the type of an
object. For that, we should use VBScript's typename
function.

So, as far as I can tell, VBScript does not have an
iterator for most COM objects. Javascript's
for (idx in obj) is far better. Therefore, we'll make
a JScript call. We could go two ways here. We
could make the call to determine all the indeces
and types and then pass these indeces/types out to
VB and let it do the detailed object type analysis with
typename (this has its own intricacies - VB is not
very happy (eg. won't iterate) dealing with JScript's
generic object {} and in the initial testing it makes
sense to have one of the property lists be an object
with the property as index and the typeof as value)

However, we could also do all the analysis in JScript.
Except that JScript does not have a typename function.
Therefore, from JScript it will make sense to call to
VBScript's typename function. How can we do this?
Here are two ways:

Typename 1: Make an MSScriptControl object wherein
typename is defined, and pass this script control object
into the script control that has the JScript com_eq defined.
Of course each object that you test has to be added to
the script control under a different name (Is that really
true - or can I call a function in the script control and
pass it an external object directly? As far as I know there
are only Eval, ExecuteStatement, and Run which all require
strings referencing script control objects) and these
objects can't be changed or moved. Nevertheless, if you
take this approach and you get the typename of an event
handler you add (a function, in other words), it will be:
JScriptTypeInfo

Typename 2: The alternate approach to script controls
is to let ie host both JScript and VBScript functions! In
other words, bring up an instance of IE solely for the
convenience of being able to put in both JScript and
VBScript code via ie.document.open(),
ie.document.write(scriptElementSpec),
ie.document.close(). For example:

Set ie = CreateObject("InternetExplorer.Application")
ie.Navigate2 "about:blank"
ie.document.open()
ie.document.write( _
"<script type='text/vbscript'>" & _
"Function tname(myObj)" & vbCrLf & _
" tname=typename(myObj)" & vbCrLf & _
"End Function")

However, at this point a very interesting difference
arises in the typename evaluation of an event handler
For example, if part of the document that ie gets is:
<div id=foo oncontextmenu='alert(""foo"")'></div>
Then the IE hosted typename returns: Object
and not the JScriptTypeInfo of the script control!

Csaba Gabor from Vienna
My System SpecsSystem Spec
Reply

Thread Tools


Similar Threads
Thread Forum
testing Vista General
Testing Vista mail
testing Vista mail


Vista Forums is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media Ltd

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46