Basics: First steps
The problem
...is you want to save miscellaneous data types into one single file, no matter if TStrings, TBitmap, a wave file, the contents of a TreeView or even any other file or data. Let us take a look to Delphi:
Nearly every component in the VCL or every data kind allows you to save its contents in two different ways: SaveToFile() and SaveToStream() and vice versa. Well, saving the data to a file is nice for temporary files, but you most probably know this fact, mean saving data into files. But what we want is to create a single file containing all data. Thus it is interesting to take a look on TStream and its descendands, such as THandleStream, TFileStream, TMemoryStream etc.
Streams
Probably you might ask: "What the hell is a stream?". Good question, simple answer: any data is written as an array of bytes, also known as a buffer. So, basically, the contents of a bitmap consist of the same type as e.g. the familiar string - a simple gathering of characters. Now, what is a stream? It is a symbolic container for such a single buffer. Let me explain this taking TFileStream and TMemoryStream at hand.
TFileStream
Although all kinds of streams are handled the same way, their class defines what the stream is. TFileStream for example is an object representing a file located an the hard drive. While manipulating the stream (the buffer in it), you in fact directly manipulate the file. So this is similar to the well-known AssignFile(), Read() and Write() functions from Turbo Pascal and Delphi. You opened a file vie AssignFile and manipulated the characters in it vie reading and writing strings etc., as TFileStream does also.
TMemoryStream
TMemoryStream, as already said, is works with the same functions, but represents a buffer located in RAM of your machine. So when having a memorystream, initially you have nothing, you must fill it with contents. You can do it with calling the LoadFromFile() function, saving other component's data with SaveToStream() or simply use Read() or Write(). The advantage of TMemoryStream is, that you do not have to use (temporary) files - a memorystream represents data in the memory of the computer, and if nessesarry, parts of the swapping. Thus it may be that when you are manipulating a memorystream, you are handling a file in fact, the paging file of Windows.
Finally, why streams?
The reason why I am telling you a bit about streams is that they are the perfect thing we need to accomplish our goal, to create single files with multiple data. Each stream is an independent object beeing constructed and freed, it can store any kind of data, you can simply query its size and nearly every components offers an interface to save to such a stream. How we can use the stream, see the next site...