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) }
Allowing Function Pointer in DllCall
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
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)
Seems to be a slightly biased way of reporting the discussions...many others don't think it is so important including Chris
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.
The project could really use another developer who has an interest in these areas.
Not at all.Seems to be a slightly biased way of reporting the discussions...
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.
:?: Where do you see that!?As you just said, you and Chris don't think it would be benefitial.
Personally, I think exactly the reverse, ie. callbacks would be a great addition to DllCall, allowing the use of some API functions currently unusable.
Yes, but Sean was talking about Com.Anyway, I was not talking about COM, but FFI.
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.I see now that I missunderstood the topic.... Sean wants AHK functions as first class values.
Sean, please, can you confirm my explanation?
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
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.)
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.
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)
Strange way to say that you don't have comments at all... you can safely delete "appropriately".Sorry, I haven't commented it appropriately
Yes.BTW, is this a bug?
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.Just take it as a showcase.
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 ?
It is a known problem, still mysterious for me, but the problem might be in Windows rather than in AHK (just an hypothesis).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.
As a "non AutoHotkey user", you have quite some knowledge of the language (or at least of the proper use of DllCall and related).
I checked on a couple of WinXP Pro SP2 computers at work and both have it in System32.msjava.dll is missing from Windows XP
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.
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.
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...I checked on a couple of WinXP Pro SP2 computers at work and both have it in System32.
C like style ?At first, I leaned toward AutoIt, but now I'm definitely attracted toward AHK. I like its 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...