Axialis Software offers this 50% off sale on all their products for today only. This is a short notice, but if you are looking for an icon or cursor editor, IconWorkshop or CursorWorkshop are the ones to go with. I’m using IconWorkshop for some time and I find it a great tool for creating and editing icons. There is a free edition too, but it’s limited, so if you’re interested in getting the full version, today is your chance to do it for the half price.

Hits for this post: 4800 .

Have you tried to print colored text in a console or put the text at a specific position? You know then that STL or CRT does not provide that functionality.
Windows API however, contains a set of functions for working with console windows. The list of these functions is available in MSDN.

However, to simplify the use of these functions I have created a template, wrapper class that provides methods and overloaded operators to:

  • change the color for text and background
  • set the cursor position
  • write to the console
  • read from the console

The class is called basic_console, and is a template class. There are two specializations, one for ANSI, called console, and one for UNICODE, called wconsole.

typedef basic_console< char, std::char_traits< char >> console;
typedef basic_console< wchar_t, std::char_traits< wchar_t >> wconsole;

You can change the position on both horizontal and vertical or on only one of the two:

   void GoTo(int x, int y)
   void GoToX(int x)
   void GoToY(int y)
   console_pos GetConsolePos()

There is also an overloaded operator for changing the position, specified with a console_pos structure.

	_Myt& operator<<(const console_pos& pos)

For the color, you can change the text and background color, using one of these functions:

   void SetForeColor(text_color::Color crText)
   void SetBackColor(bg_color::Color crBack)
   void SetColors(text_color::Color crText, bg_color::Color crBack)
   void SetColors(WORD colors)
   void SetColors(WORD crText, WORD crBack)
   void UseDefaultColors()

   _Myt& operator<<(const console_colors& col)

Number of colors are limited, but we can combine them to produce more. Windows defines separate flags for the text and background colors.
I have created two classes text_color and back_color to define mnemonics for colors based on these flags.

class text_color
{
public:
	enum Color
	{
		Black = 0,
		White = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED,
		Blue = FOREGROUND_BLUE,
		Green = FOREGROUND_GREEN,
		Red = FOREGROUND_RED,
		Yellow = FOREGROUND_RED | FOREGROUND_GREEN,
		Magenta = FOREGROUND_RED | FOREGROUND_BLUE,
		LightWhite = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY,
		LightBlue = FOREGROUND_BLUE | FOREGROUND_INTENSITY,
		LightGreen = FOREGROUND_GREEN | FOREGROUND_INTENSITY,
		LightRed = FOREGROUND_RED | FOREGROUND_INTENSITY,
		LightYellow = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
		LightMagenta = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
	};
};

class bg_color
{
public:
	enum Color
	{
		Black = 0,
		White = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED,
		Blue = BACKGROUND_BLUE,
		Green = BACKGROUND_GREEN,
		Red = BACKGROUND_RED,
		Yellow = BACKGROUND_RED | BACKGROUND_GREEN,
		Magenta = BACKGROUND_RED | BACKGROUND_BLUE,
		LightWhite = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY,
		LightBlue = BACKGROUND_BLUE | BACKGROUND_INTENSITY,
		LightGreen = BACKGROUND_GREEN | BACKGROUND_INTENSITY,
		LightRed = BACKGROUND_RED | BACKGROUND_INTENSITY,
		LightYellow = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_INTENSITY,
		LightMagenta = BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY,
	};
};

Let's see several examples. The first one, shows how to print text with different colors. Moreover, the colored text is always displayed starting with column 40.

int main()
{
   console con;

   con.SetForeColor(text_color::White);
   con << "Processing with files";
   con.GoToX(40);
   con << "OK" << "n";

   con.SetForeColor(text_color::White);
   con << "Looking for templates";
   con.GoToX(40);
   con.SetForeColor(text_color::LightYellow);
   con << "Not found" << "n";

   con.SetForeColor(text_color::White);
   con << "Creating new account";
   con.GoToX(40);
   con.SetForeColor(text_color::LightRed);
   con << "Failed" << "n";

   return 0;
}

Here is the output for this program

A second example shows how to print numbers starting from 1 to N and back to 1 to form a rhomb.

int main()
{
   console con;

   int depth;
   con << "Depth (1-9)? ";
   con >> depth;

   int middle = 20;
   for(int i = 1; i <= depth; ++i)
   {
      con.GoToX(middle-i+1);
      for(int j = 1; j<=i; ++j)
      {
         con << i << " ";
      }
      con << "n";
   }
   for(int i = depth-1; i >=1; --i)
   {
      con.GoToX(middle-i+1);
      for(int j = 1; j<=i; ++j)
      {
         con << i << " ";
      }
      con << "n";
   }

   return 0;
}

And here is the output, when the selected depth is 9:

The same can be achived using the overloaded operator<< for console_pos.

int main()
{
   console con;

   int depth;
   con << "Depth (1-9)? ";
   con >> depth;

   int x = 20;
   int y = 2;
   for(int i = 1; i <= depth; ++i)
   {
      con << console_pos(x-i+1, y++);
      for(int j = 1; j<=i; ++j)
      {
         con << i << " ";
      }
   }
   for(int i = depth-1; i >=1; --i)
   {
      con << console_pos(x-i+1, y++);
      for(int j = 1; j<=i; ++j)
      {
         con << i << " ";
      }
   }

   return 0;
}

A third and last examples shows how to read a matrix on rows and columns.

int main()
{
   console con;

   int rows;
   int cols;

   con << "rows: "; con >> rows;
   con << "cols: "; con >> cols;

   std::vector< int > numbers;

   for(int i = 0; i < rows; ++i)
   {
      for(int j = 0; j < cols; ++j)
      {
         con.GoTo(j*4, i+2);
         con << "[_]";
      }
   }
   int val;
   for(int i = 0; i < rows; ++i)
   {
      for(int j = 0; j < cols; ++j)
      {
         con.GoTo(j*4+1, i+2);
         con >> val;
         numbers.push_back(val);
      }
   }

   return 0;
}

Of course, this basic_console class does not carry all the possible functionality you can imagine, but it should be good enough for basic operations.

Here is the file with the source code.

, Hits for this post: 9391 .

Sometimes, when searching in Visual Studio (all version since 2003 at least) you get this message:

No files were found to look in.
Find was stopped in progress.

It cannot find any match for the search criteria, even if there are thousands. And it displays that message immediately after pressing Search. You can search again (for something else), restart Visual Studio, restart Windows, it will do no good. The message will always be the same.

What’s the cause? I don’t know, but I’ve noticed this happens when I search for something while the solution is building.

What’s the solution? Well, pressing CTRL + SCROLL LOCK does the magic. You don’t have to have anything (search dialog) open. Just press those keys in Visual Studio and serach will be up and running.

Hits for this post: 4892 .

FParsec is an F# adaptation of Parsec, a free monadic parser combinator library for Haskell. It can parse context-sensitive, infinite look-ahead grammars, has complete support for unicode input and large files (> 4 GB) and produces excellent error messages.

You can download and install it from the above link. To use it in an application, you must add a reference to FParsec.dll and FParsecCS.dll.

In this post I will use FParsec to parse ranges of numerical values, such as [1-100], and IPs, such as [10.5.10.0-10.5.255.255].

I will start by defining some types:

type IPAddr = {C1: int64; C2:int64; C3: int64; C4: int64;}
type TValue =
   | Num of int64
   | IP of IPAddr

type Range = {Min : TValue; Max : TValue;}

Having that, I can define a parser for numerical ranges like this:

let p_numrange =
   parse
      {
         do! skipChar '['
         let! a = pint64
         do! skipChar '-'
         let! b = pint64
         do! skipChar ']'
         return {Min = Num a; Max = Num b;}
      }

That can be read like this: make sure it stars with [ byt skip that, parse an numerical value and let that be a, make sure - follows but skip that, parse a second numerical value and let that be b, make sure ] follows but skip that, and it if successful return a Range of a and b.

To print a Range value I’ll use this function:

let printip (ip:IPAddr) =
   printf "%d.%d.%d.%d" ip.C1 ip.C2 ip.C3 ip.C4
   ()

let printrange (r:Range) =
   match (r.Min, r.Max) with
   | Num(l1),Num(l2) -> printfn "Range: %d-%d" l1 l2
   | IP(ip1),IP(ip2) ->
      printf "Range: "
      printip ip1
      printf "-"
      printip ip2
      printfn ""
   | _ -> ()
   ()

Here is a test

   let result = run p_numrange "[1-100]"
   match result with
   | Success r -> printrange r
   | Failure (msg, err) -> printf "%s\n" msg
   ()

That outputs:

Range: 1-100

Using “(1-100)” instead of “[1-100]” yields the following error message:

Error in Ln: 1 Col: 1
(1-100)
^
Expecting: '['

Let's move forward and define an IP parses. Based on what I did so far this should be pretty easy to understand.

let p_ip =
   parse
      {
         let! c1 = pint64
         do! skipChar '.'
         let! c2 = pint64
         do! skipChar '.'
         let! c3 = pint64
         do! skipChar '.'
         let! c4 = pint64
         return {C1 = c1; C2 = c2; C3 = c3; C4 = c4;}
      }

And an IP range parser would look just like the first range parser, except that pint64 would be replaced by p_ip:

let p_iprange =
   parse
      {
         do! skipChar '['
         let! a = p_ip
         do! skipChar '-'
         let! b = p_ip
         do! skipChar ']'
         return {Min = IP a; Max = IP b;}
      }

Here are some helper functions for testing these parses:

let testrange range =
   let result = run (p_numrange .>> eof) range
   match result with
   | Success r -> printrange r
   | Failure (msg, err) -> printf "%s\n" msg
   ()

let testip ip =
   let result = run (p_ip .>> eof) ip
   match result with
   | Success ip -> printip ip; printfn ""
   | Failure (msg, err) -> printf "%s\n" msg
   ()   

let testiprange range =
   let result = run (p_iprange .>> eof) range
   match result with
   | Success r -> printrange r
   | Failure (msg, err) -> printf "%s\n" msg
   ()

You probably noticed the construction “(p_numrange .>> eof)”. That reads: parse a range, and then the end of the file and return the range. That helps us making sure nothing follows the range, like “[1-100] more here”.

Executing

testrange "(1-100)"
testrange "[1-100]"
testrange "[1]"

yields

Error in Ln: 1 Col: 1
(1-100)
^
Expecting: '['

Range: 1-100
Error in Ln: 1 Col: 3
[1]
  ^
Expecting: '-'

Executing

testip "192.168"
testip "192.168.0.1"
testip "192.168.0.1 "

yields

Error in Ln: 1 Col: 8
192.168
       ^
Expecting: '.'

192.168.0.1
Error in Ln: 1 Col: 12
192.168.0.1
           ^
Expecting: end of file

and executing

testiprange "[10.5.0.1-10.5.255.255]"
testiprange "[10-10.5.255.255]"

yields

Range: 10.5.0.1-10.5.255.255
Error in Ln: 1 Col: 4
[10-10.5.255.255]
   ^
Expecting: '.'

But why defining two range parser? Isn’t possible to have just a single one and specify which parser to use for the values? Yes, it is possible, and that would look like this:

let p_range p =
   parse
      {
         do! skipChar '['
         let! a = p
         do! skipChar '-'
         let! b = p
         do! skipChar ']'
         return {Min = a; Max = b;}
      }

Having that, we can re-define the p_numrange and p_iprange like shown bellow:

let p_ip =
   parse
      {
         let! c1 = pint64
         do! skipChar '.'
         let! c2 = pint64
         do! skipChar '.'
         let! c3 = pint64
         do! skipChar '.'
         let! c4 = pint64
         return IP {C1 = c1; C2 = c2; C3 = c3; C4 = c4;}
      }

let p_int =
   parse
      {
         let! v = pint64
         return Num v
      }

let p_numrange = p_range p_int
let p_iprange = p_range p_ip

Everything above would work, except for testip function that needs change to:

let testip ip =
   let result = run (p_ip .>> eof) ip
   match result with
   | Success ip -> match ip with
                   | IP v -> printip v; printfn ""
                   | _ -> printfn "error"
   | Failure (msg, err) -> printf "%s\n" msg
   ()

That’s about it about parsing ranges with FParsec.

Hits for this post: 9597 .