Let's look at a more complicated example of how you might use class RWDDEstreambuf to exchange an RWBinaryTree through the Windows DDE facility. You would use a similar technique for the Windows Clipboard.
#include <rw/bintree.h> #include <rw/collstr.h> #include <rw/bstream.h> #include <rw/winstrea.h> #include <windows.h> #include <dde.h> BOOL PostCollection(HWND hwndServer, WORD cFormat){ RWBinaryTree sc; // 1 sc.insert(new RWCollectableString("Mary")); sc.insert(new RWCollectableString("Bill")); sc.insert(new RWCollectableString("Pierre")); // Allocate an RWDDEstreambuf and use it to initialize // an RWbostream: RWDDEstreambuf* sbuf = new RWDDEstreambuf(cFormat, // 2 FALSE, // 3 TRUE, // 4 TRUE); // 5 RWbostream bostr( sbuf ); // 6 // Store the collection to the RWbostream: bostr << sc; // 7 // Lock the output stream, and get its handle: HANDLE hDDEData = sbuf->str(); // 8 // Get an atom to identify the DDE Message: ATOM atom = GlobalAddAtom("SortedNames"); // 9 // Post the DDE response: return PostMessage(0xFFFF, WM_DDE_DATA, hwndServer, //10 MAKELONG(hDDEData, atom)); }
In the code above, the large memory model has been assumed. Here's the line-by-line description:
//1 | An RWBinaryTree is built and some items inserted into it. |
//2-//5 |
An RWDDEstreambuf is allocated. The constructor takes several arguments. The first argument is the Windows Clipboard format. In this example, the format type has been passed in as an argument, but in general, you will probably want to register a format with Windows (using RegisterClipboardFormat()) and use that.
The other arguments have to do with the intricacies of DDE data exchange acknowledgments and memory management. See the Class Reference for the list of arguments; for their meanings, see Petzold (1990), Chapter 17, or the Microsoft Windows Guide to Programming. |
//6 | An RWbostream is constructed from the supplied RWDDEstreambuf. We could have used an RWpostream here, but DDE exchanges are done within the same machine architecture so, presumably, it is not worth the extra overhead of using the portable ASCII formats. Nevertheless, note how the disposition of the bytes, which is set by the type of streambuf, is cleanly separated from their formatting, which is set by the type of RWvostream. |
//7 | The collection is saved to the RWbostream. Because the streambuf associated with RWbostream is actually an RWDDEstreambuf, the collection is actually being saved to a Windows global memory allocation with characteristic GMEM_DDESHARE. This allocation is resized automatically if it overflows. Like any other strstreambuf, you can change the size of the allocation chunks using member function setbuf(). |
//8 | The RWDDEstreambuf is locked. Once locked using str(), this streambuf, like any other strstreambuf, cannot be used again. Note, however, that RWDDEstreambuf::str() returns a handle, rather than a char*. The handle is unlocked before returning it. |
//9 | An atom is constructed to identify this DDE data. |
//10 | The handle returned by RWDDEstreambuf::str(), along with its identifying atom, is posted. |
A similar and actually simpler technique can be used for Clipboard exchanges.
Note that there is nothing that constrains you to use the specialized streambufs RWCLIPstreambuf and RWDDEstreambuf with only the Rogue Wave virtual streams facility. You could quite easily use them with regular istreams and ostreams; you just wouldn't be able to set the formatting at run time.