Terminal control/Positional read

From Rosetta Code
Revision as of 21:33, 12 October 2012 by rosettacode>Gerard Schildberger (→‎{{header|REXX}}: made the REXX program agree with the comments. -- ~~~~)
Terminal control/Positional read is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Determine the character displayed on the screen at column 3, row 6 and store that character in a variable.

AutoHotkey

Works with: AutoHotkey_L

AutoHotkey is not built for the command line, so we need call the WinAPI directly.

For fun, this writes random characters to the command window so that it has something to retrieve.

<lang AHK>DllCall( "AllocConsole" ) ; create a console if not launched from one hConsole := DllCall( "GetStdHandle", int, STDOUT := -11 ) Loop 10 { Loop 10 { Random, asc, % asc("A"), % Asc("Z") WriteConsole(hConsole, Chr(asc)) } WriteConsole(hConsole, "`n") }

MsgBox % ReadConsoleOutputCharacter(hConsole, 1, 3, 6)

=== The below simply wraps part of the WinAPI ===

WriteConsole(hConsole, text){ VarSetCapacity(out, 16) If DllCall( "WriteConsole", UPtr, hConsole, Str, text, UInt, StrLen(text) , UPtrP, out, uint, 0 ) return out return 0 } ReadConsoleOutputCharacter(hConsole, length, x, y){ VarSetCapacity(out, length * (1 << !!A_IsUnicode)) VarSetCapacity(n, 16) if DllCall( "ReadConsoleOutputCharacter" , UPtr, hConsole , Str, out , UInt, length , UInt, x | (y << 16) , UPtrP, n )

&& VarSetCapacity(out, -1) return out return 0 }</lang>

BASIC

Locomotive Basic

<lang locobasic>10 LOCATE 3,6 20 a$=COPYCHR$(#0)</lang>

Amstrad CPC screen memory only stores pixels but no character information (as opposed to e.g. the C64), so the firmware routine (TXT_UNWRITE) called by BASIC works by trying to find a match between screen pixels and the shape of a currently defined character. If the character table or screen pixels in the area of the character are changed between writing and reading, COPYCHR$ will therefore fail.

QBasic

The top left corner is (1, 1).

<lang qbasic>c$ = CHR$(SCREEN(6, 3))</lang>

ZX Spectrum Basic

<lang basic> 10 REM The top left corner is at position 0,0

20 REM So we subtract one from the coordinates
30 LET c$ = SCREEN$(5,2)</lang>

BBC BASIC

<lang bbcbasic> PRINT TAB(2,5) "Here"

     char$ = GET$(2,5)
     PRINT "Character at column 3 row 6 was " char$</lang>

C

With the Windows console, call GetConsoleScreenBufferInfo() to find the top-left corner of the display screen. Then add (3, 6) to the top-left corner and call ReadConsoleOutputCharacterW() to read character. This program reckons that the top-left corner is (0, 0).

Library: Win32

<lang c>#include <windows.h>

  1. include <wchar.h>

int main() { CONSOLE_SCREEN_BUFFER_INFO info; COORD pos; HANDLE conout; long len; wchar_t c;

/* Create a handle to the console screen. */ conout = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (conout == INVALID_HANDLE_VALUE) return 1;

/* Where is the display window? */ if (GetConsoleScreenBufferInfo(conout, &info) == 0) return 1;

/* c = character at position. */ pos.X = info.srWindow.Left + 3; /* Column */ pos.Y = info.srWindow.Top + 6; /* Row */ if (ReadConsoleOutputCharacterW(conout, &c, 1, pos, &len) == 0 || len <= 0) return 1;

wprintf(L"Character at (3, 6) had been '%lc'\n", c); return 0; }</lang>

REXX

The REXX doesn't have any cursor or screen management tools, but some REXX interpreters have added the functionality via different methods.

Works with: PC/REXX

<lang rexx>/*REXX program demonstrates reading a char at specific screen location.*/

row=6 /*point to row six. */ col=3 /*point to column three. */ howMany=1 /*read one character. */

stuff=scrRead(row,col,howMany) /*this'll do it. */

other=scrRead(40,6,1) /*same thing, but for row forty. */</lang>