[Prev][Next][Index][Thread]

Re: clearing the console



On 8 Apr 2000, Chris Double wrote:
> "Matthew Luckie" <kluckie@ihug.co.nz> writes:
> 
> > I am using functional developer in windows
> 
> Here is a way of doing it using Windows API calls:

It seems this is pretty much the MS recommended way -- at least, this is
what they do in one of their code samples (the only useful code I could
find in the Platform SDK searching for "clear console").

You'll also need the definitions Chris gave for
> define C-struct <COORD>
> define C-function SetConsoleCursorPosition

------------------8<----------------------
// Transliterated from a Microsoft example in the Platform SDK
// (Platform SDK / Reference / Code Samples / WINUI / CONSOLE / CONSOLE.C)
//
// Caveats: this is completely untested and it's ages since I've
// written C-FFI definitions, so I might've screwed something up.

define C-struct <SMALL-RECT> // srct
  slot left-value :: <SHORT>;
  slot top-value :: <SHORT>;
  slot right-value :: <SHORT>;
  slot bottom-value :: <SHORT>;
  pointer-type-name: <SMALL-RECT*>;
end;
 
define C-struct <CONSOLE-SCREEN-BUFFER-INFO> // csbi
  slot dwSize-value :: <COORD>;
  slot dwCursorPosition-value :: <COORD>;
  slot wAttributes-value :: <WORD>;
  slot srWindow-value :: <SMALL-RECT>;
  slot dwMaximumWindowSize-value :: <COORD>;
  pointer-type-name: <CONSOLE-SCREEN-BUFFER-INFO*>;
end;

define C-function GetConsoleScreenBufferInfo
  parameter hConsoleOutput :: <HANDLE>;  // handle to console screen
buffer
  parameter lpConsoleScreenBufferInfo :: <CONSOLE_SCREEN_BUFFER_INFO*>;
                          // address of screen buffer info.
  result value :: <BOOL>;
  c-name: "GetConsoleScreenBufferInfo", c-modifiers: "__stdcall";
end;

define C-function FillConsoleOutputAttribute
  parameter hConsoleOutput :: <HANDLE>;  // handle to screen buffer
  parameter wAttribute :: <WORD>;        // color attribute to write
  parameter nLength :: <DWORD>;          // number of cells to write to
  parameter dwWriteCoord :: <COORD>;     // coordinates of first cell
  output parameter lpNumberOfAttrsWritten :: <DWORD>;
                          // pointer to number of cells written to
  result value :: <BOOL>;
  c-name: "FillConsoleOutputAttribute", c-modifiers: "__stdcall";
end;

// Assuming ASCII version, not Unicode
define C-function FillConsoleOutputCharacter
  parameter hConsoleOutput :: <HANDLE>;  // handle to screen buffer
  parameter cCharacter :: <TCHAR>;       // character to write
  parameter nLength :: <DWORD>;          // number of cells to write to
  parameter dwWriteCoord :: <COORD>;     // coordinates of first cell
  output parameter lpNumberOfCharsWritten :: <DWORD>;
                          // pointer to number of cells written to
  result value :: <BOOL>;
  c-name: "FillConsoleOutputCharacterA", c-modifiers: "__stdcall";
end;


// I don't know why the original example calls
// GetConsoleScreenBufferInfo twice.
define function cls (hConsole :: <HANDLE>) => ()
  let bSuccess :: <boolean> = #f;
  let dwConSize :: <DWORD>; /* number of cells in current buffer */ 
 
  with-stack-structure(coord :: <COORD*>)
    coord.x-value := 0;
    coord.y-value := 0;
    with-stack-structure(csbi :: <CONSOLE-SCREEN-BUFFER-INFO*>)
      /* get the number of character cells in the current buffer */
      bSuccess := GetConsoleScreenBufferInfo(hConsole, csbi);
      assert(bSuccess, "GetConsoleScreenBufferInfo");
      dwConSize = csbi.dwSize-value.x-value * csbi.dwSize-value.y-value;
      /* fill the entire screen with blanks */
      bSuccess := FillConsoleOutputCharacter(
        hConsole, ' ', dwConSize, coordScreen
      );
      assert(bSuccess, "FillConsoleOutputCharacter");
      /* get the current text attribute */
      bSuccess := GetConsoleScreenBufferInfo(hConsole, csbi);
      assert(bSuccess, "ConsoleScreenBufferInfo");
      /* now set the buffer's attributes accordingly */
      bSuccess := FillConsoleOutputAttribute(
        hConsole, csbi.wAttributes, dwConSize, coordScreen
      );
      assert(bSuccess, "FillConsoleOutputAttribute");
      /* put the cursor at (0, 0) */
      bSuccess := SetConsoleCursorPosition(hConsole, coordScreen);
      assert(bSuccess, "SetConsoleCursorPosition");
    end;
  end;
end function cls;
------------------8<----------------------

--
Hugh





References: