AutoHotkey Community

It is currently May 27th, 2012, 11:07 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 70 posts ]  Go to page Previous  1, 2, 3, 4, 5
Author Message
 Post subject:
PostPosted: February 9th, 2012, 1:09 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Thank you for your patience ;)
I think I got it finally :roll:
Please test :)
Code:
#include <FileGetVersionInfo>
AhkDllThread(dll="AutoHotkey.dll",obj=0){
   static init,ahkfunction,hLib,ahkexec,DynaCall:="DynaCall", MemoryLoadLibrary:="MemoryLoadLibrary",MemoryFreeLibrary:="MemoryFreeLibrary"
         ,ResourceLoadLibrary:="ResourceLoadLibrary", MemoryGetProcAddress:="MemoryGetProcAddress"
   static AHK_H:=A_IsCompiled?1:FileGetVersionInfo_AW(A_AhkPath,"InternalName")="AutoHotkey_H"
   static base:={__Delete:"AhkDllThread"}
   static functions ="
(Join
ahkKey:s|ahkFunction:s=sssssssssss|ahkPostFunction:i=sssssssssss|
ahkdll:ut=sss|ahktextdll:ut=sss|ahkReady:|ahkReload:ui=|
ahkTerminate:i|addFile:ut=sucuc|addScript:ut=si|ahkExec:ui=s|
ahkassign:ui=ss|ahkExecuteLine:ut=utuiui|ahkFindFunc:ut=s|
ahkFindLabel:ut=s|ahkgetvar:s=sui|ahkLabel:ui=sui|ahkPause:s
)"
   static AhkDllThreadfunc ="
(Join`r`n
#Persistent
#NoTrayIcon
Return
AhkDllThread(dll=""AutoHotkey.dll"",obj=0,map=""""){
   static functions = ""ahkKey:s|ahkFunction:s=sssssssssss|ahkPostFunction:i=sssssssssss|""
                     . ""ahkdll:ut=sss|ahktextdll:ut=sss|ahkReady:|ahkReload:ui=|""
                     . ""ahkTerminate:i|addFile:ut=sucuc|addScript:ut=si|ahkExec:ui=s|""
                     . ""ahkassign:ui=ss|ahkExecuteLine:ut=utuiui|ahkFindFunc:ui=s|""
                     . ""ahkFindLabel:ui=s|ahkgetvar:s=sui|ahkLabel:ui=sui|ahkPause:s""
   If (dll=""0"")
      return object:=""""
   else If dll is digit
      return MemoryFreeLibrary(dll)
   else If (!FileExist(dll)){
      MsgBox File: `%dll`% does not exist`, provide correct path for AutoHotkey.dll
      ExitApp
   }
   object:=IsObject(obj)?obj:{},object[""""]:= MemoryLoadLibrary(dll)
   Loop,Parse,functions,|
   {
      StringSplit,v,A_LoopField,:
      object[map="""" ? v1 : !InStr(map,v1) ? v1 : SubStr(map,InStr(map,v1)+StrLen(v1)+1,InStr(map,A_Space,0,InStr(map,v1)))]:=DynaCall(MemoryGetProcAddress(object[""""],v1),v2)
   }
   object.base:=Object(" (&base) ")
   return &object
}
)"
   If IsObject(dll){
      dll.ahkterminate()
      If !AHK_H{
         DllCall(ahkfunction,"Str","AhkDllThread","Str",dll[""],"Str","","Str","","Str","","Str","","Str","","Str","","Str","","Str","","Str","","CDecl Str")
      } else %MemoryFreeLibrary%(dll[""])
      return
   } else if (!FileExist(dll) && !A_IsCompiled){
      MsgBox File: %dll%`ndoes not exist`, provide correct path for AutoHotkey.dll
      ExitApp
   }
   If !AHK_H{
      If (init || ((hLib:=DllCall("LoadLibrary","Str",dll)) && (Init:=DllCall("GetProcAddress","PTR",hLib,"Astr","ahktextdll","PTR")))){
         If (ahkfunction || (DllCall(init,"Str",AhkDllThreadfunc,"Str","","Str","","Cdecl UInt") && (ahkfunction:=DllCall("GetProcAddress","PTR",hLib,"Astr","ahkFunction","PTR")) && (ahkExec:=DllCall("GetProcAddress","PTR",hLib,"Astr","ahkExec","PTR")))){
            return Object(0+DllCall(ahkfunction,"Str","AhkDllThread","Str",dll,"Str","","Str","","Str","","Str","","Str","","Str","","Str","","Str","","Str","","CDecl Str"))
            ;reset internal memory in autoHotkey.dll
            ,DllCall(ahkfunction,"Str","AhkDllThread","Str","0","Str","","Str","","Str","","Str","","Str","","Str","","Str","","Str","","Str","","CDecl Str")
         } else {
            MsgBox Could not load script in %dll%
            Return 0
         }
      } else {
         MsgBox Could not load %dll%
         Return 0
      }
   }
   object:=IsObject(obj)?obj:{},object[""]:= A_IsCompiled ? %ResourceLoadLibrary%(dll) : %MemoryLoadLibrary%(dll)
   Loop,Parse,functions,|
   {
      StringSplit,v,A_LoopField,:
      object[map="" ? v1 : !InStr(map,v1) ? v1 : SubStr(map,InStr(map,v1)+StrLen(v1)+1,InStr(map,A_Space,0,InStr(map,v1)))]:=%DynaCall%(%MemoryGetProcAddress%(object[""],v1),v2)
   }
   return object,object.base:=base
}

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 9th, 2012, 1:38 pm 
HotKeyIt wrote:
Thank you for your patience ;)
That's what I have to say. Thanks. :)
Quote:
I think I got it finally :roll:
Please test :)
This time it doesn't crash but it doesn't seem to free the memory with _L. The memory usage stays around 20mb.

This is the code I ran. Works perfectly with _H though.
Code:
#Noenv
SetWorkingDir %A_ScriptDir%
#persistent
#include <AhkDllThread>
oThreads := []   

if !FileExist(strDllLocation := A_PtrSize = 8 ? A_ScriptDir "\AutoHotkey64.dll" : A_ScriptDir "\AutoHotkey32.dll") {
   msgbox The autohotkey.dll is not found.
   ExitApp
}
loop 15
{
   oThreads[A_Index]:=AhkDllThread(strDllLocation)
   oThreads[A_Index].ahktextdll("
   (Ltrim
      #NoTrayIcon
      msgbox " A_Index "
      ExitApp
   )")
}
Process, Exist
MsgBox Check memory of PID %ErrorLevel% now, click OK to unload dlls.
loop 15
   oThreads[A_Index].ahkterminate(), oThreads[A_Index] := ""
MsgBox Memory freed.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: February 9th, 2012, 2:24 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
I am we'll get it in the end :)
Code:
#include <FileGetVersionInfo>
AhkDllThread(dll="AutoHotkey.dll",obj=0){
   static init,ahkfunction,hLib,ahkexec,DynaCall:="DynaCall", MemoryLoadLibrary:="MemoryLoadLibrary",MemoryFreeLibrary:="MemoryFreeLibrary"
         ,ResourceLoadLibrary:="ResourceLoadLibrary", MemoryGetProcAddress:="MemoryGetProcAddress"
   static AHK_H:=A_IsCompiled?1:FileGetVersionInfo_AW(A_AhkPath,"InternalName")="AutoHotkey_H"
   static base:={__Delete:"AhkDllThread"}
   static functions ="
(Join
ahkKey:s|ahkFunction:s=sssssssssss|ahkPostFunction:i=sssssssssss|
ahkdll:ut=sss|ahktextdll:ut=sss|ahkReady:|ahkReload:ui=|
ahkTerminate:i|addFile:ut=sucuc|addScript:ut=si|ahkExec:ui=s|
ahkassign:ui=ss|ahkExecuteLine:ut=utuiui|ahkFindFunc:ut=s|
ahkFindLabel:ut=s|ahkgetvar:s=sui|ahkLabel:ui=sui|ahkPause:s
)"
   static AhkDllThreadfunc ="
(Join`r`n
#Persistent
#NoTrayIcon
Return
AhkDllThread(dll=""AutoHotkey.dll"",obj=0,map=""""){
   static functions = ""ahkKey:s|ahkFunction:s=sssssssssss|ahkPostFunction:i=sssssssssss|""
                     . ""ahkdll:ut=sss|ahktextdll:ut=sss|ahkReady:|ahkReload:ui=|""
                     . ""ahkTerminate:i|addFile:ut=sucuc|addScript:ut=si|ahkExec:ui=s|""
                     . ""ahkassign:ui=ss|ahkExecuteLine:ut=utuiui|ahkFindFunc:ui=s|""
                     . ""ahkFindLabel:ui=s|ahkgetvar:s=sui|ahkLabel:ui=sui|ahkPause:s""
   If (dll=""0"")
      return object:=""""
   else If (!FileExist(dll)){
      MsgBox File: `%dll`% does not exist`, provide correct path for AutoHotkey.dll
      ExitApp
   }
   object:=IsObject(obj)?obj:{},object[""""]:= MemoryLoadLibrary(dll)
   Loop,Parse,functions,|
   {
      StringSplit,v,A_LoopField,:
      object[map="""" ? v1 : !InStr(map,v1) ? v1 : SubStr(map,InStr(map,v1)+StrLen(v1)+1,InStr(map,A_Space,0,InStr(map,v1)))]:=DynaCall(MemoryGetProcAddress(object[""""],v1),v2)
   }
   object.base:=Object(" (&base) ")
   return &object
}
)"
   If IsObject(dll){
      dll.ahkterminate()
      If !AHK_H{
         DllCall(ahkExec,"Str","MemoryFreeLibrary(" dll[""] ")")
      } else %MemoryFreeLibrary%(dll[""])
      return
   } else if (!FileExist(dll) && !A_IsCompiled){
      MsgBox File: %dll%`ndoes not exist`, provide correct path for AutoHotkey.dll
      ExitApp
   }
   If !AHK_H{
      If (init || ((hLib:=DllCall("LoadLibrary","Str",dll)) && (Init:=DllCall("GetProcAddress","PTR",hLib,"Astr","ahktextdll","PTR")))){
         If (ahkfunction || (DllCall(init,"Str",AhkDllThreadfunc,"Str","","Str","","Cdecl UInt") && (ahkfunction:=DllCall("GetProcAddress","PTR",hLib,"Astr","ahkFunction","PTR")) && (ahkExec:=DllCall("GetProcAddress","PTR",hLib,"Astr","ahkExec","PTR")))){
            return Object(0+DllCall(ahkfunction,"Str","AhkDllThread","Str",dll,"Str","","Str","","Str","","Str","","Str","","Str","","Str","","Str","","Str","","CDecl Str"))
            ;reset internal return memory in autoHotkey.dll and release object
            ,DllCall(ahkfunction,"Str","AhkDllThread","Str","0","Str","","Str","","Str","","Str","","Str","","Str","","Str","","Str","","Str","","CDecl Str")
         } else {
            MsgBox Could not load script in %dll%
            Return 0
         }
      } else {
         MsgBox Could not load %dll%
         Return 0
      }
   }
   object:=IsObject(obj)?obj:{},object[""]:= A_IsCompiled ? %ResourceLoadLibrary%(dll) : %MemoryLoadLibrary%(dll)
   Loop,Parse,functions,|
   {
      StringSplit,v,A_LoopField,:
      object[map="" ? v1 : !InStr(map,v1) ? v1 : SubStr(map,InStr(map,v1)+StrLen(v1)+1,InStr(map,A_Space,0,InStr(map,v1)))]:=%DynaCall%(%MemoryGetProcAddress%(object[""],v1),v2)
   }
   return object,object.base:=base
}
Btw.
Code:
loop 15
   oThreads[A_Index].ahkterminate(), oThreads[A_Index] := ""
; Should be
While % oThreads.MaxIndex() ; Can be Loop 15 as well
   oThreads.Remove() ; Thread will be terminated internally as well
; Alternatively
loop 15
   oThreads[16-A_Index] := ""

This is because when you remove an item, index gets updated so 2 becomes 1, 3 becomes 2 and so on

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 9th, 2012, 3:35 pm 
It's working. :) Nice job.
HotKeyIt wrote:
This is because when you remove an item, index gets updated so 2 becomes 1, 3 becomes 2 and so on
I see. Thanks for the tip.

Code:
#Noenv
SetWorkingDir %A_ScriptDir%
#persistent
#include <AhkDllThread>
oThreads := []   

if !FileExist(strDllLocation := A_PtrSize = 8 ? A_ScriptDir "\AutoHotkey64.dll" : A_ScriptDir "\AutoHotkey32.dll") {
   msgbox The autohotkey.dll is not found.
   ExitApp
}
loop 15
{
   oThreads[A_Index]:=AhkDllThread(strDllLocation)
   oThreads[A_Index].ahktextdll("
   (Ltrim
      #NoTrayIcon
      msgbox " A_Index "
      ExitApp
   )")
}
Process, Exist
MsgBox Check memory of PID %ErrorLevel% now, click OK to unload dlls.
While % oThreads.MaxIndex() ; Can be Loop 15 as well
   oThreads.Remove() ; Thread will be terminated internally as well 
MsgBox Memory freed.


This one works nicely as well.
Code:
#Noenv
#singleinstance, Force
#persistent
SetWorkingDir %A_ScriptDir%

#include <AhkDllThread>

;make it super global for testing to see the number of thread objects in the function
global oThreads := []   
loop 15
   MsgboxInThread(A_Index)
Return

;Press F1 to see the current number of thread objects in the function
F1::msgbox % oThreads.maxindex()     

MsgboxInThread(param, strDllLocation=".\AutoHotkey.dll") {
   static strDllLoc, oThreadRemove:=[] ;, oThreads := []
   strDllLoc := strDllLoc ? strDllLoc : strDllLocation
   oThreads.Insert(AhkDllThread(strDllLocation))
   oThreads[oThreads.MaxIndex()].ahktextdll("
   (Ltrim
      #NoTrayIcon
      msgbox " param "
      ExitApp
   )")

   SetTimer, MsgboxInThread_TerminateThread, 1000
   Return
   MsgboxInThread_TerminateThread:
      For index, oThread in oThreads {
         If !oThread.ahkReady() {
            oThread.ahkterminate()
            oThread := ""
            oThreadRemove.Insert(index)
         }
      }
      Loop % oThreadRemove.MaxIndex()
         oThreads.Remove(oThreadRemove[A_Index])
      if !oThreads.MaxIndex()
         SetTimer,, Off   
   Return
}


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: February 9th, 2012, 4:00 pm 
I noticed that the new version of AhkDllThread is faster in _L. Thanks HotKeyIt.

Another question.

Is it possible to run a traytip in a thread as if it appears from the main thread's tray icon? If this isn't easy, never mind. The reason is that when the task bar is set to auto-hide, the Traytip command halts the script while the task bar is appearing. It's for merely a second so it's not a big deal but I asked just in case you may know how.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: February 9th, 2012, 4:02 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Awesome, I have updated AhkDllThread thread and downloads :)

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 9th, 2012, 4:15 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
You would have to use TT() ;)
Code:
dll:=AhkDllThread(".\AutoHotkey.dll")
dll.ahktextdll("
         (LTrim
         #NoTrayIcon
         TT:=TT(""Balloon"")
         ShowToolTip:
         TT.Show(""Hello"",""TrayIcon"",""TrayIcon"",""Welcome"")
         SetTimer,HideToolTip,-5000
         Return
         HideToolTip:
         TT.Hide()
         Return
         )")
dll.ahkLabel("ShowToolTip",1)
Loop
   ToolTip % A_Now
Escape::ExitApp

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Last edited by HotKeyIt on February 10th, 2012, 12:42 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 10th, 2012, 9:49 am 
Hi HotKeyIt,

Thanks for the code but I encountered some problems. I use _L 1.1.05.06 Unicode 32bit.

1. It seems sizeof.ahk, _Struc.ahk, and TT.ahk have to be in C:\Program Files\AutoHotkey\lib. If they are placed in the lib forlder of the script directory, the thread script does not recognize them.
2. The script crashes after exiting the thread script.
3. The traytip does not appear from the main thread tray icon but the dll thread script icon. Also when the taskbar is hidden with the auto-hide setting it does not activate the taskbar and the tray icon.

I'm not so serious about achieving this task so if it's too much for you, please do not take time for this issue. I just expect short comments and your insight on this.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: February 10th, 2012, 12:27 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Quote:
1. It seems sizeof.ahk, _Struc.ahk, and TT.ahk have to be in C:\Program Files\AutoHotkey\lib. If they are placed in the lib forlder of the script directory, the thread script does not recognize them.
That is correct, this is because ahktextdll uses the path of AutoHotkey.exe as A_ScriptDir or any other program starting AutoHotkey.dll.
Code:
2. The script crashes after exiting the thread script.
You mean exiting using Escape?
Quote:
3. The traytip does not appear from the main thread tray icon but the dll thread script icon. Also when the taskbar is hidden with the auto-hide setting it does not activate the taskbar and the tray icon.
Sorry forgot to add #NoTrayIcon.
Taskbar is not activated on purpose.

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 10th, 2012, 12:45 pm 
HotKeyIt wrote:
2. The script crashes after exiting the thread script.[/code]You mean exiting using Escape?
Ah, that also makes script crash. I meant the dll thread though. Since the code does not have #NoTrayIcon, it can be exited via the tray menu. Also changing the Return command to ExitApp causes the script to crash.


Report this post
Top
  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 70 posts ]  Go to page Previous  1, 2, 3, 4, 5

All times are UTC [ DST ]


Who is online

Users browsing this forum: BrandonHotkey, Edd, Exabot [Bot], Google [Bot], HotkeyStick and 12 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