AutoHotkey Community

It is currently May 27th, 2012, 10:58 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 44 posts ]  Go to page 1, 2, 3  Next
Author Message
PostPosted: January 29th, 2007, 5:43 pm 
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)
}


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: January 30th, 2007, 9:26 am 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
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

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 30th, 2007, 12:55 pm 
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)



Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: January 30th, 2007, 2:30 pm 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
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.

_________________
Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 30th, 2007, 3:12 pm 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 30th, 2007, 4:04 pm 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
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.

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 30th, 2007, 4:15 pm 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
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?

_________________
Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 31st, 2007, 2:51 am 
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


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: January 31st, 2007, 9:17 am 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
I don't see how function pointers in DllCall can help us with COM. Example using mentioned WebBrowser control with imaginary DllCall would help.

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 31st, 2007, 4:18 pm 
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.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: January 31st, 2007, 4:29 pm 
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)



Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: January 31st, 2007, 4:35 pm 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
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 ?

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 31st, 2007, 5:07 pm 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
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.

_________________
Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 31st, 2007, 5:08 pm 
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.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: January 31st, 2007, 5:18 pm 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
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...

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 44 posts ]  Go to page 1, 2, 3  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: SKAN and 3 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group