AHK v2

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

just me
Posts: 6060
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: AHK v2

15 Mar 2016, 05:28

Ja, da hast Du natürlich recht! :facepalm:
User avatar
fump2000
Posts: 313
Joined: 04 Oct 2013, 17:31

Re: AHK v2

15 Mar 2016, 05:33

Hast du das mit v2 getestet?
Klappt bei mir nicht.

Code: Select all

#NoEnv
#Persistent
#SingleInstance force

script=
(
#Persistent
#SingleInstance force

F4::
MsgBox Hello World!
Return

F6::
MsgBox % A_AhkVersion " " (A_IsUnicode ? "Unicode" : "ANSI") " " (A_PtrSize * 8) "-bit    (" (A_IsCompiled ? ".exe" : ".ahk") ")`nPID: " DllCall("GetCurrentProcessId")
Return
)

DllCall("LoadLibrary","Str",ahkdll:=A_ScriptDir "\AutoHotkey.dll")
hNewThread := DllCall(ahkdll "\ahktextdll","Str",script,"Str","","CDecl")
PID := DllCall("GetCurrentProcessId")

msgbox %PID%
"Error: This parameter contains a variable name missing its ending percent sign."

Aber davon ab, weder ProcessExist() noch DllCall("GetCurrentProcessId") liefern mir eine PID. Ich frag mich wie man das lösen soll???

Es muss doch auch hier eine PID geben auch wenn das Script per DLL geladen wurde oder?
just me
Posts: 6060
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: AHK v2

15 Mar 2016, 05:56

Ah, es liegt an Deiner 'continuation section' -> Eine lange Zeile in mehreren kurzen Zeilen aufteilen. Wenn die %-Zeichen enthält, musst Du die Option % setzen, wenn AHK nicht versuchen soll, die aufzulösen. Anderenfalls kannst Du sie auch 'escapen': `%.
User avatar
fump2000
Posts: 313
Joined: 04 Oct 2013, 17:31

Re: AHK v2

15 Mar 2016, 06:02

In v1 macht die Zeile keine Probleme...
In v2 aber doch... und dennoch erscheint keine PID.

Ich verzweifel hier noch :)
just me
Posts: 6060
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: AHK v2

15 Mar 2016, 06:09

Hallo Fump,

Deine continuation section wird ja in v1 auch nicht als Skript ausgeführt! Schau Dir in v1 doch einfach einmal per MsgBox, %script% an, was da tatsächlich übergeben wird:

Code: Select all

#NoEnv
#Persistent
#SingleInstance ignore

script=
(
#Persistent
#SingleInstance ignore

F4::
MsgBox Hello World!
Return

F6::
PID := DllCall("GetCurrentProcessId")
Msgbox %PID%
Return
)

MsgBox, %script%
User avatar
fump2000
Posts: 313
Joined: 04 Oct 2013, 17:31

Re: AHK v2

15 Mar 2016, 06:17

Okay, verstehe.
Jedoch ist das hinderlich für mein vorhaben. Ich will ja eigentlich schon ein komplexeres Script als Variable per v2 DLL laden.

Jetzt funktioniert natürlich auch der Funktionsaufruf, dabei stelle ich fest, dass die PID aus dem v2 Script die gleiche ist wie die aus dem v1 Script? Kann das wirklich so sein? Weil die v1 die DLL aufruft läuft sie unter der selben PID?

Kann man das mit dem laden von komplexeren Scripten per Variable und DLL irgendwie bewerkstelligen oder mss ich wenn ich das so will alles Escapen?
just me
Posts: 6060
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: AHK v2

15 Mar 2016, 06:22

Hast Du Dir die % Option angesehen?

Und ja, Du startest ja einen neuen Thread, und der läuft innerhalb desselben Prozesses. Alternativ sollte es aber möglich sein, die zu AHK_H gehörige AutoHotkey.exe per Run zu starten und ihr die fertige Skriptdatei als Parameter zu übergeben. Dann hast Du auch einen getrennten Prozess.
User avatar
fump2000
Posts: 313
Joined: 04 Oct 2013, 17:31

Re: AHK v2

15 Mar 2016, 06:37

Angesehen ja, verstanden nein.

Nun, ich denke ich werde das v2 Script kompilieren. Dann habe ich ne eigene PID und kann auch einfacher per SendMessage Daten übergeben.

Im übrigen, danke für dein Tutorial bzgl. der Messages :)
just me
Posts: 6060
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: AHK v2

15 Mar 2016, 06:59

% (Prozentzeichen): Behandelt Prozentzeichen nicht als Variablenverweise, sondern als literale Zeichen.
Soll heißen, wenn die 'continuation section' %-Zeichen enthält, sorgt die %-Option dafür, dass sie wie jedes andere normale Zeichen behandelt werden und nicht versucht wird, sie als Variablenreferenzen zu interpretieren.

Der Unterschied:

Code: Select all

#NoEnv
#SingleInstance ignore

script1=
(
#Persistent
#SingleInstance ignore

F4::
MsgBox Hello World!
Return

F6::
PID := DllCall("GetCurrentProcessId")
Msgbox %PID%
Return
)

script2=
(%
#Persistent
#SingleInstance ignore

F4::
MsgBox Hello World!
Return

F6::
PID := DllCall("GetCurrentProcessId")
Msgbox %PID%
Return
)

MsgBox, 0, script1 (ohne `%-Option), %script1%
MsgBox, 0, script2 (mit `%-Option), %script2%
User avatar
fump2000
Posts: 313
Joined: 04 Oct 2013, 17:31

Re: AHK v2

15 Mar 2016, 07:05

Manchmal ist die Lösung doch sehr naheliegend... Ich danke dir!

Da das Script per DLL geladen wird und ja nun die selbe PID hat wie das auslösende Script, wie kann ich das Script beenden ohne das auslösende Script zu beeinflussen?
just me
Posts: 6060
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: AHK v2

15 Mar 2016, 07:09

Vielleicht gibt es in AHK_H auch eine Funktion, um die gestarteten Threads auch wieder vom startenden Thread aus zu beenden?
User avatar
fump2000
Posts: 313
Joined: 04 Oct 2013, 17:31

Re: AHK v2

15 Mar 2016, 07:15

Mit dem hier gehts:

Code: Select all

DllCall("FreeLibrary", "Ptr", hModule)
Beim laden dann halt so:

Code: Select all

hModule:=DllCall("LoadLibrary","Str",ahkdll:=A_ScriptDir "\AutoHotkey.dll")
Mit If !hModule könnte man nach dem Laden der DLL auch prüfen ob es erfolgreich war.


----

Nun die Frage der Datenweitergabe an das per DLL ausgeführte Script.
Habe es nun so versucht:

Code: Select all

#NoEnv
#Persistent
#SingleInstance force

hModule:=DllCall("LoadLibrary","Str",ahkdll:=A_ScriptDir "\AutoHotkey.dll")
DllCall(ahkdll "\ahkdll","Str",A_ScriptDir "\PWM_Translater.ahk","Str","")
PID := DllCall("GetCurrentProcessId")

ESC::
DllCall("FreeLibrary", "Ptr", hModule)
Return

F8::
Critical
scr:=PID
detecthiddenwindows,on
settitlematchmode,2
PostMessage, 0x5555, 2,1,,ahk_pid %scr%
detecthiddenwindows,off
settitlematchmode,1
Return
Zielscript:

Code: Select all

#Persistent
#SingleInstance ignore
OnMessage(0x5555, "Test")
Return

Test(wParam, lParam)
	{
		If (wParam=2 && lParam=1)
			msgbox
	}
Sollte das nicht eigentlich funktionieren?

In einem anderem Script von mir habe ich es so realisiert jedoch statt PID den namen der EXE verwendet.
Übersehe ich hier etwas offensichtliches?
Last edited by fump2000 on 15 Mar 2016, 09:55, edited 1 time in total.
User avatar
fump2000
Posts: 313
Joined: 04 Oct 2013, 17:31

Re: AHK v2

15 Mar 2016, 09:57

Wenn ich im Empfängerscript ein Fenster offen habe dann klappt es so... Jedoch nicht ohne Fenster.
Ich muss aber erstmal ohne Fenster da dran kommen damit sich das Fenster öffnet :)

Wie kann ich das lösen? Ich komm nicht drauf.
just me
Posts: 6060
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: AHK v2

15 Mar 2016, 10:05

Was willst Du denn übergeben?
User avatar
fump2000
Posts: 313
Joined: 04 Oct 2013, 17:31

Re: AHK v2

15 Mar 2016, 10:13

Nur Zahlen. Darauf soll das Zielscript reagieren indem in der Funktion ein Label aufgerufen wird. So wie im Beispiel angegeben.
just me
Posts: 6060
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: AHK v2

15 Mar 2016, 10:30

Wenn per AhkDll nur ein Thread ohne eigenen Prozess gestartet wird, sendest Du die Nachricht an das verborgene Hintergrundfenster des Hauptskripts, wenn kein anderes Fenster des Prozesses offen ist. Im Hauptskript gibt es keinen Messagehandler. Und vielleicht 'sieht' es den im anderen Thread auch nicht. Ob das so ist, weiß aber nur HotKeyIt.
User avatar
fump2000
Posts: 313
Joined: 04 Oct 2013, 17:31

Re: AHK v2

15 Mar 2016, 10:41

Dann frag ich ihn mal... Danke dir erstml :)
HotKeyIt
Posts: 1812
Joined: 29 Sep 2013, 18:35
Contact:

Re: AHK v2

15 Mar 2016, 12:18

OutPutVar := ProcessExist() oder ProcessExist, OutPutVar, ich werde die Dokumentation aktualisieren sobald ich dafür Zeit finde.
Es macht kein sinn die Nachricht an die pid zu senden wenn du die an einen bestimmten Thread senden willst da alle Threads die gleiche ahk_class benutzen (ahk_class AutoHotkey).
Du musst dafür A_ScriptHwnd benutzen!

Code: Select all

#Persistent
#SingleInstance force

ahkdll:=AhkThread("
(
#Persistent
#SingleInstance ignore
OnMessage(0x5555, "Test")
Return
 
Test(wParam, lParam)
{
    If (wParam=2 && lParam=1)
        msgbox
}
)")
dll_ScriptHwnd:=ahkdll.ahkgetvar("A_ScriptHwnd")

ESC::
ahkdll.ahkterminate()
ExitApp
Return
 
F8::PostMessage_(dll_ScriptHwnd,0x5555,2,1)
Es gibt viele Möglichkeiten Daten mit dem Thread auszutauschen, Send/PostMessage ist definitiv nicht die beste davon :)
Die gängigsten sind CriticalObject um einen Object zu teilen, Alias für variable und ObjShare wird gebraucht wenn du eine Klasse teilen willst und die Methoden aufrufen willst.
Hier gibt es mehr Infos zu AutoHotkey[Mini].dll.
User avatar
fump2000
Posts: 313
Joined: 04 Oct 2013, 17:31

Re: AHK v2

16 Mar 2016, 02:25

Hallo HotKeyIt,

dein Beispielscript wird ja mit v2 ausgeführt. Dann mag das ja alles kein Problem sein.
Wenn ich aber aus v1 heraus die v2 DLL nutzen will wird es anscheinend schon schwieriger.

A_ScriptHwnd gibt es in v1 zwar auch, ein PostMessage klappt aber nicht.

Code: Select all

F8::
Critical
scr:=A_ScriptHwnd
detecthiddenwindows,on
settitlematchmode,2
PostMessage, 0x5555, 2,1,,% scr
detecthiddenwindows,off
settitlematchmode,1
Return
All die Dinge die du nennst zum Datenaustausch gibt es in der v1 nicht :(

Ich starte das Script mit v2 so wie du gezeigt hast:

Code: Select all

hModule:=DllCall("LoadLibrary","Str",ahkdll:=A_ScriptDir "\AutoHotkey.dll")
DllCall(ahkdll "\ahkdll","Str",A_ScriptDir "\Translater.ahk","Str","")
Funktioniert auch soweit ganz gut. Das Script macht was es soll.
Aber es soll vom Hauptscript (v1) aus gesteuert werden daher muss ich irgendwie Daten übermitteln auf die das v2 Script reagiert.

Hast du dafür eine Lösung?

// EDIT:

Verstehe ich das richtig, dass die Alias() Funktion die Variable in beiden Threads zur verfügung stellt diese somit in beiden scripts zum Datenaustausch genutzt werden kann weil man ja per Timer prüfen kann ob sich etwas verändert hat?

Gibt es da eine Funktion um sie in v1 zu nutzen? In den Links die du hier gepostet hattest ist sie nicht dabei.
Wie muss der Thrad dann gestartet werden?
Am schönsten wäre es, das Script komplett als Variable im Hauptscript zu speichern und es dann per DLL zu laden. Hab ich nicht hinbekommen. Trotz Tipps von just me. Ansonsten würde ich es halt per AHK Datei an die DLL übergeben so wie oben beschrieben.
HotKeyIt
Posts: 1812
Joined: 29 Sep 2013, 18:35
Contact:

Re: AHK v2

16 Mar 2016, 06:09

Fast alle Funktionen und Features von v2 sind in v1 enthalten und kompatibel, in v1 sind jedoch die neuen Features nur als Funktion und nicht als Befehl verfügbar!
Also kannst du fast immer auf die v2 Dokumentation zurückgreifen.
Um zusätzlichen Code hinzuzufügen, kannst du entweder ahkExec oder addScript benutzen aber am besten ist es direkt ahktextdll zu benutzen.
Also anstatt: DllCall(ahkdll "\ahkdll" -> DllCall(ahkdll "\ahktextdll".
Z.B.:

Code: Select all

obj:=CriticalObject(["A","B","C"])
FileRead,Script,A_ScriptDir "\Translater.ahk"
DllCall("LoadLibrary","Str",ahkdll:=A_ScriptDir "\AutoHotkey.dll")
DllCall(ahkdll "\ahktextdll","Str","obj:=CriticalObject(" (&obj) ")`nMsgBox `% obj.2`n" Script,"Str","")
MsgBox End
Du musst auch die A_ScriptHwnd von dem anderen (dll) Thread benutzen und ahk_id hast du auch vergessen!

Code: Select all

F8::
Critical
scr:=DllCall(ahkdll "\ahkgetvar","Str","A_ScriptHwnd","UInt",0,"Str")
detecthiddenwindows,on
settitlematchmode,2
PostMessage, 0x5555, 2,1,,% "ahk_id " scr
detecthiddenwindows,off
settitlematchmode,1
Return
Bei Alias muss du aufpassen wenn Inhalt vom Typ String ist da durch die Neuzuordnung des Speichers schnell eine Access Violation ensteht, im meisten Fällen hilft VarSetCapacity und anstatt var:="", NumPut(0,&var,"UShort").

Code: Select all

var:="Hello World!"
DllCall("LoadLibrary","Str",ahkdll:=A_AhkDir "\AutoHotkey.dll")
DllCall(ahkdll "\ahktextdll","Str","Alias(var," getvar(var) ")`nMsgBox `% var","Str","","Cdecl")
MsgBox end

Return to “Ich brauche Hilfe”

Who is online

Users browsing this forum: No registered users and 8 guests