Article View: borland.public.cppbuilder.nativeapi
Article #7950Re: Console Window for GUI application
From: Richard Ulrich
Date: Thu, 09 Dec 2004 10:51
Date: Thu, 09 Dec 2004 10:51
191 lines
6982 bytes
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-mailReferences:
<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