COM Helper
REDIRECT. CoHelper.ahk is now retired. Use instead COM Standard Library.
Good examples of its usage are:[*:3vhaalq5]Scripting.Dictionary Object as Associative Array
[*:3vhaalq5]Embed an Internet Explorer control in your AHK Gui via COM
Also, as discussed several times before, the line
Return *ptr | *++ptr << 8 | *++ptr << 16 | *++ptr << 24relies on undocumented AHK features (the order of evaluation of the terms in expressions). They may change in the future, without appearing in the change log. It looks safer to use
Return *ptr | *(ptr+1) << 8 | *(ptr+2) << 16 | *(ptr+3) << 24
All I found in the documentation is:Actually, the documentation is pretty clear that it will be evaluated in left-to-right order.
It does not say anything about the order terms are evaluated, only that exp1+exp2+exp3 = (exp1+exp2)+exp3. It is possible that exp3 is evaluated first, pushed on the stack, than exp2 and finally exp1. At this point pop the two topmost stack entries, add them together (exp1+exp2), then pop the third stack entry and add it to the result. It makes a difference if the sub-expressions have side effects, like *++p.Operators of equal precedence such as multiply (*) and divide (/) are evaluated in left-to-right order unless otherwise specified
Unless there is an explicit statement in the documentation, that sub-expressions are evaluated from left to right, and none of them is left out, even if they don't affect the result (0*f(x)), it is dangerous to rely on these. Even if it will be documented in the future, using side effects is bad style, and should be avoided when feasible.
Look at the case, which is documented:
It means, that the following expressions can result in different values of ptrWhen AND, OR, and the ternary operator are used within an expression, they short-circuit to enhance performance (regardless of whether any function calls are present). Short-circuiting operates by refusing to evaluate parts of an expression that cannot possibly affect its final result.
*ptr | *++ptr << 8 | *++ptr << 16 | *++ptr << 24 *ptr || *++ptr << 8 || *++ptr << 16 || *++ptr << 24The second one might not increment ptr at all.
2 Sean
I see you have CreateObject function, pandan from VBScript. This fun in VB takes only 1 parameter, progID and somehow determines witch interface to use. Do you maybe understand how it finds the interface ?
BTW, Sean, you should put available functions in the header of the file, this way
My IP seems suddenly banned from the forum, the reason is yet to be known. I'm not sure if allowed to post, so, I'll briefly answered.2 Sean
I see you have CreateObject function, pandan from VBScript. This fun in VB takes only 1 parameter, progID and somehow determines witch interface to use. Do you maybe understand how it finds the interface ?
I think what I'm doing is nearly mimics what VBS engine does: use TypeLib. The only difference may be that I have to do it manually.
For example, with WMI case, retrieve the info about the TypeLib from the registry, which resides in WbemDisp.tlb (:I think vbs actually uses the GUID of the TypeLib to LoadRegTypeLib), then find the default interface is IID_ISWbemLocator of the coclass SWbemLocator.
OK, I'll do that if I'm allowed.BTW, Sean, you should put available functions in the header of the file, this way
My point was, that this is a separate thread. Having read the first post I have no idea what is the function library for, let alone the individual functions. It might be enough to say that we should not care, they are used internally by scripts posted elsewhere, but just saying COM is not enough, because it has many meanings. Here it means Component Object Model, but it can mean other things, like Comedy Central (a cable television channel) or Computer output on microfilm.Lazslo, take a look here. Read the article.
Anyway thats why I urge him to put things in wiki along with this place.
Also, as discussed several times before, the line
Return *ptr | *++ptr << 8 | *++ptr << 16 | *++ptr << 24relies on undocumented AHK features (the order of evaluation of the terms in expressions). They may change in the future, without appearing in the change log.
I took it from the help file:
IMHO, it explains pretty clearly about the usage. Am I missing something here?Pre- and post-increment/decrement. Adds or subtracts 1 from a variable (but in versions prior to 1.0.46, these can be used only by themselves on a line; no other operators may be present). The operator may appear either before or after the variable's name. If it appears before the name, the operation is performed immediately and its result is used by the next operation. For example, Var := ++X increments X immediately and then assigns its value to Var. Conversely, if the operator appears after the variable's name, the operation is performed after the variable is used by the next operation. For example, Var := X++ increments X only after assigning the current value of X to Var.
Yes. The order in which sub-expressions are evaluated is not specified. There are 4 of them in the top levelAm I missing something here?
*ptr | *++ptr << 8 | *++ptr << 16 | *++ptr << 24Nothing guaranties that *ptr is first evaluated or *++ptr << 24, in which case you would miss the first address.
So, what you're saying is that the operations should apply by their precedence as whole.Yes. The order in which sub-expressions are evaluated is not specified. There are 4 of them in the top levelAm I missing something here?
For example, consider
SetFormat, Integer, H var := 1 MsgBox % var | ++var << 8 | ++var << 16 | ++var << 24
According to your rule, the first, second, third ++ apply first, then first, second, third << apply, then finally all |'s apply. Then, the result would become
0x04030204
On the other hand, what I'm thinking is that the operation should apply from left to right according to their precedence. What I mean is that, with the above example, when meet the first operator, the first | in this case, parse the next operator and if it's of higher precedence then, defer the procedure and go on until meeting an operator of lower or equal precedence. Then stop there and apply all the operations accordingly.
So, with the above example, first apply the first ++, then the first <<, then the first |. After that, the second ++, the second <<, the second |. Finally, the third ++, the third <<, the third |. The result would be
0x04030202
What AHK actually produces is 0x04030202.
In conclusion, AHK seems to use the rule of mine, which is more logical IMHO.
If you say that the current evaluation order should be the rule, try to convince Chris to document it and promise that it will not change (very often).
It does not make bad coding style (relying on side effects) good. They make the code hard to understand, debug, modify or optimize. Especially in this case, when it is faster, simpler, safer to use explicit offsets, like *(ptr+1).