Jump to content
Shaggi

Console.au3 UDF

Recommended Posts

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

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.

You tell me :D One cannot know if cls has access to undocumented api.

Anyway, thanks for the code. Although it looks a bit hacky, it actually seems to be the only way, besides switching buffers, cls & clrscr() (anyone know what exports this?)

e: apparantly some ansi escape codes should do the trick, too.

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

According to the MSDN site, they say to use system("cls") which is a system function or to do it progammatically use FillConsoleOutputCharacterW themselves, so it appears that is the best way to do it.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

I want to change the font of the console to "Lucida Console" (for a look-like MSysGit/Cygwin console), is it possible ?

EDIT: And how to change title of window ? Because use "title" with "System()" put the title in CAPS.

Edited by RevengeOfShadow

Share this post


Link to post
Share on other sites

I want to change the font of the console to "Lucida Console" (for a look-like MSysGit/Cygwin console), is it possible ?

EDIT: And how to change title of window ? Because use "title" with "System()" put the title in CAPS.

I dont think you can do that, sorry. It's possible by rightclicking the icon on a running console, then settings - but i do think it's global for all consoles, then.

Uploaded a new udf that supports non-capped titles, will probably be implemented as a function sometime.


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've found a method for set CMD to "Lucida Console" with a nice size !

Juste add this to your code start (Before first init of console) :

Global $AUTREP = StringReplace(@AutoItExe,"","_")
If Regread("HKEY_CURRENT_USERConsole" & $AUTREP,"FaceName") <> "Lucida Console" Then
  RegWrite("HKEY_CURRENT_USERConsole" & $AUTREP,"FaceName","REG_SZ","Lucida Console")
  RegWrite("HKEY_CURRENT_USERConsole" & $AUTREP,"FontFamily","REG_DWORD","0x00000036")
  RegWrite("HKEY_CURRENT_USERConsole" & $AUTREP,"FontSize","REG_DWORD","0x000e0000")
  RegWrite("HKEY_CURRENT_USERConsole" & $AUTREP,"FontWeight","REG_DWORD","0x00000190")
EndIF

It's not perfect, but it works fine !

Share this post


Link to post
Share on other sites

Welcome. How to execute commands in the library Console.au3 cmd from which it was run the same script AutoIt. Open 2 windows detected by the fact I'm not at hand. Of course, this can not be it:

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.

Because it is incomprehensible to me. Thank you for your help.

Share this post


Link to post
Share on other sites

I get the following error when I use zip.au3 and console.au3 together.  To simulate this error please create a new script in SciTE script editor and include zip.au3 and console.au3 and then run it.  You will get two pop up messages.

Here are the error messages:

First Popup message:

AutoIt Error: 

Line 456 (File "C:Program Files (z86)|AutoIt3Includezip.au3:):

$ZipFile=#ZipSplit[2]
$ZipFile=^Error

Error:  Array variable has incorrect number of subscripts or subscript dimension range exceeded.

Second popup message:

Line 455 (File "C:Program Files (z86)|AutoIt3IncludeConsole.au3:):

If $_Amount_Startup_COnsole Then If^Error

Error:  Variable used without being declared.

Share this post


Link to post
Share on other sites

nazirm, The problem is that both scripts wants to use $CmdLine. Comment out line 12 - 14 in Zip.au3 to get rid of the error.

The only UDFs you can expect will work together without small problems are the UDFs that belong to the official installation.

Edited by LarsJ

Share this post


Link to post
Share on other sites

Sry for gravedigging, but how about adding a Consoleclear command?

Or how can I clear the console using ur udf?

 

Sorry i haven't been around. Either use system("cls") or write a wrapper around FillConsoleOutputCharacterW, as brewman said.


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

To avoid using global variables, you can declare variables like $__Console__hCtrlHandler (Which is used only in 1 function and its value needs to be available also in next calls), you can declare them inside the related functions as Local Static.

Func RegisterConsoleEvent($fFunc, $dwSig = $sigCtrlClose, $bRegisterExit = True)
    Local Static $__Console__hCtrlHandler = 0

    .
    .
    .

Nice UDF, thanks,

Share this post


Link to post
Share on other sites

What is the console's GUI handle that I can interact with it?

For example,the use of AdlibRegister inside a script that based on the Console.au3 is not working.

I  looked at the code and saw that the console is using the function __Console__CreateConsole()

but how to get the handle that can be used in function such as  "_Timer_SetTimer($Form1, 1000)" where $Form1 is a  windows handle.

EDIT: Maybe its not working because I am running it on WIN7 64 Bit?

Thanks

Edited by lsakizada

Be Green Now or Never (BGNN)!

Share this post


Link to post
Share on other sites

There is a _Console_GetWindow function, though I'm not sure you'll be able to use it for that. (as always, my console functions can be found here: https://github.com/MattDiesel/au3-console)

The solution may be to use the autoit hidden window. Look in the helpfile at AutoItWinSetTitle, what you have to do is set the title to something unique, then get the handle using WinGetHandle.

If that doesn't work either than you'll have to make your own hidden window.

Share this post


Link to post
Share on other sites

Hi ,

I want to print the output of the autoit script on the same CMD(DOS) console.

Can I use this UDF do print the output of the result of the script on the same CMD console where I ran the script?

Just like "hostname" command print the output on the same CMD window.

I can able to print the value in the MSG box but want to print it on the same CMD window.

Thanks,

Edited by Sudhir229

Share this post


Link to post
Share on other sites

Is there a way to get a color like yellow into it? ;)

Because i use Green, Red, and Gray ALOT, but the Blue one is very hard to see without a background, and i think the way backgrounds are made in CMD looks weird :P

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...