Konsolenproblem (SetConsoleCursorPosition)

03/20/2014 14:58 DarkCrusade2#1
Guten Tag :)

ich bin Neueinsteiger in AutoIT, komme von C++ und habe die wunderbare Eigenschaft von AutoIT gefunden, einfach dynamische Bibliotheken zu nutzen um die Begrenztheit mehr oder minder auszugleichen.
Also wollte ich ein wenig an der Konsole rumfrickeln, funktioniert auch bisher, allerdings habe ich folgendes Problem:


Die Methode gibt mir immer false zurück. Weiß jemand worans liegt?
als Parameter habe ich einfach "struct" als Typ gewählt, da structs wie "COORD" ja nicht registriert sind. Scheint aber nicht zu funktionieren. Handle der Konsole ist gegeben. Error wird nicht gesetzt (Aufruf war erfolgreich), schreibt jedoch in die Variable [0]:0, [1]:0x000..0, Extended wird auf 6 gesetzt (GetLastError()).
Doku zu SetConsoleCursorPosition:
[Only registered and activated users can see links. Click Here To Register...].

Vielen Dank im Voraus :)
03/20/2014 16:25 alpines#2
Da kommen Variablen vor die gar nicht deklariert wurden, wie wäre es denn wenn du uns ein Beispiel zippst und hochlädst?
03/21/2014 08:23 DarkCrusade2#3
$STD_OUTPUT_HANDLE = 0xfffffff5, wie in Winbase.h definiert.
$result ist eine neue Variable, sollte eigentlich in der Deklaration im Kopf der Methode stehen. Alle anderen Variablen sind lokal.
04/01/2014 15:34 DarkCrusade2#4
*bump* jemand ne Idee?
04/01/2014 15:55 lolkop#5
Quote:
Originally Posted by DarkCrusade2 View Post
Guten Tag :)

ich bin Neueinsteiger in AutoIT, komme von C++ und habe die wunderbare Eigenschaft von AutoIT gefunden, einfach dynamische Bibliotheken zu nutzen um die Begrenztheit mehr oder minder auszugleichen.
Also wollte ich ein wenig an der Konsole rumfrickeln, funktioniert auch bisher, allerdings habe ich folgendes Problem:


Die Methode gibt mir immer false zurück. Weiß jemand worans liegt?
als Parameter habe ich einfach "struct" als Typ gewählt, da structs wie "COORD" ja nicht registriert sind. Scheint aber nicht zu funktionieren. Handle der Konsole ist gegeben. Error wird nicht gesetzt (Aufruf war erfolgreich), schreibt jedoch in die Variable [0]:0, [1]:0x000..0, Extended wird auf 6 gesetzt (GetLastError()).
Doku zu SetConsoleCursorPosition:
[Only registered and activated users can see links. Click Here To Register...].

Vielen Dank im Voraus :)
schau doch einfach mal in die dokumentation zu DllCall:
Quote:
If the function call fails then @error is set to non-zero.
Otherwise an array is returned that contains the function return value and a copy of all the parameters (including parameters that the function may have modified when passed by reference).
$return[0] = function return value
$return[1] = param1
$return[2] = param2
...
$return[n] = paramn
DllCall gibt immer ein array zurück (wenn der funktionsaufruf nicht fehlschlägt). fragt man ein beliebiges array als normale variable ab, so wird IMMER False (0) zurück gegeben.

entsprechend kann $result bei dir nur false zurück geben.
04/01/2014 16:59 DarkCrusade2#6
Quote:
Originally Posted by lolkop View Post
schau doch einfach mal in die dokumentation zu DllCall:


DllCall gibt immer ein array zurück (wenn der funktionsaufruf nicht fehlschlägt). fragt man ein beliebiges array als normale variable ab, so wird IMMER False (0) zurück gegeben.

entsprechend kann $result bei dir nur false zurück geben.
Die Funktion selber gibt BOOL zurück. Eine ähnliche Funktion ist MoveWindow(). Diese schreibt mir "true" in $result, wenn sie ausgeführt wurde (also setzt den Bitwert auf != 0).
04/01/2014 17:22 lolkop#7
Quote:
Originally Posted by DarkCrusade2 View Post
Die Funktion selber gibt BOOL zurück. Eine ähnliche Funktion ist MoveWindow(). Diese schreibt mir "true" in $result, wenn sie ausgeführt wurde (also setzt den Bitwert auf != 0).
du scheinst nicht zu verstehen, das dllcalls arrays zurück geben...

Code:
Dim $array[1]=[5]
ConsoleWrite(Not $array&@CRLF)
wird immer True zurückgeben... 5!=0 und somit True in Autoit. Da $array aber ohne index verwendet wurde, ist $array immer False.

Code:
Dim $array[1]=[5]
ConsoleWrite(Not $array[0]&@CRLF)
hingegen gibt wie erwartet False zurück da der Index auf das erste element verweist.

in deinem beispiel musst du entsprechend $result[0] nutzen, um den ersten eintrag des ergebnisarrays zu erhalten.
korrekt wäre also zb:
Code:
Func consoleSetCursorPosition($x, $y)
	Local 	$coords 	= DllStructCreate("INT X;INT Y")		_
		,	$kernel 	= DllOpen("kernel32.dll")				_
		,	$handle

	DllStructSetData($coords, "X", $x)
	DllStructSetData($coords, "Y", $y)

	$handle = DllCall($kernel, 	"HANDLE", "GetStdHandle",				_
								"DWORD", $STD_OUTPUT_HANDLE)

	if($handle[0] = 0) Then SetError(1, 0, -1)

	$result = DllCall($kernel, 	"BOOL", "SetConsoleCursorPosition", 	_
								"HANDLE", $handle, 						_
								"struct",$coords)
	If @error Then Return @error
	DllClose($kernel)
	return $result[0]
EndFunc
04/01/2014 17:35 DarkCrusade2#8
Ach natürlich, habe nur ewig lange rumprobiert. Habe nicht gesehen, dass ich oben noch $result ohne Index stehen habe.

Richtig hieße es natürlich $result[0]. Funktioniert trotzdem nicht. :)
04/01/2014 17:50 lolkop#9
Quote:
Originally Posted by DarkCrusade2 View Post
Ach natürlich, habe nur ewig lange rumprobiert. Habe nicht gesehen, dass ich oben noch $result ohne Index stehen habe.

Richtig hieße es natürlich $result[0]. Funktioniert trotzdem nicht. :)
versuchs mal so:
Code:
Func consoleSetCursorPosition($x, $y)
	Local $coords = BitShift($y, -16) + $x, $kernel = DllOpen("kernel32.dll"), $handle, $return
	$handle = DllCall($kernel, "hwnd", "GetStdHandle", "dword", $STD_OUTPUT_HANDLE)
	If @error Then Return SetError(@error, @extended, False)
	$result = DllCall($kernel, "bool", "SetConsoleCursorPosition", "hwnd", $handle[0], "int", $coords)
	If @error Then Return SetError(@error, @extended, False)
	DllClose($kernel)
	return $result[0]<>0
EndFunc
04/01/2014 18:08 DarkCrusade2#10
*facepalm* ich hatte ja auch einfach bei $handle keinen Index angegeben. Jetzt funktioniert's, danke dir :)
04/02/2014 01:02 YatoDev#11
vergest es ... ^^