|
Joined: Feb 2004
Posts: 2,019
Hoopy frood
|
OP
Hoopy frood
Joined: Feb 2004
Posts: 2,019 |
EDIT: Before anyone tries this code, be aware you need atleast mIRC 6.16 or it will not work! Bug number one:$comval seems to suffer from a severe inefficiency, where looping through a collection with $comval is significantly slower to its counterpart being the "item" method, which you normally use in other languages such as VBScript, since $comval is an mIRC identifier. One would expect $comval to be more efficient, but the difference is really striking. Consider the following code, note that it will take a few seconds before it starts echoing stuff to your active window, so give it some time. alias mirclinks {
var %t
.comopen ie.main internetexplorer.application
showmirc -s
%t = $com(ie.main,navigate,1,bstr*,http://www.mirc.com/get.html)
:loop
%t = $ticks + 300
while ($ticks < %t) !
%t = $com(ie.main,readystate,2)
if ($com(ie.main).result != 4) goto loop
%t = $com(ie.main,document,2,dispatch* ie.doc)
%t = $com(ie.doc,links,2,dispatch* ie.links)
var %total = $comval(ie.links,0), %ticks, %i
echo -ac info Total amount of links: %total
echo -a $chr(15)
echo -ac info * Looping with $!comval from 1 - %total
%ticks = $ticks
%i = 1
while (%i <= %total) {
%t = $comval(ie.links,%i,href)
inc %i
}
echo -ac info * Time taken with first approach: $calc($ticks - %ticks) ms
echo -a $chr(15)
echo -ac info * Looping with $!comval from %total - 1
%ticks = $ticks
%i = %total
while (%i) {
%t = $comval(ie.links,%i,href)
dec %i
}
echo -ac info * Time taken with second approach: $calc($ticks - %ticks) ms
echo -a $chr(15)
echo -ac info * Looping with item method to access the collection
%ticks = $ticks
%i = 0
while (%i < %total) {
%t = $com(ie.links,item,1,uint,%i,dispatch* ie.item)
if ($com(ie.item)) {
%t = $com(ie.item,href,2)
%t = $com(ie.item).result
.comclose ie.item
}
inc %i
}
echo -ac info * Time taken with third approach: $calc($ticks - %ticks) ms
:error
if ($com(ie.links)) .comclose $v1
if ($com(ie.doc)) .comclose $v1
if ($com(ie.main)) .comclose $v1 $com($v1,close,1)
} My results: - * Total amount of links: 131
* Looping with $comval from 1 - 131 * Time taken with first approach: 2109 ms
* Looping with $comval from 131 - 1 * Time taken with second approach: 2125 ms
* Looping with item method to access a collection * Time taken with third approach: 172 ms
The results speak for theirselves, the two methods (looping from front to back, and back to front) take around 2 seconds, whilst the item method, which consists of more code actually only takes 172 milliseconds. Bug number two:Often, when I dispatch to a childobject which holds a collection, $comval will not be able to access any of its properties. The worst thing is, that the item method also doesn't work in mIRC on this collection, whereas this does works fine in VBScript. Consider the following code, but note that you must atleast have 1 internetexplorer window open connected to a site (will also work if you have tabs open in Avantbrowser, Maxthon or other IE based browsers) alias shellwindows {
var %t, %i = 0, %total
.comopen shell shell.application
%t = $com(shell,windows,3,dispatch* wins)
%t = $com(wins,count,3)
%total = $com(wins).result
echo -a Total amount of shell windows found: %total
echo -a But what does comval say? -> $comval(wins,0)
echo -a Trying to access this collection with the "item" method:
while (%i < %total) {
%t = $com(wins,item,1,uint,%i,dispatch* item)
if ($com(item)) {
echo -a Item %i retrieved with dispatch
.comclose item
}
inc %i
}
echo -a Using VBScript to access the collection:
window -h @@
%t = aline @@
%t dim s
%t set shell = createobject("shell.application")
%t set wins = shell.windows
%t For each item in wins
%t s = s & item.locationurl & VbCrLf
%t Next
%t wscript.echo s
savebuf @@ wins.vbs
close -@ @@
run wins.vbs
.timer 1 2 .remove wins.vbs
:error
if ($com(shell)) .comclose $v1
if ($com(wins)) .comclose $v1
} My results: Total amount of shell windows found: 8 But what does comval say? -> 0 Trying to access this collection with the "item" method: Using VBScript to access the collection:
The count property clearly shows there are 8 shellwindows open, whereas $comval says the collection is empty. Nothing is echoed in the while loop that attempts to dispatch with the item method. Finally, the VBScript executes, and you see the locationurls of the shellwindows in a message box. Note that in the while loop where I try to retrieve an item object with the line: %t = $com(wins,item,1,uint,%i,dispatch* item) I use "1", since it's a method, but changing it to 2 or 3 doesn't change anything. Just thought I'd mention before someone tries to suggest this All of this was tested on mIRC 6.16, Windows XP+SP2
Gone.
|
|
|
|
Joined: Apr 2004
Posts: 871
Hoopy frood
|
Hoopy frood
Joined: Apr 2004
Posts: 871 |
I don't have any experience with bug number two, but I can fully confirm bug number one. At least one reason for the inefficiency is the fact that a new iterator is created for each individual $comval call, then looped through N times (N as passed to that $comval call), used, and closed again. It would be great if the iterator were "cached" instead; scripts typically use $comval with values from 1 to the maximum in sequence anyway.
Saturn, QuakeNet staff
|
|
|
|
Joined: Jan 2003
Posts: 2,523
Hoopy frood
|
Hoopy frood
Joined: Jan 2003
Posts: 2,523 |
Regarding the 2nd bug, you can use Item in mirc (and all properties of the item child object that's created) but you need to change the type from uint to i2 or i4. Why/how this is related to $comval not working, I have no idea.
Oh and I can confirm the 1st 'bug' of course. Caching the results for the duration of the routine (ie the current alias and any parent aliases) would be really wonderful, not just for $comval() but for any other identifier that currently works like that, with $hget(name,N).item being the most important imo.
/.timerQ 1 0 echo /.timerQ 1 0 $timer(Q).com
|
|
|
|
Joined: Feb 2004
Posts: 2,019
Hoopy frood
|
OP
Hoopy frood
Joined: Feb 2004
Posts: 2,019 |
How weird, I've always been able to access the item method with an uint, changing to i2 or i4 indeed works now. I had tried before with i1, which also doesnt work, so didn't bother with versions higher than 1, since i1 already supports the necessary range :rolleyes:
I still see this issue as a $comval bug, it's a collection so $comval should be able to be used on it.
Gone.
|
|
|
|
Joined: Oct 2004
Posts: 73
Babel fish
|
Babel fish
Joined: Oct 2004
Posts: 73 |
How would I test this bug with Firefox 1.5? Now that personally IE6 is just a little too "zero-day exploit" friendly for my liking.
|
|
|
|
Joined: Feb 2004
Posts: 2,019
Hoopy frood
|
OP
Hoopy frood
Joined: Feb 2004
Posts: 2,019 |
Whether you use Firefox or IE for your everyday browsing does not matter to test this bug. As long as you have IE installed on your system (every windows user does), you will be able to reproduce it with the code in my first post. It doesn't require for you to open any browser, it is all done programmatically and hidden.
Note that you don't need to use that code, any collection that $comval is able to retrieve where the item method works on, can show you $comval's inefficiency.
Gone.
|
|
|
|
|