 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Sean
Joined: 12 Feb 2007 Posts: 1337
|
Posted: Wed Feb 14, 2007 2:34 am Post subject: COM Helper |
|
|
This is a collection of helper functions to be used for COM.
Please save it as CoHelper.ahk.
DOWNLOAD CoHelper.ahk or Standard Library COM.ahk.
PS. It requires at least AHK build 1.0.47.00.
PS. The usage of Invoke():
If it has the form in VBS-like scripts as
| Code: | | result := Object.Function(parm1, param2, ...) ; Method, PropertyGet |
it'll be translated like
| Code: | | result := Invoke(Object, "Function", param1, param2, ...) |
And, if
| Code: | | Object.Function := param ; PropertyPut, PropertyPutRef |
then
| Code: | | Invoke(Object, "Function=", param) ; notice the suffix = in the function name |
There are some occasions where another COM Object ObjPrm should be a parameter. In that case, please prefix it with "+" like
| Code: | | Invoke(Object, "Function", "+" . ObjPrm) |
WARN. Don't directly prefix it like +ObjPrm.
Good examples of its usage are:
Last edited by Sean on Sat Sep 08, 2007 10:51 am; edited 42 times in total |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4015 Location: Pittsburgh
|
Posted: Wed Feb 14, 2007 3:21 am Post subject: |
|
|
Looks interesting. Could you add some explanations, what the functions do? At least a URL to the relevant MSDN site.
Also, as discussed several times before, the line | Code: | | Return *ptr | *++ptr << 8 | *++ptr << 16 | *++ptr << 24 | relies 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 | Code: | | Return *ptr | *(ptr+1) << 8 | *(ptr+2) << 16 | *(ptr+3) << 24 |
|
|
| Back to top |
|
 |
jonny
Joined: 13 Nov 2004 Posts: 3004 Location: Minnesota
|
Posted: Wed Feb 14, 2007 4:07 am Post subject: |
|
|
| Actually, the documentation is pretty clear that it will be evaluated in left-to-right order. |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4015 Location: Pittsburgh
|
Posted: Wed Feb 14, 2007 6:13 am Post subject: |
|
|
| jonny wrote: | | Actually, the documentation is pretty clear that it will be evaluated in left-to-right order. | All I found in the documentation is:
| Quote: | | Operators of equal precedence such as multiply (*) and divide (/) are evaluated in left-to-right order unless otherwise specified | 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.
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: | Help wrote: | | When 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. | It means, that the following expressions can result in different values of ptr | Code: | *ptr | *++ptr << 8 | *++ptr << 16 | *++ptr << 24
*ptr || *++ptr << 8 || *++ptr << 16 || *++ptr << 24 | The second one might not increment ptr at all. |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Wed Feb 14, 2007 9:36 am Post subject: |
|
|
Lazslo, take a look here. Read the article.
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 _________________
 |
|
| Back to top |
|
 |
Sean
Joined: 12 Feb 2007 Posts: 1337
|
Posted: Wed Feb 14, 2007 11:39 am Post subject: |
|
|
| majkinetor wrote: | 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 ? |
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.
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.
| Quote: | | BTW, Sean, you should put available functions in the header of the file, this way |
OK, I'll do that if I'm allowed. |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Wed Feb 14, 2007 11:51 am Post subject: |
|
|
I thought typelibs are connected to interfaces not objects, as one object can have multiple interfaces. _________________
 |
|
| Back to top |
|
 |
foom
Joined: 19 Apr 2006 Posts: 386
|
Posted: Wed Feb 14, 2007 2:05 pm Post subject: |
|
|
| I like it that you create wrappers around the dll calls but please name the functions the same as the wrapped functions. Having to remember 2 different names for 1 function is a PITA. It would be much better if you could read on msdn and start typing the functions names out as they apear on msdn rather than have to look what the wrapper function is called in your lib. |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Wed Feb 14, 2007 2:30 pm Post subject: |
|
|
Yup.
I explaind here how to crate API wrappers.
But foom, i think this is only temporary wrapper. At the end, we will, with little luck, need only 2 or 3 functions: CreateObject, Invoke and SetField _________________
 |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4015 Location: Pittsburgh
|
Posted: Wed Feb 14, 2007 3:54 pm Post subject: |
|
|
| majkinetor wrote: | | Lazslo, take a look here. Read the article. | 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. |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Wed Feb 14, 2007 4:08 pm Post subject: |
|
|
Sean is the new guy here, not zombie like you He needs time.
Anyway thats why I urge him to put things in wiki along with this place. _________________
 |
|
| Back to top |
|
 |
Sean
Joined: 12 Feb 2007 Posts: 1337
|
Posted: Thu Feb 15, 2007 2:51 am Post subject: |
|
|
| Laszlo wrote: | Also, as discussed several times before, the line | Code: | | Return *ptr | *++ptr << 8 | *++ptr << 16 | *++ptr << 24 | relies 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:
| Quote: | | 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. |
IMHO, it explains pretty clearly about the usage. Am I missing something here? |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4015 Location: Pittsburgh
|
Posted: Thu Feb 15, 2007 2:59 am Post subject: |
|
|
| Sean wrote: | | Am I missing something here? | Yes. The order in which sub-expressions are evaluated is not specified. There are 4 of them in the top level | Code: | | *ptr | *++ptr << 8 | *++ptr << 16 | *++ptr << 24 | Nothing guaranties that *ptr is first evaluated or *++ptr << 24, in which case you would miss the first address. |
|
| Back to top |
|
 |
Sean
Joined: 12 Feb 2007 Posts: 1337
|
Posted: Thu Feb 15, 2007 4:48 am Post subject: |
|
|
| Laszlo wrote: | | Sean wrote: | | Am I missing something here? | Yes. The order in which sub-expressions are evaluated is not specified. There are 4 of them in the top level |
So, what you're saying is that the operations should apply by their precedence as whole.
For example, consider
| Code: | 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. |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4015 Location: Pittsburgh
|
Posted: Thu Feb 15, 2007 5:09 am Post subject: |
|
|
I did not state any rule of expression evaluation, but merely pointed out, that the current AHK behavior is not documented. (Try to read my post more carefully.) In f(x)+f(y) you can evaluate f(x) or f(y) first. Both are conform to the documentation. If your code relies on f(x) being computed the first, it could break at the next AHK release. I don't say it will happen, but could.
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). |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|