INFO: Calling CRT Output Routines from a GUI Application (105305)
The information in this article applies to:
- Microsoft Win32 Application Programming Interface (API), when used with:
- the operating system: Microsoft Windows NT 3.1
- the operating system: Microsoft Windows NT 3.5
- the operating system: Microsoft Windows NT 3.51
- the operating system: Microsoft Windows NT 4.0
- the operating system: Microsoft Windows 95
- the operating system: Microsoft Windows 98
- the operating system: Microsoft Windows 2000
- the operating system: Microsoft Windows Millennium Edition
- the operating system: Microsoft Windows XP
This article was previously published under Q105305 SUMMARY
To use C Run-time output routines, such as printf(), from a GUI
application, it is necessary to create a console. The Win32 application
programming interface (API) AllocConsole() creates the console. The CRT
routine setvbuf() removes buffering so that output is visible immediately.
This method works if the GUI application is run from the command line or
from File Manager. However, this method does not work if the application is
started from the Program Manager or via the "start" command. The following
code shows how to work around this problem:
int hCrt;
FILE *hf;
AllocConsole();
hCrt = _open_osfhandle(
(long) GetStdHandle(STD_OUTPUT_HANDLE),
_O_TEXT
);
hf = _fdopen( hCrt, "w" );
*stdout = *hf;
i = setvbuf( stdout, NULL, _IONBF, 0 );
This code opens up a new low-level CRT handle to the correct console output
handle, associates a new stream with that low-level handle, and replaces
stdout with that new stream. This process takes care of functions that use
stdout, such as printf(), puts(), and so forth. Use the same procedure for
stdin and stderr.
Note that this code does not correct problems with handles 0, 1, and 2. In
fact, due to other complications, it is not possible to correct this, and
therefore it is necessary to use stream I/O instead of low-level I/O.
MORE INFORMATION
When a GUI application is started with the "start" command, the three
standard OS handles STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, and
STD_ERROR_HANDLE are all "zeroed out" by the console initialization
routines. These three handles are replaced by valid values when the GUI
application calls AllocConsole(). Therefore, once this is done, calling
GetStdHandle() will always return valid handle values. The problem is that
the CRT has already completed initialization before your application gets a
chance to call AllocConsole(); the three low I/O handles 0, 1, and 2 have
already been set up to use the original zeroed out OS handles, so all CRT
I/O is sent to invalid OS handles and CRT output does not appear in the
console. Use the workaround described above to eliminate this problem.
In the case of starting the GUI application from the command line without
the "start" command, the standard OS handles are NOT correctly zeroed out,
but are incorrectly inherited from CMD.EXE. When the application's CRT
initializes, the three low I/O handles 0, 1, and 2 are initialized to use
the three handle numbers that the application inherits from CMD.EXE. When
the application calls AllocConsole(), the console initialization routines
attempt to replace what the console initialization believes to be invalid
standard OS handle values with valid handle values from the new console. By
coincidence, because the console initialization routines tend to give out
the same three values for the standard OS handles, the console
initilization will replace the standard OS handle values with the same
values that were there before--the ones inherited from CMD.EXE. Therefore,
CRT I/O works in this case.
It is important to realize that the ability to use CRT routines from a GUI
application run from the command line was not by design so this may not
work in future versions of Windows NT or Windows. In a future version, you
may need the workaround not just for applications started on the command
line with "start <application name>", but also for applications started on
the command line with "application name".
Modification Type: | Minor | Last Reviewed: | 9/27/2004 |
---|
Keywords: | kbConsole kbinfo kbKernBase KB105305 |
---|
|