[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1162
  • Last Modified:

windows.h console functions, smitty1276

please take a look at the class below and suggest how i can display variables (i.e. integer vars, string vars, etc.) can the print function be overloaded to handle other data types?

// console.h
#ifndef CONSOLE_H
#define CONSOLE_H

#include <windows.h>

class console
{
public:
     console();
     void conInit   ();
     void cls       (void);
     void print     (char *text);
     void gotoxy    (short x, short y);
     void fontColor (WORD attr);
private:
     HANDLE scr;
};

#endif

// console.cpp
#include "console.h"

console::console()
{
     conInit();
}

void console::conInit(void)
{
    scr = CreateConsoleScreenBuffer( GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CONSOLE_TEXTMODE_BUFFER, 0 );
    SetConsoleActiveScreenBuffer( scr );
}

void console::cls(void)
{
     CloseHandle(scr);
     scr = CreateConsoleScreenBuffer( GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CONSOLE_TEXTMODE_BUFFER, 0 );
     SetConsoleActiveScreenBuffer( scr );
}

void console::print(char *text)
{
     char buf[1024];
     strcpy(buf, text);
     DWORD num;
     WriteConsole( scr, buf, strlen(text), &num, 0);
}

void console::gotoxy(short x, short y)
{
     COORD pos = { y, x };
     SetConsoleCursorPosition(scr, pos);
}

void console::fontColor(WORD attr)
{
     SetConsoleTextAttribute(scr, attr);
}

// consoleMain.cpp
#include "console.h"

#include <string>
using std::string;

void main()
{
     int num = 5;
     sting name;
     name = "kiphughes";

     console A;
     A.cls();
     A.conInit();
     A.gotoxy(5,5);
     A.fontColor(FOREGROUND_RED);
     A.print("This is a test");
     A.print(name);                    // won't print string
     A.print(num);                    // won't print int
     A.print(num + num);               // won't print calculations
     A.cls();
}
0
kiphughes
Asked:
kiphughes
1 Solution
 
makerpCommented:

    void print     (int num);

    void print     (char *text);

    void print     (float number);

then just implement them, c++ supports method overloading, the parameters must be different
0
 
nietodCommented:
Some suggestions...

Your must remember to call close. If you failt to call close you will cause a resource leak.  Dangerious.  Instead give the class a destructor and have it call close..  Pluse the close function "reopens"   I assume that is a mistake.  if not that is another memory leakl.  A good safe  system woudl be

console::console() :
   scr(INVALID_HANDLE_VALUE) // Indicate class is colose
{
   conInit();
}

console::~console()
{
   cls();// Make sure class is closed.
}


void console::conInit(void)
{
   if (!Isclosed())  // If called when open
      cls();             // be sure to close first.
   scr = CreateConsoleScreenBuffer( GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
    0, CONSOLE_TEXTMODE_BUFFER, 0 );
    SetConsoleActiveScreenBuffer( scr );
}

void console::cls(void)
{
   CloseHandle(scr);
   scr = INVALID_HANDLE_VALUE;
}

bool console::IsClosed() const
{
    return scr == INVALID_HANDLE_VALUE;
}

Now it is still "unsafe" to use this class for output when it is closed.  It will simply ignore the requested operation in this case, it will not act unpredictably, so its an improvement over yoru version.


Your print function will fail to print anything longer than 1k.  sometimes that sort of limit is needed, but in this case it was totally arbitrary because you added an unnecessary copying of the data.  Try.

oid console::print(const char *text)
{
   DWORD num;
   WriteConsole( scr, text, strlen(text), &num, 0);
}l

Now you can overload the output functiosn as markerp suggested, but I would recommend using operator << 

0
 
nietodCommented:
for example,

console &operator << (console &Con,const char *Dat)
{
   con.print(Dat);
   return Con;
};

console &operator << (console &Con,int Dat)
{
   char Str[32];

   sprintf(Str,"%i",Dat);
   con.print(Str);
   return Con;
};

console &operator << (console &Con,double Dat)
{
   char Str[32];

   sprintf(Str,"%e",Dat);
   con.print(Str);
   return Con;
};

console &operator << (console &Con,char Dat)
{
   char Str[2] = "?";

   Str[0] = Dat;;
   con.print(Str);
   return Con;
};


Now you can do things like

console C;

C << "Label:" << ' ' << 123 << ' ' << 123.456;

0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
smitty1276Commented:
Actually, that wasn't intended to be a close function.  It was supposed to be a clear screen function (I just stole the old BASIC function name).  

Like I said before... I haven't used ConsoleScreenBuffer objects all that much myself.  When I posted those functions I specified that there was probably a better way to clear the screen.  I just found that closing the handle and reopening it was the quickest to code, and it seemed to do the job.

You bring up a good point though. There needs to be a method that will close the buffer and deallocate the memory.
0
 
kiphughesAuthor Commented:
how does this display a string?

example:

console C;
string str = "kiphughes";

C << str;
0
 
kiphughesAuthor Commented:
nietod,

also, where am i suppose to put the code u posted? do i put it in the console class? or do i put that in a different class that will use the overloaded operators? either way, what must i put in the .h file? i think i'd rather have this in my console class.

btw, what's the difference here?
console &operator << (console &Con,char Dat)
console &operator << (console &Con,const char *Dat)
0
 
nietodCommented:
>> lso, where am i suppose to put the code u posted?
the operator << functions are free functions (not members of the console class.  that is why tha don't have "console::" in there names.  The rest is in the console class, that is why they have "Console::" in their names.

>> what must i put in the .h file?
The changes to the console class and the operator << functions, but those go outside of the class.

>> console &operator << (console &Con,char Dat)
>> console &operator << (console &Con,const char *Dat)
the first outputs a character, the 2nd poiputs a NUL termianted strign of charcters, like

SomeConsole << 'A';  // Single charcter.
SomeConsole << "A"; // String of 1 character.

For those two cases the differences doesn't seem important, but there will probably be times when you have only a single character as a varaible and need to ouput it and you don't want to have to form a NUL termianted string from it.
0
 
kiphughesAuthor Commented:
what about displaying a string?
0
 
nietodCommented:
That is what the 2nd one does.   I could be a string of 1 character or a string of 1000.
0
 
nietodCommented:
Oh you mean a STL string object.

console &operator << (console &Con,const string &Str)
{
   con.print(Str.c_str());
   return Con;
};

i.e. to print anyting, pass it to operator <<.  then convert that thing to a string and pass the converted string to prnt().
0
 
kiphughesAuthor Commented:
it won't work for some reason, i get this message:

error C2664: 'print' : cannot convert parameter 1 from 'const char *' to 'char *'
        Conversion loses qualifiers
Error executing cl.exe.

this is how the string is declared:

#include <string>
using std::string;

string str;
str = "kiphughes";
0
 
nietodCommented:
             error C2664: 'print' : cannot convert parameter 1 from 'const char *' to 'char *'
the problem is in print().  It should be declared to take a parameter that is a constant character pointer.  I did that above.  print doesn't change the string so there is no loss n functionallity by making this explicit, by adding the const.  But when you make it constant you increase the usability of the function.  it can be used with non-constant string AND with constant strings.  (your version could only be used with non-constant strings).   This more than doubles the usability of the function since most strings actually will be constant.
0
 
kiphughesAuthor Commented:
i got it working, thanx!
0

Featured Post

[Webinar] Kill tickets & tabs using PowerShell

Are you tired of cycling through the same browser tabs everyday to close the same repetitive tickets? In this webinar JumpCloud will show how you can leverage RESTful APIs to build your own PowerShell modules to kill tickets & tabs using the PowerShell command Invoke-RestMethod.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now