Solved

Urgent!! compound file

Posted on 2000-04-07
8
336 Views
Last Modified: 2011-09-20
Hi!

Would you please help me how to combine a few kinds of file:1.bmp 1.wav to a compound file ,I need to create two storage and each for bmp ,the other for .wav and then save files into storage accordingly.

I think I need to use StgCreatXXX() some like that but I dont know how indeed to implement in code,plz help me.

the files are under c:\\ ,using windows and please no MFC , would you please give me a sample?

Thanks a lot!!
 
0
Comment
Question by:bidr
  • 3
  • 3
  • 2
8 Comments
 
LVL 1

Expert Comment

by:ntdragon
ID: 2695883
i didn't understand what exectlly do you want to do with those files

but for working with files you have the fstream class it will do all the work with files that you need

if i didn't understood your problem explain it to me
0
 

Author Comment

by:bidr
ID: 2696068
I need to put all this files into a single compound file under seperate storages.
so,i need to create a compound file with two storage and each contain some files.
0
 
LVL 1

Expert Comment

by:ntdragon
ID: 2696260
maybe i still didn't get it but i don't see your problem

take the fstream class open your two files read them into your prog
then create a theard file write the size in bytes of the BMP them write the bmp data itself then the same with WAV

you can use it for any files to stick them together

you should each time to write to the file the name of the file<them bmp>then
the size in bytes<of the bmp>
and then the same for all the next files you want to add
0
Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

 
LVL 4

Expert Comment

by:wylliker
ID: 2696499
ntdragon,

bidr is using Microsoft's COM Compound Files.


bidr,

You need to do something like this ...
(Don't copy this verbatim - off the top of my head)

Keep in mind the a Compound File is a File System within a single file - so I am using the familiar metaphor of Folders (think of them as subdirectories) for your storages.  Root would be similar to the root directory of a drive.

IStorage * Root;
IStorage * WAVFolder;
IStorage * BMPFolder;
IStream * WAVStream;
IStream * BMPStream;

// Open the compound file

StgOpenStorage(FileName, NULL, STGM_READ_WRITE | STGM_SHARE_DENY_WRITE | STGM_DIRECT, NULL, 0, &Root);

// Create the "folders" for WAVs and BMPs
Root->CreateStorage(WAVStorageName,STGM_CREATE | STGM_DIRECT,0, 0, &WAVFolder);

Root->CreateStorage(BMPStorageName,STGM_CREATE | STGM_DIRECT,0, 0, &BMPFolder);

// put BMPs and WAVs in the folders

// For each WAV file
WAVFolder->CreateStream(WAVFileName,STGM_CREATE | STGM_DIRECT,0,0, &WAVStream);

// to write to the stream

fp = fopen(WAVFileName, "rb");
while(!feof(fp))
{
   BytesRead = fread(Buffer, 1, BUFFER_LEN, fp);
   if(BytesRead)
     WAVStream->Write(Buffer, BytesRead, &BytesWritten);
}
fclose(fp)

// close the stream
WAVStream->Release();

// close the "folder"
WAVFolder->Release();

// For each BMP file
BMPFolder->CreateStream(BMPFileName,STGM_CREATE | STGM_DIRECT,0,0, &BMPStream);

// write to stream

fp = fopen(BMPFileName, "rb");
while(!feof(fp))
{
   BytesRead = fread(Buffer, 1, BUFFER_LEN, fp);
   if(BytesRead)
     BMPStream->Write(Buffer, BytesRead, &BytesWritten);
}
fclose(fp)

// Close the stream
BMPStream->Release();

// close the "folder"
BMPFolder->Release();

// Close the compound file
Root->Release();



I had used C file reading in the above use whatever method you prefer - the idea with streams is that when writing them you need to pass a Buffer, it's length and a variable for the IStream to return how many bytes were actually written.

Here is the IStream::Write function from the Docs

HRESULT Write(
  void const* pv,  //Address of buffer from which stream is written
  ULONG cb,        //Specifies the number of bytes to write
  ULONG * pcbWritten
                   //Specifies the actual number of bytes written
);
 

You will have to add error checking, etc.

Also note that I used DIRECT instead of TRANSACT - if you need the compound file to be transactional then it gets a little more involved.

One more thing - calling Release() on a Storage or Stream closes it.



A suggestion ...

Get Inside OLE2 by Kraig Brockschmidt.
He has a full section devoted to Compound Files .



0
 

Author Comment

by:bidr
ID: 2697532
Thank!!

1:would you tell me how to specify storage and stream name ?
I use "somename" but it 's wrong.

2:Would you plz tell me how to translate to c++ ?
fp = fopen(BMPFileName, "rb");
while(!feof(fp))
{
   BytesRead = fread(Buffer, 1, BUFFER_LEN, fp);
   if(BytesRead)
     BMPStream->Write(Buffer, BytesRead, &BytesWritten);
}
fclose(fp)

I will give you more points later after I do excercise ,thank you very much!!!!
0
 
LVL 4

Accepted Solution

by:
wylliker earned 57 total points
ID: 2697611
You can use the actual file name as the name of each of the streams or you can give it a friendlier name, if it is going to be displayed back to a user at some point.  For the storages just use a "good" name.

The name part of storages and streams are just character strings - again no different than what you have in long file names in windows.  Just like a file system.  If you only keep one kind of file in the streams under a specific storage you wouldn't need to have an extension or some other identifier to tell you what it was.

For example:

WAVFolderName = "WAVs";

if you were putting in a WAV called hohoho.wav you could ...

WAVStreamName = "hohoho.wav";

or maybe ...

WAVStreamName = "Santa Claus";


BMPFolderName = "BMPs";

if you were putting in a BMP called warhol15.bmp you could ...

BMPStreamName = "warhol15.bmp";

or maybe ...

BMPStreamName = "Campbell Soup Can";


Again, a compound file is a file system within a single file. An anology is windows explorer - the left hand pane contains the storages and the right hand pane has the streams within those storages.

As for the C++ file I/O ...

You can use the functions I mentioned above without any problem.  However, if you want to use pure c++ you would have to get some help from one of the other experts as I don't do much file I/O work using pure c++.

At the MSDN site on microsoft ...

http://msdn.microsoft.com/library/

.... you might have to register but it is free

You can find Brockschmidt's book - Inside OLE

When the tree (TOC) comes up on the left click on the + next to Books then click on the + next to Inside OLE then click on the + next to Chapter 7 Structured Storage and Compound Files.

Do some reading.  There is sample code available that shows you how to use Compound Files.

Take a look!

















0
 

Author Comment

by:bidr
ID: 2697847
Thanks
0
 
LVL 4

Expert Comment

by:wylliker
ID: 2698116
If you need any more help with this, you can keep posting back as a comment or open a new question.

If I had more time I could have gotten more involved with this - and given you more useful ready to use code.

(Have a system going to production the end of this week - and it seems as though the system is coming un-glued!)

You probably just have to get this task done, but long ago (1993 or so) when I first had worked with Structured Storage I really liked the concept - there were (are) just so many opportunities with the design of it.

Oh well, best of luck with your efforts!
0

Featured Post

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

776 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question