 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Sean Guest
|
Posted: Mon Jan 29, 2007 5:43 pm Post subject: Allowing Function Pointer in DllCall |
|
|
I'm not an AutoHotkey user, however, I'm curious why AHK hasn't this feature yet. I think it's just a few lines of codes addtion to already existing codes, and AHK will have some benefits from it, like COM ability through VTable method. Here is an example: changing Wallpaper via IActiveDesktop (:need XP or higher, I think). Actually, others, like WMI etc, also can be done by this method of course, although a bit cumbersome compared to the dispatch method. It'll need msjava.dll for calling function pointer, which can be easily obtained from the web if missing in the system.
| Code: |
sFile := "C:\WINDOWS\Web\Wallpaper\Home.jpg"
VarSetCapacity(wFile, 260 * 2)
VarSetCapacity(CLSID_ActiveDesktop, 16)
VarSetCapacity( IID_IActiveDesktop, 16)
EncodeInteger(&CLSID_ActiveDesktop , 0x75048700)
EncodeInteger(&CLSID_ActiveDesktop + 4, 0xEF1F | 0x11D0 << 16)
EncodeInteger(&CLSID_ActiveDesktop + 8, 0x98 | 0x88 << 8 | 0x00 << 16 | 0x60 << 24)
EncodeInteger(&CLSID_ActiveDesktop + 12, 0x97 | 0xDE << 8 | 0xAC << 16 | 0xF9 << 24)
EncodeInteger(&IID_IActiveDesktop , 0xF490EB00)
EncodeInteger(&IID_IActiveDesktop + 4, 0x1240 | 0x11D1 << 16)
EncodeInteger(&IID_IActiveDesktop + 8, 0x98 | 0x88 << 8 | 0x00 << 16 | 0x60 << 24)
EncodeInteger(&IID_IActiveDesktop + 12, 0x97 | 0xDE << 8 | 0xAC << 16 | 0xF9 << 24)
DllCall("MultiByteToWideChar", "Uint", 0, "Uint", 0, "Uint", &sFile, "int", -1, "Uint", &wFile, "int", 260)
DllCall("ole32\CoInitialize", "Uint", 0)
DllCall("ole32\CoCreateInstance", "Uint", &CLSID_ActiveDesktop, "Uint", 0, "Uint", 1, "Uint", &IID_IActiveDesktop, "UintP", ppv)
pv := DecodeInteger(ppv)
DllCall("msjava\call", "Uint", DecodeInteger(pv + 4*5), "Uint", ppv, "Uint", &wFile, "Uint", 0)
DllCall("msjava\call", "Uint", DecodeInteger(pv + 4*3), "Uint", ppv, "Uint", 7)
DllCall("msjava\call", "Uint", DecodeInteger(pv + 4*2), "Uint", ppv)
DllCall("ole32\CoUninitialize")
DecodeInteger(ptr)
{
DllCall("RtlMoveMemory", "UintP", deref, "Uint", ptr, "Uint", 4)
Return deref
}
EncodeInteger(ref, val)
{
DllCall("ntdll\RtlFillMemoryUlong", "Uint", ref, "Uint", 4, "Uint", val)
}
|
|
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3600 Location: Belgrade
|
Posted: Tue Jan 30, 2007 9:26 am Post subject: |
|
|
There was already a big discussion about this.
I beleive that adding such functionality to AHK would bring it to another level, but many others don't think it is so important including Chris, unless he changed his mind in the meantime. This will probably be implemented one day but IF and WHEN, we are about to see...
Its good place, here, again, to reference this library for foreign function calls that could be integrated into AHK - C/Invoke _________________
 |
|
| Back to top |
|
 |
Sean Guest
|
Posted: Tue Jan 30, 2007 12:55 pm Post subject: |
|
|
What I was asking is a lot simpler one, and I thought AHK almost got there already. Essentially only one additional check whether the first argument is an integer or a string "dll\ftn", then jump to the appropriate place. So, if implemented the codes would look like
| Code: |
DllCall(DecodeInteger(pv + 4*5), "Uint", ppv, "Uint", &wFile, "Uint", 0)
DllCall(DecodeInteger(pv + 4*3), "Uint", ppv, "Uint", 7)
DllCall(DecodeInteger(pv + 4*2), "Uint", ppv)
|
|
|
| Back to top |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6721 Location: France (near Paris)
|
Posted: Tue Jan 30, 2007 2:30 pm Post subject: |
|
|
| majkinetor wrote: | | many others don't think it is so important including Chris | Seems to be a slightly biased way of reporting the discussions...
I don't recall Chris discarding callbacks as unimportant, but as hard to implement properly.
This might have not the highest priority indeed, so perhaps he didn't had time to do the right researches, but if somebody presented him usable code, he would be able to integrate it sooner.
To Sean, what you present is interesting, but I must admit I don't understand it. Although I am familiar with Windows API, I never had time to study properly Com and related, so your code is quite cryptic for me. Alas, Chris is, AFAIK, at the same state than me, that's what prevented him to add Com support to AHK up to now.
We reckon the usefulness of a full Com support in AutoHotkey, but it won't come soon, I fear. _________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2") |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10465
|
Posted: Tue Jan 30, 2007 3:12 pm Post subject: |
|
|
I would like to see COM support and callbacks implemented, but I don't fully understand them. Like many things, maybe they just seem daunting, becoming easier after you learn them.
The project could really use another developer who has an interest in these areas. |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3600 Location: Belgrade
|
Posted: Tue Jan 30, 2007 4:04 pm Post subject: |
|
|
| Philho wrote: | | Seems to be a slightly biased way of reporting the discussions... |
Not at all.
As you just said, you and Chris don't think it would be benefitial. Its hard for me to grasp such .... hm.... vision ..... as COM is primarly made for automatition, and AHK is automatition language. Being automatition language and not supporting the system native way of automatition while trying to automate the very same system, is really a problem.
Anyway, I was not talking about COM, but FFI.
I see now that I missunderstood the topic.... Sean wants AHK functions as first class values. _________________
 |
|
| Back to top |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6721 Location: France (near Paris)
|
Posted: Tue Jan 30, 2007 4:15 pm Post subject: |
|
|
| majkinetor wrote: | | As you just said, you and Chris don't think it would be benefitial. | Where do you see that!?
Personally, I think exactly the reverse, ie. callbacks would be a great addition to DllCall, allowing the use of some API functions currently unusable.
| Quote: | | Anyway, I was not talking about COM, but FFI. | Yes, but Sean was talking about Com.
| Quote: | | I see now that I missunderstood the topic.... Sean wants AHK functions as first class values. | That's not what I understood, but I can get wrong here. From what I grasped, he wants a facility to provide a pointer on an API function to another API function.
Sean, please, can you confirm my explanation? _________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2") |
|
| Back to top |
|
 |
Sean Guest
|
Posted: Wed Jan 31, 2007 2:51 am Post subject: |
|
|
I'm afraid I caused a confusion because I wasn't clear enough. What I asked was simple: let allow using function pointers in place of function names in DllCall(). Then, the places in which it could be used most beneficially would be COM. There could be other cases like calling APIs exported with ordinal only without name, however, the chances of finding useful ones of the kind may be rare as usually they are not documented. Here is one example of the kind which will invoke the run... dialog (need msjava.dll again currently):
| Code: |
hModule := DllCall("LoadLibrary", "str", "shell32.dll")
pRunDlg := DllCall("GetProcAddress", "Uint", hModule, "Uint", 61)
DllCall("msjava\call", "Uint", pRunDlg, "Uint", 0, "Uint", 0, "Uint", 0, "Uint", 0, "Uint", 0, "Uint", 0)
; DllCall(pRunDlg, "Uint", 0, "Uint", 0, "Uint", 0, "Uint", 0, "Uint", 0, "Uint", 0)
; if the feature is implemented
DllCall("FreeLibrary", "Uint", hModule)
|
I'm not by any means an expert on COM either. But, I'd like to stress that the VB-like fancy way is not the only way to invoke COM, there is another way to achieve it, namely C/C++ like way. As a matter of fact, C/C++ way is more broader than VB way in scope. For example, my example here with IActiveDesktop can't be invoked from a VBScript.
Although I don't think it's quite correct conceptually, in practice from the point of view of C/C++, COM object could be usefully viewed as a Class in C++, I think (:btw, I'm not an expert on C/C++). So, what I did in the first example can be regraded as calling the member functions by their offsets in its VTable.
I'm not saying there is no need to implement VBScript way to do COM. On the contrary, I think it should be, as majority of the scripters expect this way when talking about COM (:btw, my friend told me LuaCom can be a valuable source in this regard). Until it's implemented fully, however, C/C++ way can be an execellent work-around. And a good news for the developers is that it doesn't require anything more on the developers side, only require a lot of reseach on users side.
If it's implemented, I'm willing to post a script invoking WMI which has already been done on my side. And, I saw here a script controlling IExplore using external library, then, there would be no need to rely on an external library any more, although I'm not sure how complicated it would be to achieve as I haven't done it myself because I seldom use IExplore.
Sean |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3600 Location: Belgrade
|
Posted: Wed Jan 31, 2007 9:17 am Post subject: |
|
|
I don't see how function pointers in DllCall can help us with COM. Example using mentioned WebBrowser control with imaginary DllCall would help. _________________
 |
|
| Back to top |
|
 |
Sean Guest
|
Posted: Wed Jan 31, 2007 4:18 pm Post subject: |
|
|
| Quote: | | I don't see how function pointers in DllCall can help us with COM. Example using mentioned WebBrowser control with imaginary DllCall would help. |
My first example isn't enough?
As I said in the previous message I haven't tried IWebBrowser2 so I can't show the usage about it right now. Instead, I'll post about WMI which has been done already.
Actually there exist two ways to do it. Since MS thinks WMI is so important, MS provides both Interfaces to be used in C/C++ and in scripts. Although the interface for C/C++ is more natural in this approach, I'll use the one for scripts as it'd be the easier one to be adapted to the objects scripters are generally interested in.
It'll enumerate all the network adapters in the system.
(Sorry, I haven't commented it appropriately. Just take it as a showcase.)
| Code: |
sNamespace := "winmgmts:{impersonationLevel=impersonate}!\\.\" . "root\cimv2"
sClass := "SELECT * FROM " . "Win32_NetworkAdapter"
sQLang := "WQL"
VarSetCapacity(wNamespace, StrLen(sNamespace) * 2 + 2)
VarSetCapacity(wClass, StrLen(sClass) * 2 + 2)
VarSetCapacity(wQLang, 8)
Unicode(sNameSpace, wNameSpace, StrLen(sNamespace) + 1)
Unicode(sClass, wClass, StrLen(sClass) + 1)
Unicode(sQLang, wQLang, 4)
EncodeInteger(&IID_IDispatch , 0x00020400)
EncodeInteger(&IID_IDispatch + 4, 0)
EncodeInteger(&IID_IDispatch + 8, 0xC0)
EncodeInteger(&IID_IDispatch +12, 0x46 << 24)
hModule := DllCall("LoadLibrary", "str", "msjava.dll")
DllCall("ole32\CoInitialize", "Uint", 0)
DllCall("ole32\CoGetObject"
, "Uint", &wNamespace
, "Uint", 0
, "Uint", &IID_IDispatch
, "UintP", psvc)
DllCall("msjava\call"
, "Uint", DecodeInteger(DecodeInteger(psvc) + 4*15)
, "Uint", psvc
, "Uint", &wClass
, "Uint", &wQLang
, "Uint", 48
, "Uint", 0
, "UintP", pset)
DllCall("msjava\call"
, "Uint", DecodeInteger(DecodeInteger(pset) + 4*7)
, "Uint", pset
, "UintP", penm)
VarSetCapacity(sText, 10240, 1)
VarSetCapacity(vt, 4 * 4)
Loop
{
hResult := DllCall("msjava\call"
, "Uint", DecodeInteger(DecodeInteger(penm) + 4*3)
, "Uint", penm
, "Uint", 1
, "Uint", &vt
, "Uint", 0)
If hResult
break
pobj := DecodeInteger(&vt + 4*2)
DllCall("msjava\call"
, "Uint", DecodeInteger(DecodeInteger(pobj) + 4*22)
, "Uint", pobj
, "Uint", 0
, "UintP", ptr)
DllCall("WideCharToMultiByte"
, "Uint", 0
, "Uint", 0
, "Uint", ptr
, "int", -1
, "Uint", &sText
, "int", 10240
, "Uint", 0
, "Uint", 0)
DllCall("msjava\call"
, "Uint", DecodeInteger(DecodeInteger(pobj) + 4*2)
, "Unit", pobj)
MsgBox % sText
}
DllCall("msjava\call"
, "Uint", DecodeInteger(DecodeInteger(pset) + 4*2)
, "Unit", penm)
DllCall("msjava\call"
, "Uint", DecodeInteger(DecodeInteger(pset) + 4*2)
, "Unit", pset)
DllCall("msjava\call"
, "Uint", DecodeInteger(DecodeInteger(pset) + 4*2)
, "Unit", psvc)
DllCall("ole32\CoUninitialize")
DllCall("FreeLibrary", "Uint", hModule)
Unicode(ByRef sString, ByRef wString, nLength)
{
DllCall("MultiByteToWideChar"
, "Uint", 0
, "Uint", 0
, "Uint", &sString
, "int", -1
, "Uint", &wString
, "int", nLength)
}
DecodeInteger(ptr)
{
DllCall("RtlMoveMemory", "UintP", deref, "Uint", ptr, "Uint", 4)
Return deref
}
EncodeInteger(ref, val)
{
DllCall("ntdll\RtlFillMemoryUlong", "Uint", ref, "Uint", 4, "Uint", val)
}
|
BTW, is this a bug? I have to use VarSetCapacity(sText, 10240, 1) or non-zero byte for the last parameter.
If use VarSetCapacity(sText, 10240) or VarSetCapacity(sText, 10240, 0), then empty sText was returned. |
|
| Back to top |
|
 |
Sean Guest
|
Posted: Wed Jan 31, 2007 4:29 pm Post subject: |
|
|
Oops, my mistake. The last three ones should have been:
| Code: |
DllCall("msjava\call"
, "Uint", DecodeInteger(DecodeInteger(penm) + 4*2)
, "Unit", penm)
DllCall("msjava\call"
, "Uint", DecodeInteger(DecodeInteger(pset) + 4*2)
, "Unit", pset)
DllCall("msjava\call"
, "Uint", DecodeInteger(DecodeInteger(psvc) + 4*2)
, "Unit", psvc)
|
|
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3600 Location: Belgrade
|
Posted: Wed Jan 31, 2007 4:35 pm Post subject: |
|
|
| Quote: | | Sorry, I haven't commented it appropriately |
Strange way to say that you don't have comments at all... you can safely delete "appropriately".
| Quote: | | BTW, is this a bug? |
Yes.
| Quote: | | Just take it as a showcase. |
Hm.... I see that you use dynamic execution using call(). So, U acctually use metaprogramming. C# may be better candidate (Invoke) as msjava.dll is missing from Windows XP due to the Microsoft-Sun agreement on Java technology.
I will check this topic more carefully and let you know what I think.
Thx for nice examples and some new insights.
BTW, as you are not AHK user, why are you posting this ? _________________
 |
|
| Back to top |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6721 Location: France (near Paris)
|
Posted: Wed Jan 31, 2007 5:07 pm Post subject: |
|
|
| Sean wrote: | BTW, is this a bug? I have to use VarSetCapacity(sText, 10240, 1) or non-zero byte for the last parameter.
If use VarSetCapacity(sText, 10240) or VarSetCapacity(sText, 10240, 0), then empty sText was returned. | It is a known problem, still mysterious for me, but the problem might be in Windows rather than in AHK (just an hypothesis).
As a "non AutoHotkey user", you have quite some knowledge of the language (or at least of the proper use of DllCall and related).
| majkinetor wrote: | | msjava.dll is missing from Windows XP | I checked on a couple of WinXP Pro SP2 computers at work and both have it in System32. _________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2") |
|
| Back to top |
|
 |
Sean Guest
|
Posted: Wed Jan 31, 2007 5:08 pm Post subject: |
|
|
| Quote: | | C# may be better candidate (Invoke) as msjava.dll is missing from Windows XP due to the Microsoft-Sun agreement on Java technology. |
That's (minor) one of the two reasons why I requested the feature.
| Quote: | | BTW, as you are not AHK user, why are you posting this ? |
'Cause I think I've benefited from AHK, although indirectly.
And I'm thinking about using a second scripting language, mainly for fun. At first, I leaned toward AutoIt, but now I'm definitely attracted toward AHK. I like its C like style. |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3600 Location: Belgrade
|
Posted: Wed Jan 31, 2007 5:18 pm Post subject: |
|
|
| Quote: | | I checked on a couple of WinXP Pro SP2 computers at work and both have it in System32. |
I know, I have it too.... but... that is official note. Some service pack or hot fix or anything can remove this dll... Also this dll is not maintaned anymore by MS, and it might have buffer overflows etc...
| Quote: | | At first, I leaned toward AutoIt, but now I'm definitely attracted toward AHK. I like its C like style. |
C like style ?
Funny ....
AutoIt's syntax capabilities are much better then in AHK, but again, that thing is slow as hell for me, while AHK shines... _________________
 |
|
| 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
|