Page 3 of 3

Re: AHK v2

Posted: 16 Mar 2016, 06:17
by fump2000
Wie kann ich den Fileread umgehen und das Script im Script hinterlegen?

Hier bekomm ich von der v1 gemeldet das die Funktion unbekannt sei.

Code: Select all

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

Re: AHK v2

Posted: 16 Mar 2016, 06:37
by HotKeyIt
Welche Funktion? Alias? Das kann nicht sein. Hast du auch die richtigen Versionen heruntergeladen: AutoHotkey_H.

Script im Script geht genauso:

Code: Select all

Script:="MsgBox Hello World!"
DllCall("LoadLibrary","Str",ahkdll:=A_ScriptDir "\AutoHotkey.dll")
DllCall(ahkdll "\ahktextdll","Str",Script,"Str","","Cdecl")
While DllCall(ahkdll "\ahkReady")
  Sleep 100

Re: AHK v2

Posted: 16 Mar 2016, 06:51
by fump2000
Die DLL trägt in der Versionsinfo H019 am Ende.

Das Script meldet, das die Funktion unbekannt sei.

Anscheinend blicke ich nicht wie genau das gehen soll. Bitte zeig mir wie du das folgende als Var im Script an die DLL übergeben würdest mit v1 an v2:

Code: Select all

translate_google(str,tl:="",sl:="",proxy:=""){
	ComObjError(false)
	http	:= ComObjCreate("WinHttp.WinHttpRequest.5.1")
	proxy?http.SetProxy(2,proxy):"",tl?"":tl:="de"
	http.open("POST","https://translate.google.com/translate_a/single?client=t&sl=" (sl?sl:"auto") "&tl=" tl "&hl=" tl "&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&otf=1&ssel=3&tsel=3&pc=1&kc=2&tk=" translate_tl(str),1)
 
	http.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
	http.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0")
	http.send("q=" Uri_Encode(str))
	http.WaitForResponse(-1)
	if IsObject(Result:=so(http.responsetext,0)) && IsObject(Result.1) && Result.1.Length()
	for i,n in Result.1
	text.= n.1 " "
	Return text
}

Re: AHK v2

Posted: 16 Mar 2016, 07:40
by HotKeyIt
Kannst du hier die Fehlermeldung reinkopieren?
Um Funktionen in den Thread einzubauen kannst du CreateScript verwenden.
Also DllCall(..., "Str", CreateScript("translate_google{}") "`n" DeinScript, "Str", ...)
Oder kopiere die Funktion in eine der Libraries.

Re: AHK v2

Posted: 16 Mar 2016, 07:51
by fump2000
AHK meldet:
Error: Call to nonexistend function
Secifically: getvar(var) ")
MsgBox % var","","Cdecl")

Also ist es eigentlich nicht möglich ein ganzes Script als Variable zu speichern und per DLL zu laden?

Beispielsweise dies:

Code: Select all

;============================================================================
; Translate text using Google Translator in a GUI.
;============================================================================
#Persistent
#SingleInstance ignore
OnMessage(0x201, "WM_LBUTTONDOWN") ; Necessary for Guis without caption.
OnMessage(0x5555, "Test")
CoordMode, Mouse, Screen
To:="en"
Return
;============================================================================
 
;============================================================================
; Aufrufen
;============================================================================
Start:
TransText:=""
TextToT:=GetTextFromClipboard()
If WinExist("PWM Translator")
	{
		GuiControl, GetText:,NewText,%TextToT%
		GoSub NewTranslate
		Return
	}
GoSub StartTranslate
Return
;----------------------------------------------------------------------------
; Funktion um Inhalte zu kopieren.
;----------------------------------------------------------------------------
GetTextFromClipboard()
{
	ClipSaved := ClipboardAll
	Clipboard := ""
	SendInput, ^c
	ClipWait, 0.5
	If ErrorLevel
		{
			Clipboard := ClipSaved
			ClipSaved := ""
			Return
		}
	v := Clipboard
	Clipboard := ClipSaved
	ClipSaved := ""
	Return v
}
;----------------------------------------------------------------------------
; Wurde kein Inhalt kopiert wird nur die GUI aufgerufen.
;----------------------------------------------------------------------------
StartTranslate:
To:="en"
if (TextToT="")
	{
		GoSub GetText
		return
	}
else
	GoSub translate
Return
;----------------------------------------------------------------------------
; Startet die Übersetzung
;----------------------------------------------------------------------------
translate:
TransText:=translate_google(TextToT, To)
StrReplace, TransText, %TransText%, `n, `n`r,,1
if (GuiOn=1)
	GuiControl, GetText:,NewTransText,%TransText%
else
	{
		WithText:=1
		Gosub GetText
	}
Return
 
translate_google(str,tl:="",sl:="",proxy:=""){
	ComObjError(false)
	http	:= ComObjCreate("WinHttp.WinHttpRequest.5.1")
	proxy?http.SetProxy(2,proxy):"",tl?"":tl:="de"
	http.open("POST","https://translate.google.com/translate_a/single?client=t&sl=" (sl?sl:"auto") "&tl=" tl "&hl=" tl "&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&otf=1&ssel=3&tsel=3&pc=1&kc=2&tk=" translate_tl(str),1)
 
	http.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
	http.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0")
	http.send("q=" Uri_Encode(str))
	http.WaitForResponse(-1)
	if IsObject(Result:=so(http.responsetext,0)) && IsObject(Result.1) && Result.1.Length()
	for i,n in Result.1
	text.= n.1 " "
	Return text
}
 
;----------------------------------------------------------------------------
; Gui zum anzeigen von übersetzen Text oder zur Eingabe von neuem Text.
;----------------------------------------------------------------------------
GetText:
MouseGetPos, TextX, TextY
Gui, GetText:Color, AAAAAA
Gui, GetText:+LastFound +AlwaysOnTop -Caption +ToolWindow +Border +HWNDh_GetText
Gui, GetText:Font, s10
Gui, GetText:Add, Text, x0 y3 w350 h17 +Center, Text der Übersetzt werden soll:
Gui, GetText:Add, Edit, x0 y20 w350 h80 cBlue vNewText +border gNewTranslate,%TextToT%
Gui, GetText:Add, Text, x0 y104 w120 h17 +Center +ReadOnly, Übersetzung:
Gui, GetText:Add, Text, x149 y104 w100 h17 , Sprachauswahl:
Gui, GetText:Add, DropDownList, x250 y101 w100 h17 vLangChange gLangChange r5 +AltSubmit,Englisch||Deutsch|Italienisch|Französisch|Spanisch
Gui, GetText:Add, Edit, x0 y125 w350 h80 cGreen +border vNewTransText,%TransText%
Gui, GetText:Add, Text, x0 y207 w350 h17 vLine1, ESC = Schließen - Klicke ins Graue zum verschieben.
Gui, GetText:Font
Gui, GetText:Font, s8
Gui, GetText:Add, Text, x313 y207 w35 h16 +Border cWhite +Center gWithTextGuiClose, close
if (WithText=1)
	GuiControl, GetText:Focus, Line1
else
	GuiControl, GetText:Focus, NewText
Gui, GetText:Show, h224 w350 x%TextX% y%TextY%,PWM Translator
Hotkey, Escape, WithTextGuiClose, on
Return
;----------------------------------------------------------------------------
; Ändern des Übersetzers von Google auf Bing oder umgekehrt.
;----------------------------------------------------------------------------
LangChange:
GuiControlGet, LangChange
if (LangChange=1)
	To:="en"
if (LangChange=2)
	To:="de"
if (LangChange=3)
	To:="it"
if (LangChange=4)
	To:="fr"
if (LangChange=5)
	To:="es"
GoSub NewTranslate
Return
;----------------------------------------------------------------------------
; Bei der Eingabe von neuem Text wird direkt neu Übersetzt.
;----------------------------------------------------------------------------
NewTranslate:
GuiControl, GetText:,NewTransText,
GuiControlGet, NewText, GetText:, NewText
if (NewText="")
	GuiControl, GetText:,NewTransText,
GuiOn:=1
TextToT:=NewText
TransText:=""
GoSub translate
Return
;----------------------------------------------------------------------------
; Schließt die GUI und leert die Var's.
;----------------------------------------------------------------------------
WithTextGuiClose:
GuiOn:=0
WithText:=0
TransText:=""
Gui, GetText:Destroy
Hotkey, Escape, WithTextGuiClose, off
Return
;----------------------------------------------------------------------------
 
;============================================================================
; Funktionen für Google
;============================================================================
so(s,n:=""){
	static JSON,JSONS,d,y:="`"",j:="`" `t",m:={"\b":Chr(08),"\\":"\","\t":"`t","\n":"`n","\f":Chr(12),"\r":"`r"},gu:="āЁξ"
	if (Type(s)="Object")
	{
		for i,n in s
			str.= (Type(i)="Object"?so(i,1):i+0=""?(gu i gu):i)  ":"  (Type(n)="Object"?so(n,1): n+0=""?(gu n gu):n)  ","
		if !n
		{
			StrReplace, str, %str%,/,\/
			for c,z in m 
				IF InStr(str,z)
				StrReplace, str, %str%,% z,% c
			StrReplace, str, %str%,% y,% "\" y
			StrReplace, str, %str%,% gu,% y
		}
		Return "{" RTrim(str,",") "}"
	}
	if (Type(s)="string")
	{
		f:=[],i:=1
		if n
			b:=StrLen(s)
		else
		{
			if !(s:=Trim(s)) or !regexmatch(s, "[\[\{]")
				Return s
			if JSON:=(n=0) ; so(s,0) JSON
			{
				for c,z in m
					if InStr(s,c)
						StrReplace,s,% s,% c,% z
				StrReplace, s, %s%,\/,/
 
 
				if e:=InStr(s,"\u")
					for e,n in StrSplit(SubStr(s, e+2), "\u")
						IF n and !f[b:=SubStr(n, 1, 4)]
						{
							IF d := Abs("0x" b)
								StrReplace,s,% s,% "\u" b,% Chr(d)
							f[b]:=1
						}
			}
			f:=[],b:=StrLen(s),n:=SubStr(s,i,1),d:=0,JSONS:=JSON?"\":"``"
		}
 
		if (n="{")
			loop
			{
				if ((r?r[0]:"") = "}") or !i or !( i:=RegExMatch(s,"\S",n,i+1) ) or ((n:=n[0]) = "}")
					Return d:=i,f
 
				if InStr("[{",n)
					 (k:=so(SubStr(s,i),n),i+=d,i:=RegExMatch(s,"\S",t,InStr(s,":",,i)+1),(InStr("[{",t:=i?t[0]:"")
						? (f[SO_JSON(K,JSON) ""]:=so(SubStr(s,i),t),i:=RegExMatch(s,",|\}",r,i+d))
						: ( ((t=y) 	? (p:=InStr(s,y,,i+1),p:=RegExMatch(s,",|\}",r,p),z:=Trim(SubStr(s,i+1,p-i-2))) 
										: (p:=RegExMatch(s,",|\}",r,i),z:=Trim(SubStr(s,i,p-i)),z:=z+0=""?SO_Try(z):z+0))
									,f[SO_JSON(K,JSON) ""]:=SO_JSON(K,JSON),i:=p)) )
				else
					 (x:=InStr(s,":",,(n=y)?InStr(s,y,,i,2):i))
						? (k:= ((n=y)?SubStr(s,i+1,x-i-2):SubStr(s,i,x-i))
							,k:=(n=y ? Trim(k) : n="(" ? SO_Try(Trim(k,"() `t")):Trim(k)),i:=RegExMatch(s,"\S",t,x+1)
							,InStr("[{",t:=i?t[0]:"")
								? (f[SO_JSON(K,JSON)  ""]:=so(SubStr(s,i),t),i:=RegExMatch(s,",|\}",r,i+d))
								: ( ((t=y) 	? (p:=so_InStr(s,i,JSONS),p:=RegExMatch(s,",|\}",r,p),z:=Trim(SubStr(s,i+1,p-i-2))) 
										: (p:=RegExMatch(s,",|\}",r,i),z:=Trim(SubStr(s,i,p-i)),z:=z+0=""?SO_Try(z):z+0))
									,f[SO_JSON(K,JSON)  ""]:=SO_JSON(Z,JSON),i:=p))
						: i:=0
			}
 
		if (n = "[")
			loop
			{
				if ((r?r[0]:"") = "]") or !i or !( i:=RegExMatch(s,"\S",n,i+1) ) or ((n:=n[0]) = "]")
					Return d:=i,f
				(InStr("[{",n)
					? (f.Push(so(SubStr(s,i),n)),i:=RegExMatch(s,",|\]",r,i+d))
					: (  (n=y) ? (p:=so_InStr(s,i,JSONS),p:=RegExMatch(s,",|\]",r,p),z:=Trim(SubStr(s,i+1,p-i-2))) 
						: (p:=RegExMatch(s,",|\]",r,i),z:=Trim(SubStr(s,i,p-i)),z:=z+0=""?SO_Try(z):z+0),i:=p
						,f.Push(SO_JSON(Z,JSON))))
			}
	}
}
 
SO_JSON(s,JSON){
	static J:="\`"",P:="`""
	Return JSON AND InStr(s,J)?StrReplace(S,J,P):S
}
 
SO_InStr(s,i,JSONS){
	while (p:=InStr(s,"`"",,i+1)) and (SubStr(s,p-1,1)=JSONS)
		i:=p
	Return p
}
 
SO_Try(f){
	global
	Try
	Return  (%f%)
}
 
Uri_Encode(str){
	n := StrPutVar(str, UTF8, "UTF-8"),f:={"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"41":1,"42":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1,"51":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"58":1,"59":1,"61":1,"62":1,"63":1,"64":1,"65":1,"66":1,"67":1,"68":1,"69":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"78":1,"79":1,"2d":1,"2e":1,"4a":1,"4b":1,"4c":1,"4d":1,"4e":1,"4f":1,"5a":1,"5f":1,"6a":1,"6b":1,"6c":1,"6d":1,"6e":1,"6f":1,"7a":1,"7e":1}
	loop, strlen(hex:=BintoHex(&UTF8,n))/2-1
		Res .= f[r:=substr(hex, A_index*2-1,2)]?Chr("0x" r):"`%" r
	return Res
}
 
translate_tl(string){
	a := b :=datediff(time?time:A_NowUTC,"19700101","hours")
	n:= StrPutVar(string,utf8,"UTF-8")
	loop, strlen(hex:=BintoHex(&UTF8, n))/2-1
		a := translate_rl(a + ("0x" substr(hex, A_index*2-1,2)), "+-a^+6")
	a := Mod((0 > (a := translate_rl(a, "+-3^+b+-f"))) ? (a := (a & 2147483647) + 2147483648) : a,10 ** 6)
	return a "." (a ^ b)
}
 
translate_rl(a, b){
	c := 0
	while c < StrLen(b) - 2
	{
		d := SubStr(b, c+3, 1),d := (d >= "a") ? Ord(d) - 87 : d+0
		,d := (SubStr(b, c+2, 1) ==  "+") ? a >> d : a << d
		,a := (SubStr(b, c+1, 1) == "+") ? (a + d & 4294967295) : a ^ d
		,c += 3
	}
	return ToInt(a)
}
 
ToInt(ByRef num,buf:=0){
	return num:=NumGet(getvar(buf:=num+0),"Int")
}
 
StrPutVar(Str, ByRef Var, Enc := "")
{
   Len := StrPut(Str, Enc) * (Enc = "UTF-16" || Enc = "CP1200" ? 2 : 1)
   VarSetCapacity(Var, Len, 0)
   Return, StrPut(Str, &Var, Enc)
}
 
BinToHex(addr,len) { ; Thanks Laszo
  static b2h
  if !b2h
    b2h:=McodeH(A_PtrSize=8?"4C8BC94585C0744F458BD00F1F440000440FB6024983C10248FFC241C0E8044180E80A410FB6C0C0E805442AC04180C041458841FE0FB64AFF80E10F80E90A0FB6C1C0E8052AC880C14149FFCA418849FF75BD458811C3C60100C3":"558BEC578B7D1085FF74398B4D08568B750C8A06C0E8042C0A8AD0C0EA052AC2044188018A06240F2C0A8AD0C0EA052AC204418841014683C1024F75D55EC601005F5DC38B4508C600005F5DC3","i==ttui")
  VarSetCapacity(hex,2 * len + 1),b2h[&hex,addr,len]
  Return StrGet(&hex,"CP0")
}
 
MCodeH(h,def,p*){
static f,DynaCalls
If !f
f:={},DynaCalls:={}
If DynaCalls.HasKey(h)
return DynaCalls[h]
f.Push(h),f.SetCapacity(f.Length(),len:=StrLen(h)//2)
DllCall("VirtualProtect","PTR",addr:=f.GetAddress(f.Length()),"Uint",len,"UInt",64,"Uint*",0)
Loop len
NumPut("0x" SubStr(h,2*A_Index-1,2),addr,A_Index-1,"Char")
if p.Length()
Return DynaCalls[h]:=DynaCall(addr,def,p*)
else Return DynaCalls[h]:=DynaCall(addr,def)
}
;============================================================================
 
WM_LBUTTONDOWN()
{
	if (A_Gui="GetText")
		{
			If (A_GuiControl = "") ; Klick auf den Hintergrund der GUI
				PostMessage, 0xA1, 2, 0 ; sehr sehr alter Trick von SKAN: 0xA1 = WM_NCLBUTTONDOWN
		}
}

Test(wParam, lParam)
	{
		If (wParam=2 && lParam=1)
			GoSub Start
	}

Re: AHK v2

Posted: 16 Mar 2016, 09:01
by HotKeyIt
Du benutzt AutoHotkey_L, für Alias brauchst du Autohotkey_H!
Dein Script ist doch in einer Datei und nicht in einer Variable, wo ist das Problem mit FileRead?

Re: AHK v2

Posted: 16 Mar 2016, 09:09
by fump2000
Okay verstanden.

Ich will das Hauptscript kompilieren. Das Google Translater Tool ist nur ein kleiner Bestandteil. Ich will halt nicht das Script da liegen haben sondern am liebsten alles in der kompilierten EXE. FileInstall würd ich gerne auch umgehen. Es wäre halt schön wenn man es komplett im File speichern könnte.

Re: AHK v2

Posted: 16 Mar 2016, 09:17
by jNizM
Warum nicht in verschiedenen Klassen ausgliedern und mit #Include durch Kompilieren zusammenführen?

Re: AHK v2

Posted: 16 Mar 2016, 09:18
by fump2000
Weil ich nicht weiß wie das geht :(

Re: AHK v2

Posted: 16 Mar 2016, 11:06
by HotKeyIt
Du kannst es einfach mit FileInstall machen, du musst es ja nicht extrahieren.
Du musst aber komplett AutoHotkey_H benutzen und die letzte Version herunterladen, da war ein Problem mit ResGet (Compiler muss auch aktualisiert werden)!
StrGet(&Script+3,"UTF-8") brauchst du nur wenn GoogleScript.ahk als UTF-8 gespeichert wurde, bei ANSI brauchst du nur StrGet(&Script).
Wenn du bei Compiler Compression benutzen willst, brauchen wir auch noch UnZipRawMemory.

Code: Select all

If 0 {
  FileInstall,GoogleScript.ahk,- ;Never extracted
  FileInstall,AutoHotkeyV2.dll,-
}
If A_IsCompiled {
  ResGet(Script,A_ScriptFullPath,"GoogleScript.ahk",10)
  hDll:=ResourceLoadLibrary("AutoHotkeyV2.dll")
  DllCall(MemoryGetProcAddress(hDll,"ahktextdll"),"Str",StrGet(&Script+3,"UTF-8"),"Str","","Cdecl")
} else {
  FileRead,Script,GoogleScript.ahk
  hDll:=MemoryLoadLibrary("AutoHotkeyV2.dll")
  DllCall(MemoryGetProcAddress(hDll,"ahktextdll"),"Str",Script,"Str","","Cdecl")
}
MsgBox end

Re: AHK v2

Posted: 17 Mar 2016, 01:57
by fump2000
Mit AutoHotkey_H meinst du v2 oder?

// Edit
Ja meinst du,
das geht aber nicht. Mein Hauptscript das alle Tools umfasst oder zumindest verwaltet ist sehr groß. Massenhaft Libs und sehr viel Code. Das alles auf v2 umzustellen da habe ich weder Lust zu noch bin ich mir sicher, dass ich dies auch hinbekommen würde.

Ich muss nun schauen wie ich das unterbekomme... Entweder per DLL oder halt kompilieren.
Da der Bitdefender die v2 EXE aber als "MIDAS3" erkennt und löscht, wird dies wohl auch mit einer kompilierten Version der Fall sein.
Bei der DLL ist es halt unschön, wenn das Script da liegt und von jedem verändert werden könnte der evtl. gar keine Ahnung von dem hat was er da sieht.

Keine zufriedenstellende Lösung dabei...

Re: AHK v2

Posted: 17 Mar 2016, 11:24
by HotKeyIt
fump2000 wrote:Mit AutoHotkey_H meinst du v2 oder?
Nein, es gibt AutoHotkey_H v1 und AutoHotkey_H v2!
Den oberen Script habe ich zum testen mit AutoHotkey_H v1 compiliert und die AutoHotkey.dll von AutoHotkey_H v2 mit FileInstall eingefügt.

Re: AHK v2

Posted: 18 Mar 2016, 02:22
by fump2000
Wenn AHK_H auch in v1 mehr Funktionen hat und ebenfalls aktuell gehalten wird, warum gibts dann AHK_L noch?

Finde ich irgendwie verwirrend...
Anders gefragt, sind alle AHK_L Scripts mit AHK_H v1 ausführbar?

// EDIT

Ein paar Fragen noch zu AHK_H v1

Ich habe nun deinen Code eingefügt:

Code: Select all

If 0 {
msgbox bin hier
  FileInstall,PWM_Translater.ahk,- ;Never extracted
  FileInstall,AutoHotkeyV2.dll,-
}
If A_IsCompiled {
msgbox bin compiliert
  ResGet(Script,A_ScriptFullPath,"PWM_Translater.ahk",10)
  hDll:=ResourceLoadLibrary("AutoHotkeyV2.dll")
  DllCall(MemoryGetProcAddress(hDll,"ahktextdll"),"Str",StrGet(&Script+3,"UTF-8"),"Str","","Cdecl")
} else {
msgbox bin nicht compiliert
  FileRead,Script,PWM_Translater.ahk
  hDll:=MemoryLoadLibrary("AutoHotkeyV2.dll")
  DllCall(MemoryGetProcAddress(hDll,"ahktextdll"),"Str",Script,"Str","","Cdecl")
}
Was bewirkt If 0?

Ich habe mir das Hilfe File angeschaut und für ahkgetvar, ahkLabel und ahkterminate würde ich so vorgehen:

Code: Select all

ESC::
hDll.ahkterminate()
Return

F8::
dll_ScriptHwnd:=hDll.ahkgetvar("A_ScriptHwnd")
msgbox % dll_ScriptHwnd
;PostMessage_(dll_ScriptHwnd,0x5555,2,1)
hDll.ahkLabel.Start
Return
Funktioniert aber nicht.
Bei ahkterminate würde ich davon ausgehen, dass der Thread geschlossen wird das Script somit beendet wird.
hDll ist doch korrekt?
In der Hilfe wird es sogar so dargestellt... Oder versteh ich da was falsch?

// Edit2

Das klappt nicht weil es nicht als Thread also nicht per AhkDllThread gestartet wurde, Richtig?
Kann man das trotzdem irgendwie bewerkstelligen?

Re: AHK v2

Posted: 18 Mar 2016, 06:10
by just me
Moin,

ich habe diesen Thread recht intensiv verfolgt, weil ich das Thema "multi-threading" recht interessant finde. Ich bin auch durchaus geneigt, AHK_H einzusetzen, bisher fehlt mir aber der entscheidende Anlass.

Zur Klarstellung: AHK in seiner aktuellen Form nannte man früher einmal AHK_L. Das war in der Zeit, bevor es zur offiziellen AHK Version gekürt wurde. AHK_H ist eine von HotkeyIt modifizierte Version von AHK und stellt eine Reihe von zusätzlichen, nützlichen Funktionen bereit, u.a. auch Multi-Threading.

Es gibt es sicher gute Gründe, für bestimmte Aufgaben AHK_H zu nutzen oder ganz umzusteigen. Das hier behandelte Beispiel "Google Translate" gehört aber für mich nicht dazu. Ich habe das deshalb auf das handelsübliche AHK 1.1 portiert. Zumindest für den vorgesehenen Zweck scheint es zu funktionieren. arcticirs platzsparenden und performanten Codierungsstil habe ich dabei 'aufgebröselt', weil es in jedem Fall mir und vielleicht auch anderen so leichter fallen mag, dem Code zu folgen. Du kannst die Ergebnisse ja mal vergleichen:

Code: Select all

#NoEnv
#SingleInstance, force
SetBatchLines,-1
s := "translate"
MsgBox % s := translate_google(s,"de")
Exitapp
; ==================================================================================================================================
; Originally released as "[H2] Google Translate API" by arcticir -> https://autohotkey.com/boards/viewtopic.php?f=6&t=14757
; Modified by just me for AHK 1.1
; ==================================================================================================================================
translate_google(str, tl := "", sl := "", proxy := "") {
   ; ComObjError(False)
   Static http := ComObjCreate("WinHttp.WinHttpRequest.5.1")
   If (proxy)
      http.SetProxy(2, proxy)
   If !(tl)
      tl := "en"
   http.open("POST", "https://translate.google.com/translate_a/single?client=t"
                     . "&sl=" . (sl ? sl : "auto") . "&tl=" . tl . "&hl=" . tl
                     . "&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&otf=1&ssel=3&tsel=3"
                     . "&pc=1&kc=2&tk=" . translate_tl(str), 1)
   http.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
   http.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0")
   http.send("q=" . Uri_Encode(str))
   http.WaitForResponse(-1)
   If IsObject(Result := so(http.responsetext, 0)) && IsObject(Result.1) && Result.1.Length()
      For i, n in Result.1
         text .= n.1 . " "
   Return text
}
; ----------------------------------------------------------------------------------------------------------------------------------
so(s, n := ""){
   Static JSON
        , JSONS
        , d
        , y := """"
        , j := """ `t"
        , m := {"\b": Chr(08), "\\": "\", "\t": "`t", "\n": "`n", "\f": Chr(12), "\r": "`r"}
        , gu := "āЁξ"
   If IsObject(s)
   {
      For i, n In s
         str .= (IsObject(i) ? so(i, 1) : i + 0 = "" ? (gu . i . gu) : i)
              . ":"
              . (IsObject(n) ? so(n, 1) : n + 0 = "" ? (gu . n . gu) : n) . ","
      If !(n)
      {
         str := StrReplace(str, "/", "\/")
         For c, z In m
            If InStr(str, z)
               str := StrReplace(str, z, c)
         str := StrReplace(str, y, "\" . y)
         str := StrReplace(str, gu, y)
      }
      Return "{" . RTrim(str, ",") . "}"
   }
   Else
   {
      f := []
      i := 1
      If (n)
      {
         b := StrLen(s)
      }
      Else
      {
         If !(s := Trim(s)) Or !RegExMatch(s, "[\[\{]")
         {
            Return s
         }
         If (JSON := (n = 0)) ; so(s,0) JSON
         {
            For c, z In m
               If InStr(s, c)
                  s := StrReplace(s, c, z)
            s := StrReplace(s, "\/", "/")
            If (e := InStr(s, "\u"))
            {
               For e, n In StrSplit(SubStr(s, e+2), "\u")
               {
                  If (n And !f[b := SubStr(n, 1, 4)])
                  {
                     If (d := Abs("0x" . b))
                        s := StrReplace(s, "\u" . b, Chr(d))
                     f[b] := 1
                  }
               }
            }
         }
         f := []
         , b := StrLen(s)
         , n := SubStr(s, i, 1)
         , d := 0
         , JSONS := JSON ? "\" : "`" ; "``"
      }
      If (n = "{")
      {
         Loop
         {
            If (r = "}") or !(i) or !(i :=RegExMatch(s, "\S", n, i+1)) or (n = "}")
               Return f, d := i
            If InStr("[{",n)
            {
               k := so(SubStr(s, i), n)
               , i += d
               , i := RegExMatch(s, "\S", t, InStr(s, ":", , i) + 1)
               If InStr("[{", i ? t : "")
               {
                  f[SO_JSON(k, JSON) ""] := so(SubStr(s, i), t)
                  , i := RegExMatch(s, ",|\}", r, i+d)
               }
               Else
               {
                  If (t = y)
                  {
                     p := InStr(s, y, , i+1)
                     , p := RegExMatch(s, ",|\}", r, p)
                     , z := Trim(SubStr(s, i+1, p-i-2))
                  }
                  Else
                  {
                     p := RegExMatch(s, ",|\}", r, i)
                     , z := Trim(SubStr(s, i, p-i))
                     , z := z+0 = "" ? SO_Try(z) : z+0
                  }
                  soj := SO_JSON(k, JSON)
                  , f[soj . ""] := soj
                  , i := p
               }
            }
            Else
            {
               If (x := InStr(s, ":", , (n = y) ? InStr(s, y, , i, 2) : i))
               {
                  k := ((n = y) ? SubStr(s, i+1, x-i-2) : SubStr(s, i, x-i))
                  , k := (n = y ? Trim(k) : n = "(" ? SO_Try(Trim(k, "() `t")) : Trim(k))
                  , i := RegExMatch(s, "\S", t, x+1)
                  If InStr("[{",i ? t : "")
                  {
                     f[SO_JSON(k, JSON) . ""] := so(SubStr(s, i) ,t)
                     , i := RegExMatch(s, ",|\}", r, i+d)
                  }
                  Else
                  {
                     If (t = y)
                     {
                        p := so_InStr(s, i, JSONS)
                        , p := RegExMatch(s, ",|\}", r, p)
                        , z := Trim(SubStr(s, i+1, p-i-2))
                     }
                     Else
                     {
                        p := RegExMatch(s, ",|\}", r, i)
                        , z := Trim(SubStr(s, i, p-i))
                        , z := z + 0 = "" ? SO_Try(z) : z + 0
                     }
                     f[SO_JSON(k, JSON)  "" ]:= SO_JSON(z, JSON)
                     , i := p
                  }
               }
               Else
               {
                  i := 0
               }
            }
         }
      }
      If (n = "[")
      {
         Loop
         {
            If (r = "]") or !(i) or !(i := RegExMatch(s, "\S", n, i+1)) or (n = "]")
               Return f, d := i
            If InStr("[{", n)
            {
               f.Push(so(SubStr(s, i), n))
               , i := RegExMatch(s, ",|\]", r, i+d)
            }
            Else
            {
               If (n = y)
               {
                  p := so_InStr(s, i, JSONS)
                  , p := RegExMatch(s, ",|\]", r, p)
                  , z := Trim(SubStr(s, i+1, p-i-2))
               }
               Else
               {
                  p := RegExMatch(s, ",|\]", r, i)
                  , z := Trim(SubStr(s, i, p-i))
                  , z := z + 0 = "" ? SO_Try(z) : z+0
                  , i := p
               }
               f.Push(SO_JSON(z, JSON))
            }
         }
      }
   }
}
; ----------------------------------------------------------------------------------------------------------------------------------
SO_JSON(s, JSON) {
   Static j := "\"""
        , p := """"
   Return JSON And InStr(s, j) ? StrReplace(s, j, p) : s
}
; ----------------------------------------------------------------------------------------------------------------------------------
SO_InStr(s, i, JSONS) {
   While (p := InStr(s, """", , i+1)) And (SubStr(s, p-1, 1) = JSONS)
      i := p
   Return p
}
; ----------------------------------------------------------------------------------------------------------------------------------
SO_Try(f) {
   Global
   Try
   Return (%f%)
}
; ----------------------------------------------------------------------------------------------------------------------------------
Uri_Encode(str) {
   Static f := {0x30:1,0x31:1,0x32:1,0x33:1,0x34:1,0x35:1,0x36:1,0x37:1,0x38:1,0x39:1,0x41:1,0x42:1,0x43:1,0x44:1,0x45:1,0x46:1
               ,0x47:1,0x48:1,0x49:1,0x50:1,0x51:1,0x52:1,0x53:1,0x54:1,0x55:1,0x56:1,0x57:1,0x58:1,0x59:1,0x61:1,0x62:1,0x63:1
               ,0x64:1,0x65:1,0x66:1,0x67:1,0x68:1,0x69:1,0x70:1,0x71:1,0x72:1,0x73:1,0x74:1,0x75:1,0x76:1,0x77:1,0x78:1,0x79:1
               ,0x2d:1,0x2e:1,0x4a:1,0x4b:1,0x4c:1,0x4d:1,0x4e:1,0x4f:1,0x5a:1,0x5f:1,0x6a:1,0x6b:1,0x6c:1,0x6d:1,0x6e:1,0x6f:1
               ,0x7a:1,0x7e:1}
   VarSetCapacity(utf8, StrPut(str, "UTF-8"), 0)  ; StrPutVar()
   Loop, % StrPut(str, &utf8, "UTF-8") - 1
      Res .= f[r := NumGet(utf8, A_Index - 1, "UChar")] ? Chr(r) : Format("%{:02X}", r)
   Return Res
}
; ----------------------------------------------------------------------------------------------------------------------------------
translate_tl(string) {
   a := A_NowUTC ; DateDiff()
   a -= 19700101, H
   b := a
   VarSetCapacity(utf8, StrPut(string, "UTF-8"), 0) ; StrPutVar()
   Loop, % StrPut(string, &utf8, "UTF-8") - 1
      a := translate_rl(a + NumGet(utf8, A_Index - 1, "UChar"), "+-a^+6")
   a := Mod((0 > (a := translate_rl(a, "+-3^+b+-f"))) ? (a := (a & 2147483647) + 2147483648) : a, 10 ** 6)
   Return a "." (a ^ b)
}
; ----------------------------------------------------------------------------------------------------------------------------------
translate_rl(a, b){
   c := 0
   While c < (StrLen(b) - 2)
   {
      d := SubStr(b, c+3, 1)
      , d := (d >= "a") ? Ord(d) - 87 : d + 0
      , d := (SubStr(b, c+2, 1) = "+") ? a >> d : a << d
      , a := (SubStr(b, c+1, 1) = "+") ? (a + d & 4294967295) : a ^ d
      , c += 3
   }
   VarSetCapacity(i, 4, 0) ; ToInt()
   NumPut(a, i, "Int")
   Return NumGet(i, "Int")
}

Re: AHK v2

Posted: 18 Mar 2016, 06:29
by fump2000
Wow da bin ich platt :)
Das ist cool. Nun kann ich das so integrieren ohne es auslagern zu müssen.

Das mit AHK_H ist dennoch sehr interessant. Das Starten mehrere Threads und somit auskoppeln von Funktionen oder oder sonstigen Code ist eine echt geniale Sache.

Ich danke dir für den Code!


@ HotKeyIt:
Es wäre trotzdem schön, wenn du mir das Rätzel noch lösen könntest auf das ich da gestoßen bin.

Re: AHK v2

Posted: 18 Mar 2016, 07:41
by HotKeyIt
fump2000 wrote:Anders gefragt, sind alle AHK_L Scripts mit AHK_H v1 ausführbar?
AHK_H ist eine erweiterung zu AHK_L, AutoHotkey.dll war der Auslöser für AutoHotkey_H, Lexikos hat kein Interesse an einer dll variante und die zusätzlichen Funktionen und Features habe ich eingebaut wenn diese gebraucht wurden.

Der einzige was beachtet werden muss, in AHK_H v1 ist #NoEnv default und man muss GetEnv benutzen um die Environment Variablen zu bekommen.
Desweiteren behält VarSetCapacity(var,100) den Speicher Inhalt der vorherigen Variable, das ist nützlich wenn man z.B. ein Struct() array erweitern will.
Sonst sollte alles kompatibel zu AHK_L sein.
Was bewirkt If 0?
Der code wird einfach nie ausgeführt und die Dateien werden zwar von Ahk2Exe ein die Exe eingefügt aber nicht mit FileInstall extrahiert sondern mit ResGet direct in den speicher geladen.
Ich habe mir das Hilfe File angeschaut und für ahkgetvar, ahkLabel und ahkterminate würde ich so vorgehen:
Korrekt, entweder änderst du AhkThread für v2 deine dll zu laden oder du benutzt die Funktionen über DllCall, z.B.: DllCall(MemoryGetProcAddress(hDll,"ahkgetvar"),"Str","var","UInt", 0, "Str").

EDIT:
ahkgetvar return type ist "Str"!

Re: AHK v2

Posted: 18 Mar 2016, 08:55
by fump2000
Danke dir!