Program descr: Im trying to make a windows manager for windows I might draw in CONSOLE.

the plan is to draw manually windows in the console in an objectified way.
instead of drawing the windows using console coordinates I create a buffer then use writeConsoleOutput to write this buffer to the console. I have the following code which have this detail I dont understand. Im testing the code trying to output a grid of #'s (the symbol) but the output is the intended grid BUT with top left coordinate black (i.e coord 0,0 of the grid)

I suspect the vector class as the culprit, simply because if I call drawWin() at the end of win ctr ( after filling the buffer) the grid shows fines, maybe a vector is not adecuate for this case, if so I like to know why is giving this trouble, that is, if vector is indeed the trouble maker.

#define _WIN32_WINNT 0x0501
#include <windows.h>
#include <iostream>
#include <vector>

using namespace std;

//A 1-1 mapping from cells ti array

enum winStyle
{
	warningsON, warningsOFF 
};

const WORD Black = 0x0000;
const WORD fWhite = 0x0001 | 0x0002 | 0x0004;
const WORD bWhite = 0x0010 | 0x0020 | 0x0040;

class CUIelement
{};

class win
{
	public:
		win(COORD org , COORD size, winStyle ws);
		~win();
		void addElement(CUIelement x){}
		const CHAR_INFO * getBuffer(); 
		void drawWin(HANDLE hOut);
		winStyle getWinStyle();
	private:
		CHAR_INFO * _buffer;
		COORD _org;	
		COORD _size;
		winStyle _ws; 
};

 HANDLE HOUT = GetStdHandle(STD_OUTPUT_HANDLE);
 
win::win(COORD org ,COORD size, winStyle ws): _org(org), _size(size),_ws(ws) 
{
	
	_buffer = new CHAR_INFO[size.X * size.Y];
	 for (int y = 0; y < size.Y ; ++y) {
        for (int x = 0; x < size.X; ++x) {
            _buffer[x+size.X*y].Char.AsciiChar = 0x23;
            _buffer[x+size.X*y].Attributes = fWhite;
           }	
	}	
}

win::~win()
{ 
	delete[] _buffer ; 
}

winStyle win::getWinStyle(){	return _ws; }

void win::drawWin(HANDLE hOut)
{
		COORD startWhereInBuffer = {0,0};
		SMALL_RECT SBregion = {_org.X, _org.Y, _org.X + _size.X - 1  , _org.Y + _size.Y - 1  };
		WriteConsoleOutput(hOut, _buffer, _size, startWhereInBuffer , &SBregion);
			 
}

class SBman
{
	public:
		SBman(	COORD _SBsize );
		void addWindow(win w);
		void drawScr();
	private:
		void setUpScr();
		vector<win> vWin;
		HANDLE _hOut ;
		COORD _SBsize;
		HWND _hWnd;
};

SBman::SBman(COORD SBsize): 	_hOut (GetStdHandle(STD_OUTPUT_HANDLE)),
																				_SBsize (SBsize), _hWnd(GetConsoleWindow())
{	
	setUpScr();
}

void SBman::addWindow(win w)
{
	vWin.push_back(w);
}

void SBman::drawScr()
{
	for(int i = 0 ; i < vWin.size() ; ++i )
	{
		//get window info	
		vWin[i].drawWin(_hOut);	
	}
}

void SBman::setUpScr()
{
	SetConsoleScreenBufferSize(_hOut,_SBsize);
	CONSOLE_SCREEN_BUFFER_INFO csbi;
	GetConsoleScreenBufferInfo(_hOut, &csbi);
	SMALL_RECT winSize = {0,0,csbi.dwMaximumWindowSize.X-1,csbi.dwMaximumWindowSize.Y-1};
	SetConsoleWindowInfo(_hOut,1,&winSize);

}

int main()
{

	//make appropiate console
	COORD size = {80,40};
	SBman sb(size);
	
	COORD wOrigin = {4,8};
//	for(int j = 5 ; j < 40 ; ++j)
//	for(int i = 5 ; i < 80 ; ++i)
	//{
		//create win
	COORD wSize = {11,5};
	win tmp(wOrigin, wSize, warningsOFF);
	sb.addWindow(tmp);
	sb.drawScr();

// }

}

Recommended Answers

All 3 Replies

Your program is trashing the stack and/or the heap somewhere. I compiled with vc++ 2010 express and it get assertion error when exiting the program.

Ok, got this figured out. You need to code a copy constructor for class win which will be called for push_back into the vector of win objects.

Whether it works the way you want it to, I don't know. But I got it to run without crashing.

class win
{
public:
    win(COORD org , COORD size, winStyle ws)
    {
       allocbuffer(org,size,ws);
    }
    win(const win& w)
    {
        allocbuffer(w._org,w._size,w._ws);
    }
    ~win();
    void addElement(CUIelement x){}
    const CHAR_INFO * getBuffer(); 
    void drawWin(HANDLE hOut);
    winStyle getWinStyle();
private:
    void allocbuffer(COORD org , COORD size, winStyle ws);
    CHAR_INFO * _buffer;
    COORD _org;	
    COORD _size;
    winStyle _ws; 
};

void win::allocbuffer(COORD org ,COORD size, winStyle ws)  
{
    _org = org;
    _size = size;
    _org = org;
    _buffer = new CHAR_INFO[size.X * size.Y];
    for (int y = 0; y < size.Y ; ++y) {
        for (int x = 0; x < size.X; ++x) {
            int offset = x+((size.X-1)*y);
            _buffer[offset].Char.AsciiChar = 0x23;
            _buffer[offset].Attributes = fWhite;
        }	
    }	
}

first, thank you for your time and expertize, its precious.
Now, I added the code you gave me to the win class, left the other code the same, Im not sure, Im assuming the copy ctor will be called in push_back, if Im wrong pls dont explain this part, I have some reference for that, then I compiled and ran the app, it draw this:

###########
###########
###########
###########
#######COE=

wich is not what im looking for (all the symbols should be #'s)
If I misuse your code, correct me, so maybe the program no longer trashes stack but the output is still wrong.

START 'philosophical' stuff.
This app was supposed to be a simple task and still for this little "detail" I lost a day, bugs can be hard punching, not knowing whats wrong you start doubting the basis, and If you doubt the basis then you have no "polar star" to navigate.

The other part is fixing code with code that you know at heart you shouldn't be coding when you cant explain whats wrong, thing I was tempted to do and in fact did, as an example changing vector<win> to vector<win * >, or removing vector altogether and using other data structure.
END 'philosophical' stuff.

IF
you read my tantrum, Id like to hear some advice, do you use "solutions" that might clutter the original design, or what else is there to do, Im expecting quick answers so maybe this doesn't get flagged off topic.

ELSE
this concerns code. previously to your answer I removed the vector altogether and used a CHAR_INFO *, adjusted the addWindow() to:

//fix#1

void SBman::addWindow(win w)
{
	_pWin = &w;
}

the rest of the code the same.. and the same error

Later I changed, the addWindow to:

//fix#2
void SBman::addWindow(win * w)
{
	_pWin = w;
}

and the main code to:

COORD wSize = {11,5};
	win * tmp = new win(wOrigin, wSize, warningsOFF);
	sb.addWindow(tmp);

the rest of the code the same, but this time the grid is painted correctly
i.e

###########
###########
###########
###########
###########

I question why.
The fix#1 code is not good, I was saving a pointer to an automatic object which is bad in itself, but even with this error I cant explain why the fix#1 code didnt work, the last code to execute in main is sb.drawScr() which will work with an auto object wich is still valid. so I don't see why the output of fix#1 and fix#2 is different.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.