![]() |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
| 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. |
| |||||||
![]() |
| |
| | #1 (permalink) |
| | 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 Specs![]() |
| | #2 (permalink) |
| | 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 Specs![]() |
![]() |
| Thread Tools | |
| |
Similar Threads | ||||
| Thread | Forum | |||
| testing | Vista General | |||
| Testing | Vista mail | |||
| testing | Vista mail | |||