Click here to Skip to main content
15,881,413 members
Articles / Programming Languages / C++
Article

Deriving your own stream from the iostreams framework

Rate me:
Please Sign up or sign in to vote.
3.80/5 (7 votes)
24 Jul 20023 min read 90.9K   987   20   19
An exploration of extending the iostreams framework through custom streams.

Introduction

This is the third in my trilogy of articles on iostreams. Having covered how to create inserters, extractors and modifiers, it follows that I should explain how to write a stream. I am going to provide two classes, one of which overrides basic_streambuf, and provides the streaming implementation and one which derives from ostream in order to provide us with a stream to pass information to our underlying code.

The idea

The basic idea for this article came about because someone asked a question in the C++ forum, regarding redirecting printf to an edit box. So the task at hand will be to create a stream which appends the stream input to the text of an edit box.

MFC ?

The article code takes the form of an MFC dialog project, but the actual stream does not use MFC. You can copy the header file into any Win32 project, and it should work just as well. I suspect it should work for WTL as well, but I have not tested this at ALL, OK ?

Point of entry

Because we are deriving from an iostream class, we need to override specific functions in order for our code to integrate into the library. We have three options. A stream operation can look something like this:

cout << "this is some text " << 42 << InstanceOfSomeOtherType;

In this example, the possible places for cout to handle the input are as follows:

FunctionWhere called
overflowGets called once for each character passed into the stream
flushgets called when a flush occurs, usually via endl or a destructor
xsputnGets called once per shift operator

So we see we have three options.

  1. pass each character into the edit box when overflow is called
  2. store each character when overflow is called and pass it in one go in flush
  3. pass each string or other object one at a time in xsputn

Option 1 should be used only by streams with low overhead in performing their functionality. Option 2 is best for costly operations. Option 3 is about as easy as option 1, and more efficient. We will pursue option 3.

The stream

Basically our approach inside our function is to call GetWindowTextLength to get the length of the text in the window, and GetWindowText to get the string, then we concatenate it with the one we already have, and use (surprise) SetWindowText to put it back in.

In order to do all this, we need the HWND of the edit box, so we provide a function in both stream objects that takes a HWND and returns the one previously stored. If it has not been set, our stream does nothing.

The code looks like this:

std::streamsize xsputn(const charT * pChar, std::streamsize n)
{
    if (NULL != m_hWnd)
    {
        const int nLength = ::GetWindowTextLength(m_hWnd) + 1;
        char * pText = new char [nLength];
        ::memset(pText, 0, nLength);
        ::GetWindowText(m_hWnd, pText, nLength);

        std::string s(pText);
        delete [] pText;

        s += std::string(pChar);

        ::SetWindowText(m_hWnd, s.c_str());

        return static_cast<std::streamsize>(s.length());
    }
    else
        return 0;
}

Now we just need to initialise our stream with the HWND of the edit box, and call our stream with the text we want to pass in. The demo program provides a disabled edit box that shows the text already received, and an enabled one, whose contents is streamed in when you press the button provided.

If you're the person I wrote this for, I hope it helps you. Either way, I hope it provides you with some more ideas as to ways that iostreams can be used to make your life easier with regard to input and output. It is an awesome library in my opinion, and one that seems to me to be under utilised by a lot of people. I hope you find it useful to you.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
Australia Australia
Programming computers ( self taught ) since about 1984 when I bought my first Apple ][. Was working on a GUI library to interface Win32 to Python, and writing graphics filters in my spare time, and then building n-tiered apps using asp, atl and asp.net in my job at Dytech. After 4 years there, I've started working from home, at first for Code Project and now for a vet telemedicine company. I owned part of a company that sells client education software in the vet market, but we sold that and I worked for the owners for five years before leaving to get away from the travel, and spend more time with my family. I now work for a company here in Hobart, doing all sorts of Microsoft based stuff in C++ and C#, with a lot of T-SQL in the mix.

Comments and Discussions

 
QuestionCan I use MT-safe stream as a pipe between two threads? A TANGLED question about standart C++-library. Pin
shestero222-Dec-03 4:51
shestero222-Dec-03 4:51 
GeneralEditBufStr::xsputn(...) error Pin
Vladimir Klimov30-Aug-03 10:20
Vladimir Klimov30-Aug-03 10:20 
GeneralSugestion Pin
Daniel Turini25-Jul-02 4:58
Daniel Turini25-Jul-02 4:58 
GeneralRe: Sugestion Pin
Tim Smith25-Jul-02 10:21
Tim Smith25-Jul-02 10:21 
GeneralRe: Sugestion Pin
Christian Graus25-Jul-02 11:58
protectorChristian Graus25-Jul-02 11:58 
GeneralRe: Sugestion Pin
Stuart Dootson25-Jul-02 14:16
professionalStuart Dootson25-Jul-02 14:16 
GeneralRe: Sugestion Pin
Christian Graus25-Jul-02 14:19
protectorChristian Graus25-Jul-02 14:19 
GeneralRe: Sugestion Pin
Li Lirong25-Jul-02 16:46
Li Lirong25-Jul-02 16:46 
GeneralRe: Sugestion Pin
Christian Graus25-Jul-02 17:18
protectorChristian Graus25-Jul-02 17:18 
GeneralRe: Sugestion Pin
Li Lirong25-Jul-02 17:39
Li Lirong25-Jul-02 17:39 
GeneralRe: Sugestion Pin
Christian Graus25-Jul-02 17:45
protectorChristian Graus25-Jul-02 17:45 
GeneralRe: Sugestion Pin
IanMold1-May-03 0:28
IanMold1-May-03 0:28 
GeneralRe: Sugestion Pin
Joaquín M López Muñoz29-Jul-02 9:16
Joaquín M López Muñoz29-Jul-02 9:16 
GeneralRe: Sugestion Pin
Stuart Dootson30-Jul-02 9:04
professionalStuart Dootson30-Jul-02 9:04 
GeneralRe: Sugestion Pin
Joaquín M López Muñoz30-Jul-02 9:16
Joaquín M López Muñoz30-Jul-02 9:16 
GeneralRe: Sugestion Pin
Stuart Dootson30-Jul-02 10:14
professionalStuart Dootson30-Jul-02 10:14 
GeneralRe: Sugestion Pin
Christian Graus1-Aug-02 19:50
protectorChristian Graus1-Aug-02 19:50 
GeneralRe: Sugestion Pin
Christian Graus30-Jul-02 12:32
protectorChristian Graus30-Jul-02 12:32 
GeneralRe: Sugestion Pin
James Hopkin11-Nov-02 6:53
James Hopkin11-Nov-02 6:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.