Click here to Skip to main content
Click here to Skip to main content
Go to top

Deriving your own stream from the iostreams framework

, 24 Jul 2002
Rate this:
Please Sign up or sign in to vote.
An exploration of extending the iostreams framework through custom streams.
<!-- Download Links --> <!-- Add the rest of your HTML here -->

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

Share

About the Author

Christian Graus
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. Pinmembershestero222-Dec-03 4:51 
GeneralEditBufStr::xsputn(...) error PinmemberVladimir Klimov30-Aug-03 10:20 
GeneralSugestion PinmemberDaniel Turini25-Jul-02 4:58 
GeneralRe: Sugestion PinmemberTim Smith25-Jul-02 10:21 
GeneralRe: Sugestion PinmemberChristian Graus25-Jul-02 11:58 
GeneralRe: Sugestion PinmemberStuart Dootson25-Jul-02 14:16 
GeneralRe: Sugestion PinmemberChristian Graus25-Jul-02 14:19 
GeneralRe: Sugestion PinsussLi Lirong25-Jul-02 16:46 
GeneralRe: Sugestion PinmemberChristian Graus25-Jul-02 17:18 
GeneralRe: Sugestion PinmemberLi Lirong25-Jul-02 17:39 
GeneralRe: Sugestion PinmemberChristian Graus25-Jul-02 17:45 
GeneralRe: Sugestion PinmemberIanMold1-May-03 0:28 
GeneralRe: Sugestion PinmemberJoaquín M López Muñoz29-Jul-02 9:16 
GeneralRe: Sugestion PinmemberStuart Dootson30-Jul-02 9:04 
GeneralRe: Sugestion PinmemberJoaquín M López Muñoz30-Jul-02 9:16 
GeneralRe: Sugestion PinmemberStuart Dootson30-Jul-02 10:14 
GeneralRe: Sugestion PinmemberChristian Graus1-Aug-02 19:50 
GeneralRe: Sugestion PinmemberChristian Graus30-Jul-02 12:32 
GeneralRe: Sugestion PinmemberJames Hopkin11-Nov-02 6:53 

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.

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