CLOSE ALL * Demo Writing to Console * Declare a few things we'll need - constants first #DEFINE STD_OUTPUT_HANDLE -11 #DEFINE INVALID_HANDLE_VALUE -1 #DEFINE ENABLE_WRAP_AT_EOL 2 #DEFINE ENABLE_PROCESSED_OUTPUT 1 * API Calls * Retrieve the last error recorded by a function using Win32 default error reporting DECLARE INTEGER GetLastError IN Win32API * Allocate a new console - fails if we currently are attached to a console DECLARE SHORT AllocConsole IN WIN32API * Request a pseudohandle to a standard device DECLARE INTEGER GetStdHandle IN WIN32API INTEGER nStdHandleID * Retrieve the current settings of the console handle specified DECLARE SHORT GetConsoleMode IN WIN32API INTEGER nConsoleHandle, INTEGER @ nConsoleMode * Alter the console handling behavior of the specified console handle DECLARE SHORT SetConsoleMode IN WIN32API INTEGER nConsoleHandle, INTEGER dwMode * DECLARE SHORT CloseHandle IN WIN32API INTEGER hHandle * Release a console; does not destroy the console, but detaches the current process from it DECLARE SHORT FreeConsole IN WIN32API * Direct output to a console handle - can be used to write to StdOut or StdErr DECLARE SHORT WriteConsole IN WIN32API ; INTEGER hConsoleOutput, ; STRING @ lpBuffer, ; INTEGER nNumCharsToWrite, ; INTEGER @ lpNumCharsWritten, ; INTEGER nReserved LOCAL nStdOutHandle, nStdOutMode, lAllocatedConsole, cStringToWrite, nCharsWritten * Check to see if we currently have a console; if we do, then AllocConsole() will fail and we'll * use the console we're attached to - otherwise, create a console to write to. Track if we do * create one so that we can free it when we're done with it, otherwise, stay attached to it lAllocatedConsole = ( AllocConsole() # 0) nStdOutHandle = GetStdHandle(STD_OUTPUT_HANDLE) IF nStdOutHandle = INVALID_HANDLE_VALUE MESSAGEBOX('Unable to open StdOut ' + TRANSFORM(GetLastError())) RETURN ENDIF nStdOutMode = 0 IF GetConsoleMode(nStdOutHandle, @ nStdOutMode) = 0 MESSAGEBOX('Unable to determine Console Mode ' + TRANSFORM(GetLastError())) RETURN ENDIF * We want to enable Word wrap, and allow expansion/interpretation of ASCII control characters * like Tab, CR, LF, etc =SetConsoleMode(nStdOutHandle, BITOR(nStdOutMode,ENABLE_WRAP_AT_EOL+ENABLE_PROCESSED_OUTPUT)) * Spew cStringToWrite = "Hello, World" + CHR(13) + CHR(10) + CHR(10) + "and Hello again!" =INKEY(10) nCharsWritten = 0 =WriteConsole(nStdOutHandle, cStringToWrite, LEN(cStringToWrite), @ nCharsWritten, 0) * You can check how many characters actually were written; important if using control * sequences/ANSI addressing (not native), backspace, etc. =INKEY(10) * The INKEY() is there just to prove we really do the actual writes to console nCharsWritten = 0 * Add a tab - a character processed by the console handler just to prove we can cStringToWrite = CHR(9) + cStringToWrite =WriteConsole(nStdOutHandle, cStringToWrite, LEN(cStringToWrite), @ nCharsWritten, 0) * The INKEY() is there just to prove we really do the actual writes to console =INKEY(10) * Close your handle when done to allow the OS object to release when fully dereferenced * * If we allocated our own console, and we don't love it any more, we can release it. If * we're going to spawn DOS apps or console WinApps and want to control them, redirect * their streams, we won't close the handle (we'll pass it to the child via CreateProcess() * or can set up the console as we want our children inheriting the console to act. =CloseHandle(nStdOutHandle) IF lAllocatedConsole =FreeConsole() ENDIFDon't say I never gave you anything...