AutoHotkey Community

It is currently May 25th, 2012, 9:34 am

All times are UTC [ DST ]




Post new topic This topic is locked, you cannot edit posts or make further replies.  [ 156 posts ]  Go to page Previous  1 ... 4, 5, 6, 7, 8, 9, 10, 11  Next
Author Message
 Post subject:
PostPosted: June 6th, 2007, 4:08 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
Joy2DWorld wrote:
any help/guidance appreciated, streaming feed to the html from var seems like a valueable function... anyhow...

Although I may implement it if there are urgent demands, this function would become redundant once DOM is supported, which is more elegant way to do it, IMO.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 7th, 2007, 12:32 am 
Offline

Joined: December 4th, 2006, 10:35 am
Posts: 561
Location: Galil, Israel
ok, i'll add it to *my* project list... and hopefully you'll give me some guidance in those areas where my skull is too thick...

_________________
Joyce Jamce


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 7th, 2007, 8:21 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
I added one more function, ActiveXObject, to CoHelper.ahk.
Although this function may not be as accurate as CreateObject(), I suppose it is the closest to VBScript's CreateObject() or JScript's ActiveXObject().

For example, in ZipFolder script, may replace

Code:
   CLSID_Shell := "{13709620-C279-11CE-A49E-444553540000}"
    IID_IShell := "{D8F015C0-C278-11CE-A49E-444553540000}"
   psh := CreateObject(CLSID_Shell, IID_IShell)

with

Code:
   psh := ActiveXObject("Shell.Application")


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 25th, 2007, 6:18 pm 
Offline

Joined: October 3rd, 2005, 2:42 am
Posts: 186
In another thread I am trying to intercept drag/drop operations. I am disabled by the fact that I have never done any COM programming before.

In order to do this, I need to (from MSDN's page on the topic):

  • "initialize COM with OleInitialize, not CoInitialize." [CoHelper can do this: the OleInitialize() function]
  • "expose an IDropTarget interface." [I do not know if this is possible in AHK]
  • "register with the system by calling RegisterDragDrop." - and passing it a pointer to the object that exposes the IDropTarget interface. [Though CoHelper can call the function, I do not know what DLL it is in, nor whether I can create a pointer to an interface in AHK]
  • Create the functions IDropTarget::DragEnter(), IDropTarget::DragOver(), IDropTarget::DragLeave() and IDropTarget::Drop() to be called by the system. [While I can create them as AHK functions, I suspect this is not good enough, and they need to be real functions with memory addresses and stuff.]
  • Accept a pointer to a data object as a parameter to DragEnter() [Pointers in AHK? I don't know if possible.]
  • Use that pointer to obtain the information from the IDataObject that is being dragged. [I am unsure of object manipulation is possible in AHK.]


So, I have questions :)

Is all the above possible in AHK?

Is there a lower level at which I could hook into drag/drop, so that I wouldn't need to place a window under the mouse in order to capture the IDataObject?

Am I using the wrong tool, needlessly hobbling myself using AHK? Should I instead download a C compiler and learn to program the Windows API in that?

Can you offer any other advice?

_________________
Yet another hotkeyer.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 26th, 2007, 12:54 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
Dewi Morgan wrote:
Is all the above possible in AHK?

Basically, I would say yes, now officially, using RegisterCallback.
Moreover, I think it's highly likely as IDropTarget interface is relatively simple.

I once did a similar job:
http://www.autohotkey.com/forum/viewtopic.php?t=19475

There, I'm still feeling that I was very lucky as I had to implement the corresponding AHK's procedure for only one member function. In principle, however, you have to implement its own (AHK's) procedure for each member functions.

Quote:
Should I instead download a C compiler and learn to program the Windows API in that?

You can also use C, even (in-line) ASM, inside AHK. See this breath-taking post by Laszlo:
http://www.autohotkey.com/forum/topic18713.html


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 26th, 2007, 6:13 am 
Offline

Joined: October 3rd, 2005, 2:42 am
Posts: 186
"relatively simple" he says! Way to scare me away from Windows programming! :P

But thank you - that is awesomely helpful, and I seems to be exactly what I needed.

_________________
Yet another hotkeyer.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 26th, 2007, 5:08 pm 
Offline

Joined: February 28th, 2007, 7:23 pm
Posts: 14
Hi Sean + others,

very helpful script you wrote accessing COM.
I have some problems, maybe you can give me a hint
on how to solve my problem.

I am trying to communicate with the Citrix API through the ICA client.
I am new to this topic but I have to figure out how I can send
keystrokes and maybe also mouseclicks to a citrix application.

I tried to use PostMessage but this won't work on a Citrix window.

So now I am using cohelper.ahk to use the wfica.ocx.
I managed to login through citrix but now I get stuck on how to use
the keyboard.

Alright. Now some information.

I use
Code:
piT := ActiveXObject("Citrix.ICAClient")
to connect to the API and piT contains a valid identifier. Then I am able to set some properties and to pass them.
For instance:

Code:
Ctrx_SetProp(ByRef piT, propName, propVal)
{
   pName := SysAllocString(propName)
   pStr := SysAllocString(propVal)
   ret := DllCall(VTable(piT, 16), "Uint", piT, "Uint", pName, "Uint", pStr)
   
   SysFreeString(pName)
   SysFreeString(pStr)

   return ret
}


Ctrx_SetProp(piT,"Username",user)
Ctrx_SetProp(piT,"Password",Pwd)


Now the problem. As I can see from the typelib browser, there are differten CLSIDs and IIDs but I don't know, how to use different than
the ICAClient

Code:
' ****************************************************************************************
' ProgIDs (Program identifiers)
' ****************************************************************************************

$PROGID_CitrixICAClient25 = "Citrix.ICAClient.2.5"
$PROGID_CitrixICAClientProp24 = "Citrix.ICAClientProp.2.4"

' ****************************************************************************************
' ClsIDs (Class identifiers)
' ****************************************************************************************

$CLSID_ICAClient = GUID$("{238F6F83-B8B4-11CF-8771-00A024541EE3}")
$CLSID_ICAClientProp = GUID$("{238F6F85-B8B4-11CF-8771-00A024541EE3}")
$CLSID_Keyboard = GUID$("{B5D6ED13-EDAA-4C2C-B2E2-26FD9BC1C710}")
$CLSID_Mouse = GUID$("{901591F7-7ACA-477A-9119-C75198E74F72}")
$CLSID_ScreenShot = GUID$("{1F26DF05-9E90-4156-B58B-44632B0DC461}")
$CLSID_Session = GUID$("{1DA5FBD9-3ED4-4617-9A95-334789A2B52A}")
$CLSID_window = GUID$("{CBC0A3C6-7F47-4F70-B0FC-307688E5EAB2}")
$CLSID_Windows = GUID$("{30DBF909-6147-46C8-B02C-96B460712ED3}")

' ****************************************************************************************
' IIDs (Interface identifiers)
' ****************************************************************************************

$IID_IICAClient = GUID$("{238F6F81-B8B4-11CF-8771-00A024541EE3}")
$IID_IKeyboard = GUID$("{17BFCA0A-C42E-4AC9-A693-29473FF9BA6C}")
$IID_IMouse = GUID$("{02093274-7B69-4FEB-B7FD-3A010561A5F3}")
$IID_IScreenShot = GUID$("{8F2D9E63-D224-47E4-8111-32DBB016A4C6}")
$IID_ISession = GUID$("{4A502C16-CFAE-4BB0-B1F9-93ACADDA57BB}")
$IID_IWindow = GUID$("{4D5D2139-29E2-4CDC-8020-429B35999BE6}")
$IID_IWindows = GUID$("{9B371833-5E4F-4B72-A8F6-CB8E762999F4}")
$IID__IICAClientEvents = GUID$("{238F6F82-B8B4-11CF-8771-00A024541EE3}")
$IID__IKeyboardEvents = GUID$("{8A5961DF-314E-4B7C-B57F-AAF35EA33079}")
$IID__IMouseEvents = GUID$("{24013613-FF51-4B50-9832-37FA561594ED}")
$IID__IScreenShotEvents = GUID$("{785A16E9-4E42-4C87-84AD-BFB4A60570A3}")
$IID__ISessionEvents = GUID$("{24FD31DB-3560-4C78-8950-30F03352D830}")
$IID__IWindowEvents = GUID$("{49813E6D-17FF-41A1-9A7B-95C3D5B44185}")


I tried the following to send a keystroke:
Code:
   GUID4String(CLSID_Keyboard, "{B5D6ED13-EDAA-4C2C-B2E2-26FD9BC1C710}")
   GUID4String(IID_IKeyboard, "{17BFCA0A-C42E-4AC9-A693-29473FF9BA6C}")

   puh := CreateObject(CLSID_Keyboard, IID_IKeyboard)
   VK = 65
   DllCall(VTable(piT, 7), "Uint", piT, "Long", VK, "Long")


But the puh variable always contains 0 instead of a valid identifiert.
What am I missing and what do I wrong?

I read through many articles containg cohelper and got that far but no further :-(


here is the original function as revealed with TypeLib browser
Code:
' ****************************************************************************************
' SendKeyUp method
' Interface name = IKeyboard
' method SendKeyUp
' VTable offset = 32 [&H20]
' DispID = 101 [&H00000065]
' ****************************************************************************************
FUNCTION CitrixIKeyboard_SendKeyUp ALIAS "CitrixIKeyboard_SendKeyUp" ( _
    BYVAL pthis AS DWORD PTR _                          ' %VT_DISPATCH <dispinterface>
  , BYVAL keyId AS LONG _                               ' %VT_I4 <LONG> [in]
    ) EXPORT AS LONG                                    ' %VT_HRESULT <LONG>

    LOCAL HRESULT AS LONG
    IF pthis = 0 THEN FUNCTION = %E_POINTER : EXIT FUNCTION
    CALL DWORD @@pthis[8] USING CitrixIKeyboard_SendKeyUp(pthis, keyId) TO HRESULT
    FUNCTION = HRESULT

END FUNCTION


Any help is appreciated!

n/b: I never used cohelper nor Citrix before. So both is new to me.

Thanks alot,
FlowPEE


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 27th, 2007, 1:09 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
I don't use citrix, but I got the typelib of it. Try the following.
If still not working, tell me the ErrorLevel and A_LastError.
And, make sure there exists a registry key HKEY_CLASSES_ROOT\CLSID\{B5D6ED13-EDAA-4C2C-B2E2-26FD9BC1C710}.

Code:
#Include CoHelper.ahk

CoInitialize()
pica := ActiveXObject("Citrix.ICAClient")

If !Invoke(pica, "IsKeyboardInputEnabled")
    Invoke(pica, "EnableKeyboardInput")

GUID4String(CLSID_Keyboard, "{B5D6ED13-EDAA-4C2C-B2E2-26FD9BC1C710}")
GUID4String( IID_IKeyboard, "{17BFCA0A-C42E-4AC9-A693-29473FF9BA6C}")

pkey := CreateObject(CLSID_Keyboard, IID_IKeyboard)
;MsgBox, % ErrorLevel . " | " . A_LastError
VK = 65
DllCall(VTable(pkey, 7), "Uint", pkey, "int", VK)
/*
VarSetCapacity(var, 16, 0)
NumPut( 3, var, 0)
NumPut(VK, var, 8)
Invoke(pkey, "SendKeyDown", var)
*/

Release(pkey)
Release(pica)
CoUninitialize()


PS. I updated CoHelper.ahk, so please recopy it. And, it needs AHK 1.0.47.00.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 27th, 2007, 10:23 am 
Offline

Joined: February 28th, 2007, 7:23 pm
Posts: 14
Sean,

thanks for your reply !

Unfortuanetely, that is not working.
ErrorLevel contains 0 and A_LastError contains 1008.

The reg key does NOT exist. Maybe there is the/a problem?
Why is the CLSID not registered and do I have a chance to
add it to the registry?

I tried your script with the new cohelper.ahk and the new AHK.

Do you need something else from me to support you?

Thanks for your help,

Florian

EDIT: btw, when I do e.g.
Code:
bla := Invoke(pica, "GetScreenWidth")
MsgBox %bla%

I do successfully get a result, namely 1280


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 27th, 2007, 11:31 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
FlowPEE wrote:
The reg key does NOT exist. Maybe there is the/a problem?
Why is the CLSID not registered and do I have a chance to
add it to the registry?

I see. Actually that's what I suspected from the lack of the corresponding ProgIDs.
Then, the following is the only remained one I can think of.
If it doesn't work, you may have to consult the support service of Citrix.

Code:
#Include CoHelper.ahk
CoInitialize()
pica := ActiveXObject("Citrix.ICAClient")
pssn := Invoke(pica, "Session")
pkey := Invoke(pssn, "Keyboard")

VK = 65
VarSetCapacity(var, 16, 0), NumPut(3, var, 0), NumPut(VK, var, 8)
Invoke(pkey, "SendKeyDown", var) ; Invoke(pkey, "SendKeyUp", var)

Release(pkey)
Release(pssn)
Release(pica)
CoUninitialize()

PS. May need to add the following after pica:

Code:
If !Invoke(pica, "IsKeyboardInputEnabled")
    Invoke(pica, "EnableKeyboardInput")


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 27th, 2007, 12:11 pm 
Offline

Joined: February 28th, 2007, 7:23 pm
Posts: 14
Sean,

that didn't work either :-(

So I guess I have to find a way to talk to Citrix support.
Thanks alot for your help though!

Flo


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 27th, 2007, 12:37 pm 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
FlowPEE wrote:
that didn't work either :-(

Sorry to hear that...
BTW, exactly which step not worked? pssn or pkey?
Anyway, if you find a working script in any language like VBS, that could be of help.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 27th, 2007, 9:08 pm 
Offline

Joined: June 27th, 2007, 9:07 pm
Posts: 101
Location: California
Amazing Sean! Not only have you provided support for COM early binding, but also late binding, and all in native AHK! :shock:

I've attempted to do a similar thing with another scripting language I use, but my high expectations turned it into a gross mess (I didn't want to require the API user to understand/deal with VARIANTs).

I owe you much for your posts because it helped me understand enough of the raw workings of COM to finally use it myself.

For the longest time I've wanted a super easy method to work with COM in my scripting languages. I assumed it was complicated, so I thought it would be nice if someone could at least make a small DLL to handle the dirty work. It has surprised me that no one ever has (or have they?).

Now that I know enough to do so, I'm putting together a DLL to do that very thing. It meets my needs well since I can use it in any language that loads DLLs. Plus, writing COM in C++ (or even C) is ridiculously easier than in a scripting language.

Since I have wanted this for so long, I'm curious if there's any other interest in a DLL like this.

Simple API usage example:
Code:
;; Required
hModule := DllCall("LoadLibrary", "str", "easycom.dll") 

;;; Set spVoice = CreateObject("SAPI.SpVoice")
spVoice := DllCall("easycom.dll\CreateObject", "str", "SAPI.SpVoice")

;;; iRet = spVoice.Speak("hello there", 0)
DllCall("easycom.dll\BeginMemberCall")
DllCall("easycom.dll\AddArgument", "int", TYPE_STR, "str", "hello there")
DllCall("easycom.dll\AddArgument", "int", TYPE_INT, "int", 0)
DllCall("easycom.dll\InvokeMethod", "int", spVoice, "str", "Speak")
iRet := DllCall("easycom.dll\GetReturn", "*int")
DllCall("easycom.dll\EndMemberCall")

;;; Set spVoice = Nothing
DllCall("easycom.dll\ReleaseObject", "int", spVoice)

DllCall("FreeLibrary", "UInt", hModule)

Still kinda messy I know, but at least there is no need to poke around in memory.

And after adding a few wrapper functions, down to 6 lines!
Code:
#include EasyCOM.ahk
LoadEasyCOM()

;;; Set spVoice = CreateObject("SAPI.SpVoice")
spVoice = CreateObject("SAPI.SpVoice")

;;; iRet = spVoice.Speak("hello there", 0)
iRet := Method(spVoice, "Speak", TYPE_STR, "hello there", TYPE_INT, 0)

;;; Set spVoice = Nothing
ReleaseObject(spVoice)

UnloadEasyCOM()


This small amount of code will be fully flexible for any class, any method/property, with any amount/types of arguments. And easycom.dll will likely be only around 100k.

If nothing else, thank you Sean for your input into this community. I'm really happy to finally have this available. :)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 28th, 2007, 1:05 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
erictheturtle wrote:
This small amount of code will be fully flexible for any class, any method/property, with any amount/types of arguments. And easycom.dll will likely be only around 100k.

Very interesting!
Does it care for the optional parameters too, I mean, if an user omits optional parameters then the dll fills them instead?
It would be quite helpful in some cases like Excel, where some functions expect lots of parameters and most of them are indeed optional.

Quote:
If nothing else, thank you Sean for your input into this community. I'm really happy to finally have this available. :)

Thank you and I'm glad to hear that I could be helpful.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 28th, 2007, 2:57 am 
Quote:
Since I have wanted this for so long,

Maybe most of people here have!

Quote:
I'm curious if there's any other interest in a DLL like this.


Do you really have to be curious? :D
From what I have seen from this thread, there is no quesiton about people being eager to have your EASYCOM.DLL

Personally I don't understand most of the details about raw COM object disscussed here, but I know some others and I want it!


Report this post
Top
  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic This topic is locked, you cannot edit posts or make further replies.  [ 156 posts ]  Go to page Previous  1 ... 4, 5, 6, 7, 8, 9, 10, 11  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 22 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