This section of the archives stores flipcode's complete Developer Toolbox collection,
featuring a variety of mini-articles and source code contributions from our readers.

Message Box ostream
Submitted by

I present here a msgboxstream, a std::basic_ostream-derived
class that presents its string buffer content as a Win32 MessageBox
when invoked. The title can be set through an ostream, and the style
can be controlled through good old accessors or (for the wilfully
esoteric) via insertion manipulators.
As an exercise for myself I abstracted the actual message box
mechanism out of the class and into a template policy. Under non-win32
builds the message will be displayed upon std::cout, and input
will be gathered from std::cin (only recognises 'Y' and 'y' - all
other input is false). The cout_messagebox mechanism is merely
a minimal example of how to bake your own mechanisms - I don't
expect anyone to use it.
I realised when developing this that I could leverage a std::stringstream
into being the streambuf used by the ostream, and it certainly
saved extraneous work. However, this shortcut makes the class
less informative for those wishing to learn how to hack their
own streams. To this end I've thrown into the zip file some other
streams of mine that use custom streambufs: a teestream, a debugstream
(quite common these days - took me ages to solidify when I first
hacked it), and for kicks a nilstream (I #define debugstream into
this for release builds when debugging output is no longer required).
The file main.cpp contains example usage of the classes, and even
includes a free game requiring extreme player concentration, and
an insensitivity to violence! (ahem)
The code has been compiled and executes fine on Visual Studio 6.0
with latest service packs. It _should_ compile on non-WIN32 boxes,
but I haven't tested it - please let me know if you try it.
All comments and constructive criticism will be appreciated. I just
hope that someone finds the package educational.
Regards,
A.

// Allow client code to display the message box through an insertion.
// Personally I think "mb << msgbox::display();" is ugly and involves too
// much typing, but I've included this as an example of how to code different
// custom insertion operations.
inline helper::display display() {
return helper::display();
}

// ---------------------------------------------------------------------------
// A teestream is a stringstream that pipes its input onto zero or more
// ostreams.
// It's useful for relaying data from apis that only support a single ostream
// onto multiple streams (simultaneously). Often found loitering in the
// company of cout, cerr, logging files, and debug streams.
//
// Usage:
// anthony::teestream tee;
// tee.attach(std::cerr);
// tee.attach(logfile);
// tee.attach(new debugstream);
// tee << "Testing..." << std::endl;
// tee << std::complex(0.0f, 2.3f) << std::endl;
//
// Notes:
// The streams used by the teestream need to have a lifetime at least as
// long as the attached teestream.
//
// A stream pointer passed to a teestream will become owned by the teestream,
// and released at the teestream's time of death. This is to simplify
// the aforementioned lifetime issues via simple syntax:
// tee.attach(new consolestream);
//
// The data within the teestream is only relayed onto the attached streams
// when flushed (by inserting std::endl or std::flush, or by calling the
// flush method of the teestream).
//
// There is no capability at present to detach a stream from a teestream.
//
// A teestream without attached streams will consume all input, and thus
// function as a null_stream.
// ---------------------------------------------------------------------------
namespace anthony
{
#if 0
} // Bah fungoo to you, auto-indent.
#endif