Page 1 of 2

printf()

Posted: 04 Dec 2018, 05:45
by quantum
How to use printf() from msvcrt.dll in AHK?

Re: printf()

Posted: 04 Dec 2018, 09:18
by jNizM
Why not using AHK-buildin function Format()?
https://autohotkey.com/docs/commands/Format.htm

Re: printf()

Posted: 04 Dec 2018, 11:05
by Helgef
@ jNizM, printf prints to stdout.

Use dllcall, eg,

Code: Select all

dllcall("msvcrt.dll\printf", "astr", "%x", "int", 12648430, "cdecl int")
Cheers.

Re: printf()

Posted: 04 Dec 2018, 17:57
by iPhilip
Another choice is to use the FileAppend command with an asterisk (*) for Filename along with the Format command, e.g.

Code: Select all

FileAppend, % Format("{:T}", "hello world"), *

Re: printf()

Posted: 05 Dec 2018, 03:33
by Helgef
Good point iPhilip, however, printf has a few other features which Format lacks. It doesn't do Title Case though ;).

Cheers.

Re: printf()

Posted: 05 Dec 2018, 07:49
by quantum
Are you sure this works?

DllCall("AllocConsole")
stdin := FileOpen(DllCall("GetStdHandle", "int", -10, "ptr"), "h `n")
stdout := FileOpen(DllCall("GetStdHandle", "int", -11, "ptr"), "h `n")

dllcall("msvcrt.dll\printf", "astr", "%x", "int", 12648430, "cdecl int")

Re: printf()

Posted: 05 Dec 2018, 11:01
by Helgef
It returns a positive integer, indicating success. I could printf to file starting the script like,

Code: Select all

"%ProgramFiles%\AutoHotkey\AutoHotkey.exe" "My Script.ahk" >"Error Log.txt"
see FileAppend -> FileName.

Also, you do not need to call GetStdHandle, you can call stdout := fileopen("*", "w"). You can follow the example on the fileopen page and use sprintf to format a string and then write it to stdout, if you really need any formatting not available via format.

Cheers.

Re: printf()

Posted: 05 Dec 2018, 11:46
by jeeswg
Wow, so this is all we need for a proper AHK console.

Code: Select all

q:: ;AHK console
ConsolePrint("1 " A_Now "`n")
ConsolePrintLine("2 " A_Now)
ConsolePrintLine()
return

ConsolePrint(ByRef vText:="")
{
	static vIsReady := 0, oStdOut
	if !vIsReady
	{
		DllCall("kernel32\AllocConsole")
		oStdOut := FileOpen("*", "w `n")
		vIsReady := 1
	}
	oStdOut.Write(vText)
	oStdOut.Read(0) ;flush the write buffer
}

ConsolePrintLine(ByRef vText:="")
{
	ConsolePrint(vText)
	ConsolePrint("`n")
}

Re: printf()

Posted: 05 Dec 2018, 12:00
by Helgef
vIsReady

Re: printf()

Posted: 05 Dec 2018, 12:04
by jeeswg
@Helgef: Fixed. The function is now ready. Thanks.

Re: printf()

Posted: 05 Dec 2018, 16:16
by quantum
Printing to console is no problem. However printf is also format.

Can someone post a complete example for printf? Thanks.

Re: printf()

Posted: 05 Dec 2018, 16:29
by Helgef
I'm not sure what you want. Format string then print,

Code: Select all

sprintf(byref buf, fmt, p*){
	local
	p.push("cdecl int")
	c := dllcall("msvcrt.dll\_scprintf", "astr", fmt, p*)
	varsetcapacity(buf, c + 1, 0)
	c := dllcall("msvcrt.dll\sprintf", "ptr", &buf, "astr", fmt, p*)
	buf := strget(&buf, "CP0")
	return c
}
msgbox % sprintf(buf, "0x%x`n%llu", "int", 256, "int64", -1) "`n`n" buf
Cheers

Re: printf()

Posted: 05 Dec 2018, 16:33
by quantum
Wait but that's sprintf! Not printf :)))

Re: printf()

Posted: 06 Dec 2018, 06:52
by heavyhotuser
Hello guys!
This is cool!
I would like to read StdOut after write!

Code: Select all

q:: ;AHK console
ConsolePrint("1 " A_Now "`n")
sleep, 300
ConsolePrint("2 " A_Now "`n")
MsgBox % ConsolePrint(, 1)
ExitApp
return

ConsolePrint(ByRef vText:="", RW:="")
{
	static vIsReady := 0, oStdOut
	if !vIsReady
	{
		DllCall("kernel32\AllocConsole")
		oStdOut := FileOpen("*", "w `n")
		vIsReady := 1
	}
	if !RW 
	{
		oStdOut.Write(vText)
		oStdOut.Read(0) ;flush the write buffer
	} 
	else
	return oStdOut.ReadAll(), RW:=""
}

Re: printf()

Posted: 06 Dec 2018, 06:57
by quantum
So we can't use printf? Shame.

Re: printf()

Posted: 06 Dec 2018, 09:31
by rommmcek
I heard, StdIn/Out works via stream. May be that's why we can't read afterwards.
But we can always read via copy:

Code: Select all

ConsoleRead()
{
	Clipboard := ""
	ControlSend,, ^{a}^{c}, C:\Program Files\AutoHotkey\AutoHotkey.exe ahk_class ConsoleWindowClass
	ClipWait, 1
	return vTextR := Clipboard
}

Re: printf()

Posted: 06 Dec 2018, 09:45
by heavyhotuser
Copy works very well! :bravo:

Re: printf()

Posted: 07 Dec 2018, 00:14
by jeeswg
When I use #Warn in StdOut mode, the warnings don't appear in the console. Any ideas? Thanks.

Re: printf()

Posted: 07 Dec 2018, 01:26
by Helgef
quantum wrote:
06 Dec 2018, 06:57
So we can't use printf? Shame.
As I told you, it works if you start the script from the command line as described in the fileappend page.

Also, I translated this example from msdn, see :arrow: github, its for v2. I'll add a instructions later.

Cheers.

Re: printf()

Posted: 07 Dec 2018, 02:25
by Helgef
jeeswg wrote:
07 Dec 2018, 00:14
When I use #Warn in StdOut mode, the warnings don't appear in the console. Any ideas? Thanks.
In the example I mentioned above, warnings from the child script are printed to the console (in the parent script).

I added instructions

Cheers.
Edit:
Also, starting a script as (also from fileappend)

Code: Select all

"%ProgramFiles%\AutoHotkey\AutoHotkey.exe" "My Script.ahk" |more
from the command line also prints warnings and printf in the command prompt.