AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

DDE Server (for single-instance file association) [std-lib]
Goto page Previous  1, 2, 3, 4
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
majkinetor



Joined: 24 May 2006
Posts: 3626
Location: Belgrade

PostPosted: Tue Dec 04, 2007 10:14 am    Post subject: Reply with quote

2 Sean
What about IContextMenu ? Can it be LocalServer too or must be InProc (I don't recall ever seing it local). If dll is only option, then I guess Lex's dotNet caller can creeate it dynamicaly Laughing
_________________
Back to top
View user's profile Send private message MSN Messenger
AHKnow



Joined: 03 Jul 2004
Posts: 118

PostPosted: Tue Dec 04, 2007 10:49 am    Post subject: Reply with quote

Sean wrote:
lexikos wrote:
Very interesting.

It may be more interesting to create IDispatch AutoHotkey COM Server, I suppose.


The whole COM server idea is indeed very interesting. It opens up even more capabilities for AutoHotkey and COM.
Back to top
View user's profile Send private message
Sean



Joined: 12 Feb 2007
Posts: 1338

PostPosted: Tue Dec 04, 2007 3:02 pm    Post subject: Reply with quote

majkinetor wrote:
I don't recall ever seing it local.

Neither do I. I suspect it's not allowed.
Quote:
If dll is only option, then I guess Lex's dotNet caller can creeate it dynamicaly Laughing

I became very interested in .NET through the great work of lexikos. I'm wondering how well the explorer shell goes along with .NET.
Back to top
View user's profile Send private message
Sean



Joined: 12 Feb 2007
Posts: 1338

PostPosted: Tue Dec 04, 2007 3:03 pm    Post subject: Reply with quote

AHKnow wrote:
The whole COM server idea is indeed very interesting. It opens up even more capabilities for AutoHotkey and COM.

Agreed. BTW AHK is really amazing.
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3626
Location: Belgrade

PostPosted: Tue Dec 04, 2007 3:09 pm    Post subject: Reply with quote

You got great deal of sophistication when COM is in question.
I have read DropTarget and its very funny that in your work COM is easier to implement then in some higher languages Laughing . At least it seems to me so. Particualary nice thing is that you use the same function for entire VTable (I used the same method to subclas N controls with the same function, in ComboX).

Thx for everything.
_________________
Back to top
View user's profile Send private message MSN Messenger
majkinetor



Joined: 24 May 2006
Posts: 3626
Location: Belgrade

PostPosted: Tue Dec 04, 2007 3:56 pm    Post subject: Reply with quote

The bellow script merges everything above into single script that can be used to register, unregister and see behavior of entire process. This has nothing to do with DDE anymore.

To register shell context menu entery, open cmd and run script with /reg parameter. Run it with /unreg to unregister.

After you register it with shell, "AHK VERB TEST" will appear in menu. Select multiple files or folders and select mentioned menu entery to make the Explorer call the script.

U need COM.ahk to run this.

Code:
#persistent
   OnExit, DropTargetClose

   if 1 = /unreg
   {
      Shell_Unregister()
      MsgBox Shell verb unregistred
      ExitApp
   } else if 1=/reg
   {
      Shell_Register()
      MsgBox Shell verb registred
      ExitApp
   }

   Shell_Init()
Return

Shell_Register() {
   RegWrite, REG_SZ, HKCR, *\shell\AHK VERB TEST\DropTarget, CLSID, {83E7233E-4624-488F-9CBC-DFA2521AF2FA}
   RegWrite, REG_SZ, HKCR, Folder\shell\AHK VERB TEST\DropTarget, CLSID, {83E7233E-4624-488F-9CBC-DFA2521AF2FA}
   RegWrite, REG_SZ, HKCR, CLSID\{83E7233E-4624-488F-9CBC-DFA2521AF2FA}\LocalServer32,, "%A_AhkPath%" "%A_ScriptFullPath%"
}

Shell_UnRegister() {
   RegDelete, HKCR, *\shell\AHK VERB TEST
   RegDelete, HKCR, Folder\shell\AHK VERB TEST
   RegDelete, HKCR, CLSID\{83E7233E-4624-488F-9CBC-DFA2521AF2FA}
}

Shell_Init() {
   global
   If not Shell_nRegister := DropTargetOpen() {
      msgbox Shell init failed
      ExitApp
   }
}

GetData:
   msgbox % GetData(Shell_data)
   COM_Release(Shell_data), Shell_data   := ""
Return


DropTargetClose:
   DropTargetClose(Shell_nRegister)
ExitApp


DropTargetOpen(){
   static   IDropTarget, IClassFactory

   If not VarSetCapacity(IDropTarget)
   {
      VarSetCapacity(IDropTarget,36,0), NumPut(&IDropTarget+4,IDropTarget), nParams=3116516
      Loop, Parse, nParams
         NumPut(RegisterCallback("IDropTarget","",A_LoopField,A_Index-1),IDropTarget,4*A_Index)
   }
   If not VarSetCapacity(IClassFactory)
   {
      VarSetCapacity(IClassFactory,28,0), NumPut(&IClassFactory+4,IClassFactory), nParams=31142
      Loop,   Parse,   nParams
         NumPut(RegisterCallback("IClassFactory","",A_LoopField,A_Index-1), IClassFactory,4*A_Index)
   }
   NumPut(&IClassFactory,IDropTarget,32),   NumPut(&IDropTarget,IClassFactory,24)

   COM_Init()
   DllCall("ole32\CoRegisterClassObject", "Uint", COM_GUID4String(CLSID,"{83E7233E-4624-488F-9CBC-DFA2521AF2FA}"), "Uint", &IDropTarget, "Uint", 4, "Uint", 1, "UintP", Shell_nRegister)
   Return   Shell_nRegister
}

DropTargetClose(Shell_nRegister)
{
   DllCall("ole32\CoRevokeClassObject", "Uint", Shell_nRegister)
   COM_Term()
}

GetData(this)
{
   VarSetCapacity(FormatEtc,20,0), VarSetCapacity(StgMedium,12,0)
   NumPut(DllCall("RegisterClipboardFormat", "str", "Shell IDList Array"),FormatEtc,0), NumPut(0,FormatEtc,4), NumPut(1,FormatEtc,8), NumPut(-1,FormatEtc,12), NumPut(1,FormatEtc,16)
   
   DllCall(NumGet(NumGet(1*this)+12), "Uint", this, "Uint", &FormatEtc, "Uint", &StgMedium)   ; GetData
   hData:=   NumGet(StgMedium,4)
   pData:=   DllCall("GlobalLock", "Uint", hData)
   pidlP:=   pData+NumGet(pData+4), VarSetCapacity(sPath, 259)
   Loop, %   NumGet(pData+0)
      pidl:=DllCall("shell32\ILCombine", "Uint", pidlP, "Uint", pData+NumGet(pData+4+4*A_Index)), DllCall("shell32\SHGetPathFromIDListA", "Uint", pidl, "str", sPath), COM_CoTaskMemFree(pidl), sData .= sPath . "`n"
   DllCall("GlobalUnlock", "Uint", hData)
   DllCall("ole32\ReleaseStgMedium", "Uint", &StgMedium)
   Return   sData
}

IClassFactory(this, punk="", riid="", ppobj="")
{
   hResult   := 0
   If   A_EventInfo = 3
      NumPut(NumGet(this+24),ppobj+0)
   Else If   A_EventInfo = 0
      hResult   := DllCall(NumGet(NumGet(this+24)+4), "Uint", NumGet(this+24), "Uint", punk, "Uint", riid)
   Return   hResult
}

IDropTarget(this, pdata="", key="", x="", y="", peffect="")
{
   hResult   := 0
   If   A_EventInfo = 6
   {
      NumPut(NumGet(peffect+0)&5,peffect+0)
      Global   Shell_data   := pdata
      COM_AddRef(Shell_data)
      SetTimer, GetData, -100
   }
   Else If   A_EventInfo = 3
      NumPut(NumGet(peffect+0)&5,peffect+0)
   Else If   A_EventInfo = 0
      InStr("{00000122-0000-0000-C000-000000000046}{00000000-0000-0000-C000-000000000046}",IID:=COM_String4GUID(pdata)) ? NumPut(this,key+0) : IID="{00000001-0000-0000-C000-000000000046}" ? NumPut(NumGet(this+32),key+0) : hResult:=0x80004002
   Return   hResult
}


After some testing it seems that all above problems are fixed ("file not found", speed)
_________________
Back to top
View user's profile Send private message MSN Messenger
Lexikos



Joined: 17 Oct 2006
Posts: 2558
Location: Australia, Qld

PostPosted: Tue Dec 04, 2007 5:03 pm    Post subject: Reply with quote

majkinetor wrote:
If dll is only option, then I guess Lex's dotNet caller can creeate it dynamicaly Laughing
Honestly, if you were going to program a shell extension in .NET, why mix it with AutoHotkey at all? To provide a convenient installer.ahk...?
Sean wrote:
I'm wondering how well the explorer shell goes along with .NET.
I used QtTabBar (which uses .Net Framework 2.0) for a while on XP. It works well, but there's a bit of a delay opening the first Explorer window, as the CLR loads...

Actually, would it not be possible to write a DLL (in C++ or .Net) to act as an intermediary (class factory) for an AutoHotkey local server? The DLL itself should be small, and would allow the main implementation to be in AutoHotkey.

Now I ask myself "Why would you want to implement an in-proc COM server with AutoHotkey?" Mad
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3626
Location: Belgrade

PostPosted: Tue Dec 04, 2007 5:05 pm    Post subject: Reply with quote

Quote:
Honestly, if you were going to program a shell extension in .NET, why mix it with AutoHotkey at all? To provide a convenient installer.ahk...?

I like to have possibilities, thats all. I didn't say I will do the things you mention above.

Quote:
Now I ask myself "Why would you want to implement an in-proc COM server with AutoHotkey?"

How about, just for fun Idea
_________________
Back to top
View user's profile Send private message MSN Messenger
Sean



Joined: 12 Feb 2007
Posts: 1338

PostPosted: Wed Dec 05, 2007 12:22 am    Post subject: Reply with quote

lexikos wrote:
I used QtTabBar (which uses .Net Framework 2.0) for a while on XP. It works well, but there's a bit of a delay opening the first Explorer window, as the CLR loads...

That's good to know. Thanks.

Quote:
Actually, would it not be possible to write a DLL (in C++ or .Net) to act as an intermediary (class factory) for an AutoHotkey local server? The DLL itself should be small, and would allow the main implementation to be in AutoHotkey.

Looks like you're talking about the in-process handler. As a matter of fact, the first thing hit me was Windows Media Player's deskband when you said about deskband, which I suspected might use it. But, it turned out in-process server which is the only one allowed for deskband. BTW, from the programming point of view, I believe there is not much difference between in-process server and handler. So: why not just write a full fledged in-process server and open an IPC channel with AHK, which could be COM again.
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2558
Location: Australia, Qld

PostPosted: Wed Dec 05, 2007 12:55 am    Post subject: Reply with quote

Sean wrote:
So: why not just write a full fledged in-process server and open an IPC channel with AHK, which could be COM again.
I'd thought of that, but if the main implementation is in another language, I see no reason to use AutoHotkey at all. (A while back I started a C++ project implementing a desk band, but kind of lost interest...)
Back to top
View user's profile Send private message
Sean



Joined: 12 Feb 2007
Posts: 1338

PostPosted: Wed Dec 05, 2007 11:26 am    Post subject: Reply with quote

I added Dispatch.ahk for Dispatch COM Server to AutoHotkeyVerb.ahk. Please rerun RegisterVerb.ahk to register the Server. Currently it implements only one function, AppExit.

Example:
Code:
COM_Init()
pahk := COM_CreateObject("AutoHotkey.Application")
MsgBox, % COM_Invoke(pahk, "Exit")
MsgBox, % COM_Invoke(pahk, "AppExit")
COM_Term()
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2558
Location: Australia, Qld

PostPosted: Sun Jan 13, 2008 3:31 am    Post subject: Reply with quote

Any clue how to get Dispatch.ahk to work with VBscript?
Code:
COM_Init()
ahk := COM_CreateObject("AutoHotkey.Application")
COM_Invoke(ahk, "SomeFunc", "testing", 1, 2)
COM_Invoke(ahk, "AppExit")
COM_Release(ahk)
works, but
Code:
Set ahk = CreateObject("AutoHotkey.Application")
ahk.SomeFunc "testing", 1, 2
ahk.AppExit
just gives me
Quote:
Error: ActiveX component can't create object: 'AutoHotkey.Application'

Edit: Seems it might've been a Vista registry virtualization issue. I guess RegisterVerb.ahk and my test.ahk both were accessing a virtualized key, while the VBscript wasn't. I went looking for the AutoHotkey.Application subkey under HKEY_CLASSES_ROOT in regedit, but couldn't find it. Confused

Now when I try to create the object, I get:
Quote:
Script: Z:\test.vbs
Line: 1
Char: 1
Error: Invalid access to memory location.
Code: 800703E6
Source: (null)
Back to top
View user's profile Send private message
Sean



Joined: 12 Feb 2007
Posts: 1338

PostPosted: Sun Jan 13, 2008 4:41 am    Post subject: Reply with quote

lexikos wrote:
Now when I try to create the object, I get:
Quote:
Script: Z:\test.vbs
Line: 1
Char: 1
Error: Invalid access to memory location.
Code: 800703E6
Source: (null)

For the moment, use WScript.CreateObject instead of VBS's CreateObject, it seems to work.

IDispatch and IClassFactory were implemented to the minimum necessary as I had in mind only AutoHotkey.exe to use AutoHotkey.Application. To use it with other scripting engines, I think the interfaces should be fully implemented like COM_DispInterface(). And, should also assign separate DispIDs for the custom functions as some scripting engines cache DispIDs for the performance.

PS. Is there no way to disable the notification mails for whole (already notification-enabled) threads instead of one-by-one?
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2558
Location: Australia, Qld

PostPosted: Sun Jan 13, 2008 5:48 am    Post subject: Reply with quote

Sean wrote:
For the moment, use WScript.CreateObject instead of VBS's CreateObject, it seems to work.
Thanks. Smile
Quote:
To use it with other scripting engines, I think the interfaces should be fully implemented like COM_DispInterface(). And, should also assign separate DispIDs for the custom functions as some scripting engines cache DispIDs for the performance.
That certainly wasn't the issue in this case. I logged the calls to interface members; basically it was:
  • IClassFactory.AddRef()
  • IClassFactory.QueryInterface(IID_IClassFactory)
  • IClassFactory.Release()
  • IClassFactory.AddRef()
  • IClassFactory.Release()
  • IClassFactory.QueryInterface(IID_IMarshal)
  • IClassFactory.Release()
...repeated eleven times, then an Access Violation would occur in ole.dll (iirc), attempting to read address 0x0. Confused

Quote:
PS. Is there no way to disable the notification mails for whole (already notification-enabled) threads instead of one-by-one?
Other than changing the e-mail address associated with your profile, I'm not sure.
Back to top
View user's profile Send private message
Sean



Joined: 12 Feb 2007
Posts: 1338

PostPosted: Sun Jan 13, 2008 7:59 am    Post subject: Reply with quote

lexikos wrote:
then an Access Violation would occur in ole.dll (iirc), attempting to read address 0x0. Confused

I updated Dispatch.ahk. And I changed the name AppExit to Quit to accord with other well-known local servers.

It's still not rigorous implementation, so can go wrong with other scripting engines, then please post here. I'll leave this thread as notification-on.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page Previous  1, 2, 3, 4
Page 4 of 4

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group