Click here to Skip to main content
Licence 
First Posted 24 Jul 2002
Views 71,069
Bookmarked 18 times

Deriving your own stream from the iostreams framework

By | 24 Jul 2002 | Article
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

About the Author

Christian Graus

Software Developer (Senior)

Australia Australia

Member

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 now I work for the new owners.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionCan I use MT-safe stream as a pipe between two threads? A TANGLED question about standart C++-library. Pinmembershestero24:51 22 Dec '03  
GeneralEditBufStr::xsputn(...) error PinmemberVladimir Klimov10:20 30 Aug '03  
GeneralSugestion PinmemberDaniel Turini4:58 25 Jul '02  
GeneralRe: Sugestion PinmemberTim Smith10:21 25 Jul '02  
GeneralRe: Sugestion PinmemberChristian Graus11:58 25 Jul '02  
GeneralRe: Sugestion PinmemberStuart Dootson14:16 25 Jul '02  
GeneralRe: Sugestion PinmemberChristian Graus14:19 25 Jul '02  
GeneralRe: Sugestion PinsussLi Lirong16:46 25 Jul '02  
GeneralRe: Sugestion PinmemberChristian Graus17:18 25 Jul '02  
GeneralRe: Sugestion PinmemberLi Lirong17:39 25 Jul '02  
GeneralRe: Sugestion PinmemberChristian Graus17:45 25 Jul '02  
GeneralRe: Sugestion PinmemberIanMold0:28 1 May '03  
GeneralRe: Sugestion PinmemberJoaquín M López Muñoz9:16 29 Jul '02  
GeneralRe: Sugestion PinmemberStuart Dootson9:04 30 Jul '02  
GeneralRe: Sugestion PinmemberJoaquín M López Muñoz9:16 30 Jul '02  
GeneralRe: Sugestion PinmemberStuart Dootson10:14 30 Jul '02  
GeneralRe: Sugestion PinmemberChristian Graus19:50 1 Aug '02  
GeneralRe: Sugestion PinmemberChristian Graus12:32 30 Jul '02  
GeneralRe: Sugestion PinmemberJames Hopkin6:53 11 Nov '02  

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

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

Permalink | Advertise | Privacy | Mobile
Web04 | 2.5.120517.1 | Last Updated 25 Jul 2002
Article Copyright 2002 by Christian Graus
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid