Jump to content
Shaggi

Console.au3 UDF

Recommended Posts

I think it can work with some modifications,

it will take me some time to try, but you gave me good start.

Thanks!

No problem.

Plugging in your console UDF seemed like a easy way to get colored output in the console I'm using ... but that was a short exercise.

(My exe being a CUI thats using the real windows-dos console. Oops, small communication mismatch on the word 'Console'.)

Still a nice UDF though.

Thanks. A console is a console though.

Here's a update to this UDF (Shaggi I hope you don't mind just minor things). You can now use all 255 color combinations in a console, however you cannot Obfuscate your source no longer (bug).

Removed:

$FOREGROUND_X
$BACKGROUND_X

Added:

$COLOR_X (1-255)

#include <Console.au3>

Dim $COLOR_

For $i = 1 to 255
    Cout($i & ' ', $COLOR_ & $i)
    Sleep(10)
Next

While 1 = 1
    Sleep(1000)
WEnd

Nice didn't know that, it's added. However your example doesn't work as you think, you're really passing a string containing a NULL & integer colour - the two vars are concencated. Do like this:

Cout($i & ' ',$i)
Or like this
Cout($i & ' ', Eval("COLOR_" & $i)

Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG

Share this post


Link to post
Share on other sites

Hi, I have an unusual problem with this UDF. It prints the Cout() text in plain white, then it prints the text in color. It should not be printing the text in plain white.

See the attached screenshot. I used Warmonger's example. It works until it's compiled, then the duplication occurs.

#NoTrayIcon
#Region
#AutoIt3Wrapper_outfile=consoletest.exe
#AutoIt3Wrapper_Compression=0
#AutoIt3Wrapper_Change2CUI=1
#AutoIt3Wrapper_UseX64=n
#EndRegion
#include <Console.au3>
 
Dim $COLOR_
For $i = 1 to 255
    Cout($i & ' ', $COLOR_ & $i)
    Sleep(10)
Next
While 1 = 1
    Sleep(1000)
WEnd

post-57519-0-74228400-1320356227_thumb.p

Edited by Nevermind4

Share this post


Link to post
Share on other sites

Hi, I have an unusual problem with this UDF. It prints the Cout() text in plain white, then it prints the text in color. It should not be printing the text in plain white.

See the attached screenshot. I used Warmonger's example. It works until it's compiled, then the duplication occurs.

#NoTrayIcon
#Region
#AutoIt3Wrapper_outfile=consoletest.exe
#AutoIt3Wrapper_Compression=0
#AutoIt3Wrapper_Change2CUI=1
#AutoIt3Wrapper_UseX64=n
#EndRegion
#include <Console.au3>

Dim $COLOR_
For $i = 1 to 255
    Cout($i & ' ', $COLOR_ & $i)
    Sleep(10)
Next
While 1 = 1
    Sleep(1000)
WEnd

The problem is, that this UDF also writes to the standard streams of autoit, that is consolewrite etc.. so it can be seen through scite etc. when you compile it as CUI, you get both results (winapi console and standard in one).

Simply just compile it as any other script without adding "compile as cui". the udf handles this itself.


Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG

Share this post


Link to post
Share on other sites

I have another question. Cout() outputs to the console in unicode, but doesn't seem to be able to print the box-drawing characters (Unicode 2500-2580). I've tried ChrW(2554) and simply pasting the character and it does not work. When I compile as a CUI, I would use characters like Éͻ̹ȼº to print box-drawing characters. Is there a way to print them with Cout() in your UDF?

Share this post


Link to post
Share on other sites

How about overwriting a previous line using cout? liek this for example:

Cout($szString, $iAttr = -1, $Replace = 0, $Index = -1)

Where Replace tells cout to replace a previously written char...

and Index should be the n'th character to replace, could even be a range, -1 for the whole line.

Just a few thoughts :D

Nice work btw, a few other console udfs ive seen are a bit messy :s

Edited by MegaGamerGuy

Share this post


Link to post
Share on other sites

How about overwriting a previous line using cout? liek this for example:

Cout($szString, $iAttr = -1, $Replace = 0, $Index = -1)

Where Replace tells cout to replace a previously written char...

and Index should be the n'th character to replace, could even be a range, -1 for the whole line.

Just a few thoughts :D

Nice work btw, a few other console udfs ive seen are a bit messy :s

Thanks, that is possible but im pretty sure that char positions are arranged in a x,y coordinate system instead of index.. i was too lazy to figure it out at the time of writing, i might look at it soon though

I have another question. Cout() outputs to the console in unicode, but doesn't seem to be able to print the box-drawing characters (Unicode 2500-2580). I've tried ChrW(2554) and simply pasting the character and it does not work. When I compile as a CUI, I would use characters like Éͻ̹ȼº to print box-drawing characters. Is there a way to print them with Cout() in your UDF?

it uses the unicode functions so it should be able to do it, might be related to some codepage issues.. will look into it.

Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG

Share this post


Link to post
Share on other sites

Thanks ! Your work is just awesome =).

Just a question : When I do a "Cin", How can I draw message with "Cout" ? My message is not writed if I type nothing. It's a very big problem for my game ...

Share this post


Link to post
Share on other sites

Thanks ! Your work is just awesome =).

Just a question : When I do a "Cin", How can I draw message with "Cout" ? My message is not writed if I type nothing. It's a very big problem for my game ...

Could you rephrase your question, please?

Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG

Share this post


Link to post
Share on other sites

How to put a message in console when text is asked. Sorry for my bad english :/.

I'm going to assume you want to write text while waiting for input? This is not possible and for good reasons, it doesn't make much sense. When you ask for input using cin, the stream is locked and the function waits for a linebreak-terminated string input.

Maybe if you could explain why and into a little more detail, i could help you.


Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG

Share this post


Link to post
Share on other sites

You're right. Is that anyway for "bypass" it ? For example, game servers like Counter-Strike or Minecraft can do this. How I can do this on AutoIt ?

Edited by RevengeOfShadow

Share this post


Link to post
Share on other sites

You're right. Is that anyway for "bypass" it ? For example, game servers like Counter-Strike or Minecraft can do this. How I can do this on AutoIt ?

It is possible to bypass the lock and enter text by changing the inputmode. However, you would still have to deal with retrieval of text, which now has to be handled through a kind of msgloop, which either requires threading (not possible) or some hack using adlibs. Also, you would have severe synchronization problems. In short, it would really be easier to write your own console. It isnt that hard. Edited by Shaggi

Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG

Share this post


Link to post
Share on other sites

Very cool little UDF. Definitely saves time with all the initialization. I was wondering how I would "clear" the console without doing something obvious like scrolling a bunch of lines? I tried sending a cls command via stdinwrite, but that hasnt been successful yet.

Edit - seems like the system("cls") might do it...

Share this post


Link to post
Share on other sites

Updated version posted, contains some new stuff like events.

I've take a look at your UDF source ... Too hard for me :/.

Perhaps.. Anyway, i dont think you should base your project around this UDF, it's fundamentally limited for such a purpose :D

Very cool little UDF. Definitely saves time with all the initialization. I was wondering how I would "clear" the console without doing something obvious like scrolling a bunch of lines? I tried sending a cls command via stdinwrite, but that hasnt been successful yet.

Edit - seems like the system("cls") might do it...

Yup, thats how you do it. Don't know if any alternatives exist.

Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG

Share this post


Link to post
Share on other sites

Yup, thats how you do it. Don't know if any alternatives exist.

Ok then... How does cls do it? After all, cls is just a program using the same api as we have available to us :D

Granted my solution is 100 lines longer, but if you are interested in how to do it properly then:

#AutoIt3Wrapper_Change2CUI=y

For $i = 1 to 9
    ConsoleWrite("This is line " & $i & "." & @LF)
    Sleep(500)
    if $i = 5 Then
        _Console_Clear()
        Sleep(500)
    EndIf
Next



Func _Console_Clear($hConsoleOutput = -1)
    Local $aiSize

    If $hConsoleOutput = -1 Then $hConsoleOutput = _Console_GetStdHandle()

    $aiSize = _Console_GetScreenBufferSize($hConsoleOutput)

    _Console_FillOutputCharacter($hConsoleOutput, " ", $aiSize[0] * $aiSize[1])
    _Console_SetCursorPosition($hConsoleOutput, 0, 0)

    Return
EndFunc

Func _Console_SetCursorPosition($hConsoleOutput, $iX, $iY)
    Local $iCursorPosition, $aResult

    If $hConsoleOutput = -1 Then $hConsoleOutput = _Console_GetStdHandle()

    $iCursorPosition = BitShift($iY, -16) + $iX

    $aResult = DllCall("kernel32.dll", "bool", "SetConsoleCursorPosition", _
            "handle", $hConsoleOutput, _
            "int", $iCursorPosition)
    If @error Then Return SetError(@error, @extended, False)

    Return $aResult[0] <> 0
EndFunc   ;==>_Console_SetCursorPosition

Func _Console_FillOutputCharacter($hConsoleOutput, $sCharacter, $nLength, $iX = 0, $iY = 0)
    Local $aResult, $tCOORD

    If $hConsoleOutput = -1 Then $hConsoleOutput = _Console_GetStdHandle()
    If IsString($sCharacter) Then $sCharacter = AscW($sCharacter)

    $tCOORD = BitShift($iY, -16) + $iX

    $aResult = DllCall("kernel32.dll", "bool", "FillConsoleOutputCharacterW", _
            "handle", $hConsoleOutput, _
            "WORD", $sCharacter, _
            "dword", $nLength, _
            "int", $tCOORD, _
            "dword*", 0)
    If @error Then Return SetError(@error, @extended, False)

    Return SetExtended($aResult[5], $aResult[0] <> 0)
EndFunc   ;==>_Console_FillOutputCharacter

Func _Console_GetScreenBufferSize($hConsoleOutput = -1)
    Local $tConsoleScreenBufferInfo, $aRet[2]

    $tConsoleScreenBufferInfo = _Console_GetScreenBufferInfo($hConsoleOutput)
    If @error Then Return SetError(@error, @extended, 0)

    $aRet[0] = DllStructGetData($tConsoleScreenBufferInfo, "SizeX")
    $aRet[1] = DllStructGetData($tConsoleScreenBufferInfo, "SizeY")

    Return $aRet
EndFunc   ;==>_Console_GetScreenBufferSize

Func _Console_GetScreenBufferInfo($hConsoleOutput = -1, $hDll = -1)
    Local $tConsoleScreenBufferInfo, $aResult
    Local Const $tagCONSOLE_SCREEN_BUFFER_INFO = "SHORT SizeX; SHORT SizeY; SHORT CursorPositionX;" & _
        "SHORT CursorPositionY; SHORT Attributes; SHORT Left; SHORT Top; SHORT Right; SHORT Bottom;" & _
        "SHORT MaximumWindowSizeX; SHORT MaximumWindowSizeY"

    If $hConsoleOutput = -1 Then $hConsoleOutput = _Console_GetStdHandle()

    $tConsoleScreenBufferInfo = DllStructCreate($tagCONSOLE_SCREEN_BUFFER_INFO)

    $aResult = DllCall("kernel32.dll", "bool", "GetConsoleScreenBufferInfo", _
            "handle", $hConsoleOutput, _
            "ptr", DllStructGetPtr($tConsoleScreenBufferInfo))
    If @error Or (Not $aResult[0]) Then Return SetError(@error, @extended, 0)

    Return $tConsoleScreenBufferInfo
EndFunc   ;==>_Console_GetScreenBufferInfo

Func _Console_GetStdHandle($nStdHandle = -11)
    Local $aResult

    $aResult = DllCall("kernel32.dll", "handle", "GetStdHandle", _
            "dword", $nStdHandle)
    If @error Then Return SetError(@error, @extended, 0)

    Return $aResult[0]
EndFunc   ;==>_Console_GetStdHandle

Mostly lifted straight from my console UDF, I think most of those functions will now be available in WinAPIEx so will actually be standard AutoIt functions soon. Basically you fill the console with spaces and move the cursor to square one.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...