Click here to Skip to main content
15,867,568 members
Articles / Desktop Programming / Win32

Clearing the Console Screen using API

Rate me:
Please Sign up or sign in to vote.
4.81/5 (8 votes)
1 Apr 2010CPL15 min read 40.4K   1   37   5
Learn how to clear the console screen via API calls. In addition, learn some console techniques such as moving the text around the screen.
 Download the Sample Code
I previously wrote this article in my blog, Just Like a Magic. 

Overview

In addition to clearing the console screen, this lesson teaches you some about PInvoking, marshaling, and memory management. Also you will learn additional techniques like clearing a specific portion of the screen, and changing the cursor position. Moreover, you will dig into IL and see how System.Console.Clear() method do it. More than that you will learn how to reverse-engineer a .NET assembly and discover the code inside. In addition, the sample application shows how to perform I/O operations on console using Win32 API calls, and how to show/hide the console cursor. Moreover, it teaches you how to move the text around the console screen.   

Table of Contents 

Table of contents of this article:

  • Overview
  • Table of Contents
  • Introduction
  • GetStdHandle() Function
  • A Note about Marshaling
  • GetConsoleScreenBufferInfo() Function
  • A Note about Memory Management
  • A Look Inside the Memory
  • FillConsoleOutputCharacter() Function
  • SetConsoleCursorPosition() Function
  • Putting Things Together
  • Clearing the Console Screen
  • A Look Inside the .NET Library
  • References
  • Code Sample (The Tiny Console Library)
  • Summary 

Introduction

I am one of the huge supporters of console when it comes to the fact that we need simple and fast application such as tools and utilities. One of the common needs of console is performing clear-screens (CLSs) when necessary. When dealing with the Command Prompt you can order it to clear the screen by submitting the command "cls" and pressing Enter. But, programmatically, you have no way to order the command "cls," so you must find a substitute (or more.) Starting from version 2.0 of the .NET Framework, System.Console has been added a new method, it is the Clear() method for clearing the console screen. For versions before 2.0, or if you need to do it the hard-way, or even if you want to have more control over the clearing progress such as clearing a specific portion of the screen, you must dig into Win32 API and call special functions for doing so. Clearing the console screen done through four Win32 API functions, GetStdHandle(), GetConsoleScreenBufferInfo(), FillConsoleOutputCharacter() and SetConsoleCursorPosition(). It is worth noting that all these functions located in Kernel32.dll library.
Be sure that the System.Console.Clear() method in .NET 2.0 and descendant call these four functions -and more- initially. 

GetStdHandle() Function

This method is the gate for dealing with console via the API. Almost every console operation requires a call to GetStdHandle() first. GetStdHandle() simply returns the handle for the standard input, output, error device ("stream" in .NET methodology.) This function takes a single argument specifies which standard device (stream) we wish to retrieve the handle for. The syntax of this function -in C- is as following:
C++
HANDLE GetStdHandle(
  DWORD nStdHandle
); 
The nStdHandle argument can take one of three values:
  • STD_INPUT_HANDLE = -10
    Specifies the standard input device (stream.)
  • STD_OUTPUT_HANDLE = -11
    Specifies the standard output device (stream.)
  • STD_ERROR_HANDLE = -12
    Specifies the standard error device (stream.) It is always the output device (stream.)
As its names implies, input device used for receiving user input, output device used for writing output to the user, and error device used too for writing error information to the user. In .NET, you access these devices (streams) via nice wrappers. They are the static properties In, Out, and Error of the Console class. I guess that after playing with these nice wrappers you now know what standard devices are. Because there's no such way for .NET to interoperate with Win32 API directly, you need to create wrappers for the Win32 API functions you use, and this is done through PInvoking.
PInvoke stands for Platform Invocations. It is the mechanism for the .NET to interoperate with its "girlfriend" Win32 API.
The PInvoke method for GetStdHandle() is as following - code assumes that you add a using statement for the System.Runtime.InteropServices namespace:
C#
[DllImport("Kernel32.dll")]
public static extern IntPtr GetStdHandle(int nStdHandle); 
The DllImport attribute is required for PInvoke methods so that you can specify the DLL which the function resides in. Also DllImport have a very important role when you need to change the name of the method. If you need to change the name of the PInvoke method then you must set the property EntryPoint of DllImportAttribute to the original name of the function in the DLL. If you have not set this property, .NET will search the DLL for the method and will throw a System.EntryPointNotFoundException exception if it is not found. "static" and "extern" are modifiers required for PInvoke methods. Because some data types do not exist in .NET, you need to find a substitute. In other words, you need to marshal unmanaged Win32 data types to the new managed .NET types. So we have marshaled HANDLE to System.IntPtr and DWORD to System.Int32.
Only a single output handle serves the console application (the same for input and error devices,) so do not close that opened handle using the CloseHandle() function because it will result that you cannot write to the console any more, unless you open it again.

A Note about Marshaling 

Because there are plenty of Win32 data types that do not have correspondents in .NET, you must do Marshaling. Marshaling is the process of creating a bridge between .NET types and unmanaged types. Marshaling converts .NET types into unmanaged types. As we have seen in the last code, .NET does not contain DWORD, and because DWORD is a 32-bit unsigned integer we have to marshal it as System.UInt32. However, we marshaled it in GetStdHandle() as System.Int32! While unsigned integers (inculding DWORD) do not accept negative numbers, GetStdHandle() requires DWORD. Actually, it is OK because negative values can be stored in DWORD in a special way. For example, -10 stored as FFFFFFF6, -11 stored as FFFFFFF5, and so on. And that what GetStdHandle() actually does. In addition, you may notice that we have marshaled HANDLE as System.IntPtr, because IntPtr is the best type fits to any Win32 handle. Moreover, .NET supports managed handles via the abstract SafeHandle and CriticalHandle classes. It is worth mentioning that System.Runtime.InteropServices.MarshalAsAttribute attribute can have a noticeable effect over the marshaling process.
Good resources describe the marshaling process and the Win32 data types can be found in the references section.
Managed code is the .NET code that runs inside the CLR (Common Language Runtime,) because CLR manages and controls this code. Conversely, unmanaged code is the code other than the managed code. It is legal that you write code in .NET that runs outside the CLR such as direct memory management and that code called Unsafe Code because it is error-prone and may result to an unpredictable behavior. Also, MC++ allows you to write unmanaged code together with the managed code.

GetConsoleScreenBufferInfo() Function

The third method we will use is the GetConsoleScreenBufferInfo(). This method retrieves information about a specific console screen buffer (in other words, device.) This information is like console screen buffer size, the location and bounds of the console window, and the cursor position inside the screen. The definition of this function is as following:
C++
BOOL GetConsoleScreenBufferInfo(
  HANDLE hConsoleOutput,
  [out] SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo
);

struct CONSOLE_SCREEN_BUFFER_INFO {
  COORD dwSize;
  COORD dwCursorPosition;
  WORD wAttributes;
  SMALL_RECT srWindow;
  COORD dwMaximumWindowSize;
}

struct COORD {
  SHORT X;
  SHORT Y;
}

struct SMALL_RECT {
  SHORT Left;
  SHORT Top;
  SHORT Right;
  SHORT Bottom;
}
Lengthy, isn't it? Yeah, that's true. Beside the GetConsoleScreenBufferInfo(), there're three more structures, because the type of second argument of the function is the first structure, and the first structure in turn references the second and third structures. The CONSOLE_SCREEN_BUFFER_INFO structure represents the console information. This information is:
  • The size of the console screen buffer in character rows and columns.
  • The position of the cursor in the console screen in character rows and columns.
  • Characteristics of the character written to the console like the fore color and back color.
  • The location and bounds of the console window.
  • The maximum size for the console window if we take into account the font size and the screen buffer size.
What is screen buffer and window size and what is the difference? Start the Command Prompt and right click its icon in the taskbar and go to the layout tab of the properties dialog box. Take some time playing with the values in this tab. Window size is the size of the console window -like any other window.- Screen buffer size determines the amount of text which the console screen can hold, so you always see the vertical scroll bar because the buffer height is bigger than the window height.
Here's the PInvoke method and the marshaling types because .NET does not have such those three structures:
C#
[DllImport("Kernel32.dll")]
public static extern int GetConsoleScreenBufferInfo
    (IntPtr hConsoleOutput,
    out CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);

[StructLayout(LayoutKind.Sequential)]
public struct CONSOLE_SCREEN_BUFFER_INFO
{
    public COORD dwSize;
    public COORD dwCursorPosition;
    public ushort wAttributes;
    public SMALL_RECT srWindow;
    public COORD dwMaximumWindowSize;
}

[StructLayout(LayoutKind.Sequential)]
public struct COORD
{
    public short X;
    public short Y;
}

[StructLayout(LayoutKind.Sequential)]
public struct SMALL_RECT
{
    public short Left;
    public short Top;
    public short Right;
    public short Bottom;
}
Because .NET does not contain such these three structures, and we do not have any substitutes, so we have to marshal it, we have created it manually and mapped unmanaged to the managed data types. And because memory layout of such these object is very important, we added the StructLayout attribute and specified LayoutKind.Sequential that informs the marshaller that this structure will laid-out in memory sequentially so the first field comes before the second and so on. Also you might notice that WORD unmanaged data type is an unsigned 32-bit integer so we marshaled it as System.UInt32. Also SHORT is signed 16-bit integer so it is very easy to marshal it as System.Int16. Refer to the references section for more information about Win32 data types.
BOOL defined as a 32-bit signed integer, so we have marshaled the return value of the function as Int32 not Boolean because Boolean reserves 4-bits only. It will work well with Boolean, but it is better using Int32. Though, if you want to use Boolean, is helpful decorating the return value with the MarshalAs attribute.
Also, it is very efficient to use the System.Runtime.InteropServices.InAttribute and System.Runtime.InteropServices.OutAttribute to give a notation to the marshaller. The code sample demonstrates this.

A Note about Memory Management 

You already know that every object reserves space in memory. And the memory itself divided into two parts, Heap and Stack. Objects -directly or indirectly- inherit from System.ValueType are stack-based (like structures, enumerations and primitive data types.) Conversely, most objects -directly or indirectly- inherit from System.Object are heap-based (like most objects.) And you know also that heap objects managed by the Garbage Collector (GC) and they may remain in the memory for a long time -actually even if you called System.GC many times.- On the other hand, stack objects are removed from the memory immediately when their scope ends. In addition, you need to know that stack is filled downwards. See figure 1.

Stack Memory

When interoperating with unmanaged code and marshaling types between the .NET and Win32 API (for instance) you need to know how to layout your type in memory. Unmanaged code assumes that types are laid sequentially based on the order of fields. For our example, the CONSOLE_SCREEN_BUFFER_INFO must be laid-out so dwSize comes before dwCursorPosition and so on. See figure 2.

CONSOLE_SCREEN_BUFFER_INFO in Memory

We can dig into more details and see how Windows will store the CONSOLE_SCREEN_BUFFER_INFO structure in the stack and how it will be rendered. See figure 3.

console_screen_buCONSOLE_SCREEN_BUFFER_INFO in Memory _ DetailsCONSOLE_SCREEN_BUFFER_INFO in Memory _ Details

From the diagrams we learn that:
  • Objects are stored downwards in the stack by the order they were created.
  • Object containing objects also stored downwards by the order they were declared.
  • Every object has a size. And this size determined by its containing objects -if it is not a primitive type of course.-
You can get the size of an object using two ways, the sizeof keyword, and System.Runtime.InteropServices.Marshal.SizeOf() method. The second method is preferred. Do you know why? Try, think, and then answer.
Now, we know why the StructLayout attribute is required. And why sequential layout is required. But what if you prefer to change the order of fields? Answer is very simple. Change the LayoutKind to Explicit and decorate every field with FieldOffset attribute and specify its location from the beginning of the structure. In the following code fields are reversed but they perfectly laid-out in memory using the FieldOffset attribute:
C#
[StructLayout(LayoutKind.Explicit)]
public struct CONSOLE_SCREEN_BUFFER_INFO
{
    [FieldOffset(18)]
    public COORD dwMaximumWindowSize;
    [FieldOffset(10)]
    public SMALL_RECT srWindow;
    [FieldOffset(8)]
    public ushort wAttributes;
    [FieldOffset(4)]
    public COORD dwCursorPosition;
    [FieldOffset(0)]
    public COORD dwSize;
}
If you set the LayoutKind to Auto, you will not be able to interoperate with unmanaged code using the type. Although, if you have omitted the whole StructLayoutAttribute.
Also, from the diagrams illustrated -specially the last one- we can also write our CONSOLE_SCREEN_BUFFER_INFO structure to be as following and remove the other two structures:
C#
[StructLayout(LayoutKind.Sequential)]
public struct CONSOLE_SCREEN_BUFFER_INFO
{
    public short dwSizeX;
    public short dwSizeY;
    public short dwCursorPositionX;
    public short dwCursorPositionY;
    public ushort wAttributes;
    public short srWindowLeft;
    public short srWindowTop;
    public short srWindowRight;
    public short srWindowBottom;
    public short dwMaximumWindowSizeX;
    public short dwMaximumWindowSizeY;
} 
Sounds odd, isn't it? You can also set the LayoutKind to Explicit and start working.
It is also possible to union two fields -or more- into one. For example, merging the two 16-bit integers dwSizeX and dwSizeY into one 32-bit integer, dwSize. It will work very well! In addition, you can divide them in your code using System.Collections.Specialized.BitVector32 structure.

A Look Inside the Memory

Now, this time we are going to do something interesting. We are going to look on our structure in the memory. For simplicity, we are going to use these types:
C#
[StructLayout(LayoutKind.Sequential)]
public struct CONSOLE_SCREEN_BUFFER_INFO
{
    public COORD dwSize;
    public COORD dwCursorPosition;
    public ushort wAttributes;
    public SMALL_RECT srWindow;
    public COORD dwMaximumWindowSize;
}

[StructLayout(LayoutKind.Sequential)]
public struct COORD
{
    public short X;
    public short Y;
}

[StructLayout(LayoutKind.Sequential)]
public struct SMALL_RECT
{
    public short Left;
    public short Top;
    public short Right;
    public short Bottom;
}
Next, we will initialize the structures with some data to see how it stored in the memory.
C#
unsafe static void Main()
{
    CONSOLE_SCREEN_BUFFER_INFO info
        = new CONSOLE_SCREEN_BUFFER_INFO();

    info.dwSize = new COORD();
    info.dwSize.X = 0xA1;
    info.dwSize.Y = 0xA2;

    info.dwCursorPosition = new COORD();
    info.dwCursorPosition.X = 0xB1;
    info.dwCursorPosition.Y = 0xB2;

    info.wAttributes = 0xFFFF;

    info.srWindow = new SMALL_RECT();
    info.srWindow.Left = 0xC1;
    info.srWindow.Top = 0xC2;
    info.srWindow.Right = 0xC3;
    info.srWindow.Bottom = 0xC4;

    info.dwMaximumWindowSize = new COORD();
    info.dwMaximumWindowSize.X = 0xD1;
    info.dwMaximumWindowSize.Y = 0xD2;

    uint memoryAddress =
        (uint)&info;

    Console.WriteLine(
        "Memory Address: 0x{0:X}",
        memoryAddress);

    Console.WriteLine("Press any key . . .");
    Console.ReadKey(true);

    // You can add a break point on the last line,
    // or you can use this function to break the code.
    System.Diagnostics.Debugger.Break();
}
This code assumes that you enabled the unsafe code from the Build tab of the project properties. Also, it assumes that you run your code in the debugging mode by pressing F5, or by clicking Start Debugging from the Debug menu.
Now, and after breaking the code, click Debug -> Windows -> Memory -> Memory 1 to open a memory window. Figure 4 shows how to open a memory window. And figure 5 shows the memory window opened. Click on the figures to enlarge.

Showing Memory Window

Memory Window

Now, you can locate your structure in memory by typing its memory address. Figure 6 shows the structure in the memory window.

Memory Window + CONSOLE_SCREEN_BUFFER_INFO

Now, take your time looking on how the structure -and its contained structures- laid-out in memory.

FillConsoleOutputCharacter() Function

Last but not least, this is the fourth function we will use. This function fills a specific console buffer portion with a specific character. Passing a white space as the character means clearing this portion. The syntax of this function is as following:
C#
BOOL FillConsoleOutputCharacter(
  HANDLE hConsoleOutput,
  TCHAR cCharacter,
  DWORD nLength,
  COORD dwWriteCoord,
  [out] LPDWORD lpNumberOfCharsWritten
);
This function takes four input arguments and a single output one, and it returns a value determines whether the function succeeded or failed. If the return value is non-zero (true) then the function succeeded, otherwise failed (that's for GetConsoleBufferInfo() and SetConsoleCursorPosition() also.) The five arguments are:
  • hConsoleOutput:
    A handle to an opened console output device to write to.
  • cCharacter:
    The character which to fill the buffer portion with.
  • nLength:
    The number of characters to write.
  • dwWriteCoord:
    A COORD structure defines where to begin writing (the first cell.)
  • lpNumberOfCharsWritten:An output parameters determines the number of characters written.
Here's the PInvoke method of this function: We have omitted the COORD structure because we have created it earlier.
C#
[DllImport("Kernel32.dll")]
public static extern int FillConsoleOutputCharacter
    (IntPtr hConsoleOutput, char cCharacter, uint nLength,
    COORD dwWriteCoord, out uint lpNumberOfCharsWritten);
Notice that the unmanaged data types DWORD and LPDOWRD are marshaled to System.UInt32. For more information about unmanaged data types see the references section.

SetConsoleCursorPosition() Function

This function is used to set the cursor position in the console screen buffer. The syntax of this function is as following:
C++
BOOL SetConsoleCursorPosition(
  HANDLE hConsoleOutput,
  COORD dwCursorPosition
); 
This function takes two arguments the first is a handle for an opened console output device. The second is a value specifies the new cursor position. Note that the new cursor position must be inside the console screen buffer. The PInvoke method for this function is:
C#
[DllImport("Kernel32.dll")]
public static extern int SetConsoleCursorPosition
    (IntPtr hConsoleOutput, COORD dwCursorPosition);

Putting Things Together 

After all, we have learned the required functions and created the PInvoke method, so we can mix it up and start coding. Here's the full code:
C#
public const int STD_OUTPUT_HANDLE = -11;
public const char WHITE_SPACE = ' ';

[DllImport("Kernel32.dll")]
public static extern IntPtr GetStdHandle(int nStdHandle);

[DllImport("Kernel32.dll")]
public static extern int GetConsoleScreenBufferInfo
    (IntPtr hConsoleOutput,
    out CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);

[DllImport("Kernel32.dll")]
public static extern int FillConsoleOutputCharacter
    (IntPtr hConsoleOutput, char cCharacter, uint nLength,
    COORD dwWriteCoord, out uint lpNumberOfCharsWritten);

[DllImport("Kernel32.dll")]
public static extern int SetConsoleCursorPosition
    (IntPtr hConsoleOutput, COORD dwCursorPosition);

[StructLayout(LayoutKind.Sequential)]
public struct CONSOLE_SCREEN_BUFFER_INFO
{
    public COORD dwSize;
    public COORD dwCursorPosition;
    public ushort wAttributes;
    public SMALL_RECT srWindow;
    public COORD dwMaximumWindowSize;
}

[StructLayout(LayoutKind.Sequential)]
public struct COORD
{
    public short X;
    public short Y;
}

[StructLayout(LayoutKind.Sequential)]
public struct SMALL_RECT
{
    public short Left;
    public short Top;
    public short Right;
    public short Bottom;
}

Clearing the Console Screen 

And this is the code that clears the console screen:
C#
static void Main()
{
    Console.WriteLine("Writing some text to clear.");

    Console.WriteLine("Press any key to clear . . . ");
    Console.ReadKey(true);

    ClearConsoleScreen();
}

public static void ClearConsoleScreen()
{
    // Getting the console output device handle
    IntPtr handle = GetStdHandle(STD_OUTPUT_HANDLE);

    // Getting console screen buffer info
    CONSOLE_SCREEN_BUFFER_INFO info;
    GetConsoleScreenBufferInfo(handle, out info);

    // Discovering console screen buffer info
    Console.WriteLine("Console Buffer Info:");
    Console.WriteLine("--------------------");
    Console.WriteLine("Cursor Position:");
    Console.WriteLine("t{0}, {1}",
        info.dwCursorPosition.X, info.dwCursorPosition.Y);
    // Is this information right?
    Console.WriteLine("Maximum Window Size:");
    Console.WriteLine("t{0}, {1}",
        info.dwMaximumWindowSize.X,
        info.dwMaximumWindowSize.Y);
    // Is this information right?
    Console.WriteLine("Screen Buffer Size:");
    Console.WriteLine("t{0}, {1}",
        info.dwSize.X, info.dwSize.Y);
    Console.WriteLine("Screen Buffer Bounds:");
    Console.WriteLine("t{0}, {1}, {2}, {3}",
        info.srWindow.Left, info.srWindow.Top,
        info.srWindow.Right, info.srWindow.Bottom);
    Console.WriteLine("--------------------");

    // Location of which to begin clearing
    COORD location = new COORD();
    location.X = 0;
    location.Y = 0;
    // What about clearing starting from
    // the second line
    // location.Y = 1;

    // The number of written characters
    uint numChars;

    FillConsoleOutputCharacter(handle, WHITE_SPACE,
        (uint)(info.dwSize.X * info.dwSize.Y),
        location, out numChars);

    // The new cursor location
    COORD cursorLocation = new COORD();
    cursorLocation.X = 0;
    cursorLocation.Y = 0;

    SetConsoleCursorPosition(handle, cursorLocation);
}
Also we can step further and write code that clears a specific portion of the console screen buffer, try this code:
C#
static void Main()
{
    // Require the user to enter his password
    AuthenticateUser();
}

public static void AuthenticateUser()
{
    Console.WriteLine("Please enter your password:");
    Console.Write("> "); // Two characters right

    string input = Console.ReadLine();

    while (input != "MyPassword")
    {
        COORD location = new COORD();
        // The third character
        location.X = 2;
        // The second line
        location.Y = 1;
        ClearConsoleScreen(location);
        input = Console.ReadLine();
    }

    // User authenticated
    Console.WriteLine("Authenticated!");
}

public static void ClearConsoleScreen
    (COORD location)
{
    // Getting the console output device handle
    IntPtr handle = GetStdHandle(STD_OUTPUT_HANDLE);

    // Getting console screen buffer info
    CONSOLE_SCREEN_BUFFER_INFO info;
    GetConsoleScreenBufferInfo(handle, out info);

    // The number of written characters
    uint numChars;

    FillConsoleOutputCharacter(handle, WHITE_SPACE,
        (uint)(info.dwSize.X * info.dwSize.Y),
        location, out numChars);

    SetConsoleCursorPosition(handle, location);
}

A Look Inside the .NET Library 

Here we will look inside the library mscorlib.dll and see how it implements System.Console.Clear() method. This library is the core library that every .NET application must reference, it defines the core classes and components that are essential for every application. Also, it contains classes that are required by the CLR (Common Language Runtime.)
If you are using .NET 2.0 or higher you can continue this section, otherwise, you may pass this section because the Clear() method is new with the .NET 2.0.
MSIL, CIL, and IL all refer to the same thing the intermediate Language.
MSCORLIB stands for Microsoft Common Object Runtime Library.

Using the IL Disassembler 

.NET Framework comes with a tool that allows you to reverse-engineer any assembly and view its MSIL (Microsoft Intermediate Language) instructions. This tool called IL Disassembler (ILDasm). You can find this tool in the .NET install directory in %ProgramFiles%\Microsoft SDKs\Windows<WindowsVersion>\Bin for the version 3.5, and <VSInstallDir>\Common7\bin for versions before. After opening ILDasm.exe you can open the file mscorlib.dll inside. Click File -> Open and select the library file which located in %WinDir%\Microsoft.NET\Framework\<RuntimeVersion>. Figure 7 shows IL Disassembler with the mscorlib.dll opened.

ILDASM + mscorlib_dll

Now open the namespace System, then step down to the System.Console class and double-click the Clear() method to show the IL instructions. Take a look on how the Clear() method do it. 

Using Another Tool

If MSIL seems odd, you may try another perfect tools that can reverse-engineer your assembly to your preferred language (like C# or VB.NET for instance.) Some famous tools are Lutz Roeder's .NET Reflector and XenoCode Fox.  

For me, I prefer the first tool because it is faster, simpler, and supports many features.
Of course you can reflect (reverse-engineer) an assembly and learn nice tricks from the code inside.

References

Sample Code (The Tiny Console Library)

This sample code demonstrates some of the hidden functionality of Console applications, such as moving a text around the screen and clearing a specific portion of the screen.

Download the Sample Code

Summary

So you have learned how to clear the console screen using Win32 API. In addition, you learned many techniques including PInvoking, marshaling, memory management, and how to reverse-engineer a .NET assembly and get its code out. Moreover, you learned many ideas to apply when working with unmanaged code via .NET.  Be sure to check the sample application - it provides you with many features that you will not find in the .NET Framework SDK (nor many other SDKs I think.) It illustrates many techniques including how to clear a specific portion of the screen and how to move a text around the screen. In addition, it shows all common console operations, like reading and writing to the screen buffer, done through the Win32 API and .NET. D 

License

This article, along with any associated source code and files, is licensed under The Common Public License Version 1.0 (CPL)


Written By
Technical Lead
Egypt Egypt
Mohammad Elsheimy is a developer, trainer, and technical writer currently hired by one of the leading fintech companies in Middle East, as a technical lead.

Mohammad is a MCP, MCTS, MCPD, MCSA, MCSE, and MCT expertized in Microsoft technologies, data management, analytics, Azure and DevOps solutions. He is also a Project Management Professional (PMP) and a Quranic Readings college (Al-Azhar) graduate specialized in Quranic readings, Islamic legislation, and the Arabic language.

Mohammad was born in Egypt. He loves his machine and his code more than anything else!

Currently, Mohammad runs two blogs: "Just Like [a] Magic" (http://JustLikeAMagic.com) and "مع الدوت نت" (http://WithdDotNet.net), both dedicated for programming and Microsoft technologies.

You can reach Mohammad at elsheimy[at]live[dot]com

Comments and Discussions

 
Questioncode link broken Pin
mikan668-Sep-21 4:05
mikan668-Sep-21 4:05 
GeneralI have attached the source code Pin
Mohammad Elsheimy13-May-09 5:18
Mohammad Elsheimy13-May-09 5:18 
GeneralYou might want to add a code download Pin
Jeff Circeo13-May-09 4:38
Jeff Circeo13-May-09 4:38 
GeneralInteresting Pin
Garth J Lancaster12-May-09 12:15
professionalGarth J Lancaster12-May-09 12:15 
GeneralRe: Interesting Pin
Mohammad Elsheimy13-May-09 3:36
Mohammad Elsheimy13-May-09 3:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.