🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.nativeapi
Article #7950

Re: Console Window for GUI application

#7950
From: Richard Ulrich
Date: Thu, 09 Dec 2004 10:51
191 lines
6982 bytes
Hi bob,

thanks for the hints.
If I understand right, you use special functions to output something to 
your console window.
If I were writing a new application, that would be ok for me. But I 
don't want to go through the whole code and replace all cout and the 
like with special functions or streams. I don't want to alter the 
implementation files, not even with #defines to let cout be something 
different.

Since I found the code more or less the same on different sites in the 
internet, I assume it runs, at least with other compilers.

I included some of your suggestions and spent some time debugging:

DebugConsole::DebugConsole(unsigned short bufwid, unsigned short bufheig)
{
     int ret, hConHandle;
     intptr_t pStdHandle;
     FILE* pFile;
     char tmp[512];

	m_exists = ::AllocConsole() != 0;
	if(!m_exists)
     {
         FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 
0, tmp, sizeof(tmp)-1, NULL);
         MessageBox(GetActiveWindow(), tmp, "Couldn't create debug 
console!", MB_OK | MB_ICONERROR);
         return;
     }

	//sync stdin, stdout, stderr fds up with the new console
	//original source: http://www.halcyon.com/ast/dload/guicon.htm
	//changes: removed all warnings by changing types and casting

	// set the screen buffer to be big enough to let us scroll text

	CONSOLE_SCREEN_BUFFER_INFO coninfo;
	::GetConsoleScreenBufferInfo(::GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
	coninfo.dwSize.X = bufwid;
	coninfo.dwSize.Y = bufheig;
	::SetConsoleScreenBufferSize(::GetStdHandle(STD_OUTPUT_HANDLE), 
coninfo.dwSize);

	// redirect unbuffered STDOUT to the console
	pStdHandle = reinterpret_cast<intptr_t>(::GetStdHandle(STD_OUTPUT_HANDLE));
     SetConsoleMode(stdout,ENABLE_PROCESSED_OUTPUT | 
ENABLE_WRAP_AT_EOL_OUTPUT);
	hConHandle = _open_osfhandle(pStdHandle, O_TEXT);
	pFile = _fdopen(hConHandle, "w");
	*stdout = *pFile;
	ret = setvbuf(stdout, NULL, _IONBF, 0);
     if(ret)
     {
         FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 
0, tmp, sizeof(tmp)-1, NULL);
         MessageBox(GetActiveWindow(), tmp, "Could not set up debug 
console window.", MB_OK | MB_ICONERROR);
     }

/* not using stdin and stder for the time being
	// redirect unbuffered STDIN to the console
	pStdHandle = reinterpret_cast<intptr_t>(::GetStdHandle(STD_INPUT_HANDLE));
	hConHandle = _open_osfhandle(pStdHandle, _O_TEXT);
	pFile = _fdopen(hConHandle, "r");
	*stdin = *pFile;
	ret = setvbuf(stdin, NULL, _IONBF, 0);

	// redirect unbuffered STDERR to the console
	pStdHandle = reinterpret_cast<intptr_t>(::GetStdHandle(STD_ERROR_HANDLE));
	hConHandle = _open_osfhandle(pStdHandle, _O_TEXT);
	pFile = _fdopen(hConHandle, "w");
	*stderr = *pFile;
	ret = setvbuf(stderr, NULL, _IONBF, 0);
*/

	// make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
	// point to console as well
	ios::sync_with_stdio(true);
     ret = ret;
}

pStdHandle = 7
hConHandle = 3
pFile      = :325A725C
ret        = -1
tmp        = "The handle is invalid."



Bob Gonder wrote:
> Richard Ulrich wrote:
> 
> 
>>I recently converted a commandline application to a GUI application.
>>Now it would be nice to display all the cout's in a commandline window 
>>for debugging purposes.
>>
>>It opens that commandline window, and I don't get any errormessages, but 
>>it doesnt' print out any of the cout's. Also printf doesn't write to 
>>that commandline window.
>>
>>Any hints?
>>Richard
>>
>>And here's the code:
>>
>>class DebugConsole
>>{
>>    public:
>>        DebugConsole();
>>        ~DebugConsole();
>>
>>    private:
>>        bool	m_exists;
>>};
> 
> 
> One wonders why your DebugConsole class doesn't have display
> functions?
> 
> 	DebugConsole Console = new DebugConsole(80,500);
> 	Console.Print("Error#123\n\r");
> 	Console<<"Error#"<<123<<endl;
> 
> 
>>DebugConsole::DebugConsole()
>>{
>>    int ret;
>>	m_exists = ::AllocConsole() != 0;
> 
> 
> 	Change m_exists to BOOL, then you can do
> 	m_exists = ::AllocConsole();
> 
> 
>>	if(!m_exists)
>>		::MessageBox(0, "Couldn't create debug console!", "Error", 
>>MB_ICONERROR | MB_OK);
> 
> 
> 	You don't exit on error
> 
> 
>>	CONSOLE_SCREEN_BUFFER_INFO coninfo;
>>	::GetConsoleScreenBufferInfo(::GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
>>	coninfo.dwSize.Y = 500;
>>	::SetConsoleScreenBufferSize(::GetStdHandle(STD_OUTPUT_HANDLE), 
>>coninfo.dwSize);
>>
>>	// redirect unbuffered STDOUT to the console
>>	intptr_t	pStdHandle = 
>>reinterpret_cast<intptr_t>(::GetStdHandle(STD_OUTPUT_HANDLE));
>>	int			hConHandle = _open_osfhandle(pStdHandle, _O_TEXT);
>>	FILE* pFile = _fdopen(hConHandle, "w");
>>	*stdout = *pFile;
>>	ret = setvbuf(stdout, NULL, _IONBF, 0);
> 
> 
> I don't think that's right (but I could be wrong)
> Here's what I do in a pure console app (but then, I don't use cout,
> printf, etc because I want total control):
> 
> /*	Global values	*/
> HANDLE	stdout = INVALID_HANDLE_VALUE;
> 
> /*	Startup		*/
> 	stdout=GetStdHandle(STD_OUTPUT_HANDLE);
> 	SetConsoleMode(stdout,ENABLE_PROCESSED_OUTPUT);
> 	GetConsoleScreenBufferInfo( stdout, &sbi );
> 	sbi.dwSize.Y = 500;	/* just for you */
> 	SetConsoleScreenBufferSize(stdout, sbi.dwSize);
> 
> /*	Usage		*/
> 	WriteFile( stdout,cstring,length,&byteswritten,NULL);
> 
> You can wrap that any way you want. I wrote a cputs() that massages
> the data before passing it on. You could write a string stream
> interface that masages stream data into output strings.
> 
> 
> 
>>	// redirect unbuffered STDIN to the console
> 
> 
> Why bother with stdin or stderr for a debug console?
> All input should be through the GUI, no?
> 
> 
Technical Details
Message-ID: <41b82e09@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!newsfeed2.dallas1.level3.net!news.level3.com!bloom-beacon.mit.edu!npeer.de.kpn-eurorings.net!border2.nntp.ams.giganews.com!nntp.giganews.com!pe2.news.blueyonder.co.uk!blueyonder!news-peer-test!btnet!newsfeed.bt.es!caladan.landsraad.net!newsgroups.borland.com!not-for-mail
References: <41b5d8dc@newsgroups.borland.com> <j6vbr0djl2alcs374q8q9su4vd6u88liqb@4ax.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: 10cc67,29bc3d9d57e77864
X-Google-Attributes: gid10cc67,public
X-Google-Language: ENGLISH,ASCII-7-bit
Date: Thu, 09 Dec 2004 11:51:17 +0100
From: Richard Ulrich <ulrich_tcginf@bluewin.ch>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax)
X-Accept-Language: en-us, en
MIME-Version: 1.0
Newsgroups: borland.public.cppbuilder.nativeapi
Subject: Re: Console Window for GUI application
References: <41b5d8dc@newsgroups.borland.com> <j6vbr0djl2alcs374q8q9su4vd6u88liqb@4ax.com>
In-Reply-To: <j6vbr0djl2alcs374q8q9su4vd6u88liqb@4ax.com>
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
NNTP-Posting-Host: 212.4.80.215
Message-ID: <41b82e09@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1102589449 212.4.80.215 (9 Dec 2004 02:50:49 -0800)
Lines: 192
Path: arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!newsfeed2.dallas1.level3.net!news.level3.com!bloom-beacon.mit.edu!npeer.de.kpn-eurorings.net!border2.nntp.ams.giganews.com!nntp.giganews.com!pe2.news.blueyonder.co.uk!blueyonder!news-peer-test!btnet!newsfeed.bt.es!caladan.landsraad.net!newsgroups.borland.com!not-for-mail