Solved

embeddind a midi file in an exe using resource file

Posted on 2002-03-14
19
466 Views
Last Modified: 2010-04-05
Hi!
A few days ago I asked this question and recieved a reply I was given code snippets to create the res file and how to implement it but program doesn't work! When I press the button i've created I get an error msg that says cannot find the resource. here is the code i was given. can anyone help? I believe Tongalite and Reddarin responded previously.
here is the code.
THE RESOURCE FILE:
midfile RC_DATA "twelve.mid"

I have tried puttingthe name in single quote, double quotes and no quotes.
Incidently, the code I was given for playing a wav file works, but not when I replace it with the midi data.


Code attached to the button.
{$R *.DFM}
{$R midfile.res}
procedure TForm1.Button1Click(Sender: TObject);

var

fileStr:TFileStream;
restr:TResourcestream;
begin

restr := TResourceStream.Create(hInstance, 'midfile', RT_RCDATA);

fileStr := TFileStream.Create('C:\temp.mid',fmCreate or fmOpenWrite);
fileStr.CopyFrom(restr, restr.size);
fileStr.free;
restr.free;

    MediaPlayer1.filename := 'C:\temp.mid';
    MediaPlayer1.open;
    MediaPlayer1.play;

end;
Where restr is assignned the value of Tfilestream is where the program stops.
Thanks,
Paul
0
Comment
Question by:annas
  • 6
  • 5
  • 4
  • +3
19 Comments
 
LVL 6

Accepted Solution

by:
Stuart_Johnson earned 100 total points
ID: 6866223
Hi Paul,

Here's my code to do what you were doing.

My resource file looks like this:

MYMIDI MIDI "CANYON.MID"

It's called TEST.RC

Compile TEST.RC with BRCC32.EXE.



My PAS file looks like this:

implementation

{$R *.DFM}
{$R TEST.RES}

procedure TForm1.Button1Click(Sender: TObject);
var
  ResStr: TResourceStream;
begin
  ResStr := TResourceStream.Create(hInstance, 'MYMIDI','MIDI');
  try
    ResStr.SaveToFile('C:\TEST.MID');
  finally
    ResStr.Free;
  end;
  MediaPlayer1.FileName := 'C:\TEST.MID';
  MediaPlayer1.Open;
  MediaPlayer1.Play;
end;

This works fine for me.  If you want the whole project zipped so you can see it going, let me know and I'll email it too you.

Cheers,

Stu.
0
 
LVL 3

Expert Comment

by:SteveWaite
ID: 6866308
It seems to be what's being typed in the .rc file.
As in:
midfile RC_DATA "twelve.mid"

v:
MYMIDI MIDI "CANYON.MID"

midfile and MYMIDI are great, as are the data files.

The trouble is, who knows what directives to type where RC_DATA or MIDI are placed?

Please post the list of directives someone :)

Regards,
Steve




0
 
LVL 6

Expert Comment

by:Stuart_Johnson
ID: 6866378
Steve,

I have no idea what you're taking about.  Can you explain what you mean in more details?  What are these directives you're talking about?

Stu
0
 
LVL 3

Expert Comment

by:SteveWaite
ID: 6866454
Hi Stuart and Paul,

Stu, you quite correctly posted:
MYMIDI MIDI "CANYON.MID"
as the text to type into the .rc file.
whereas Paul posted:
midfile RC_DATA "twelve.mid"

The word in the middle, I suppose, describes the type of data.
You mentioned if you include a midifile then type MIDI.

I said the only difference was MIDI/RC_DATA in the .rc file.

Then wondered if you (or anyone) knew what should be used in what situation.

For example, if it's unspecified data then 24 is typed.
help with would be appreciated.

Also rather than type 'listening' I may uncover some know-how. ;-)

Steve
0
 
LVL 6

Expert Comment

by:Stuart_Johnson
ID: 6866488
Hi Steve,

OK.  That makes sense now.  I just didn't follow what you meant.

To be honest, I've never really given it much thought.  I've NEVER used RC_DATA at all (as I find it's undescriptive and too generic).  I always use an abbreviated name for the data type:

MYJPEG JPEG "IMAGE1.JPG"
MYMP3  MP3  "LOUD.MP3"
MYTEXT TEXT "TEXT.TXT"

etc


It makes it easier in code to show what we're loading.  I guess someone will say "HAY!  You're not supposed to do that!", but to date, I've never had a problem with it, and I don't expect I will.  Naming conventions are always individual - I personally like the KISS theory :)

Cheers mate.

Stu
0
 
LVL 3

Expert Comment

by:SteveWaite
ID: 6866781
Hi Stu & Paul,

So when i picked up 24=unspecified it could have said eggsandwich, it's just what we call the parts of the data in the resource.

But Paul's code didn't work for some reason.

Paul,

Instead of using the command line to create your resources, try using the Delphi IDE!

I always create a new text file and save it as <myresource>.rc and add the lines describing the data (as we have discussed).

Crucially though, add the .rc file to the project with the project menu/add to project. Then the IDE puts the line:
{$R 'myresource.res' 'myresource.rc'}

into the application unit for you.

Then the resource gets rebuilt each time you compile the program and it's just another file in the ide as well. (comes up in view/units..)

Btw. do not mess with the application resource or things go wrong.

Regards,
Steve



 
0
 
LVL 15

Expert Comment

by:simonet
ID: 6867025
Download a working application (w/ full source code) from:


Athena's Place: http://www.bhnet.com.br/~simonet/archive/resonlydll.zip


Yours,

Alex
0
 
LVL 3

Expert Comment

by:SteveWaite
ID: 6867273
I take my hat off to you, Alex.
0
 
LVL 6

Expert Comment

by:Stuart_Johnson
ID: 6867331
Alex is a walking hat stand :)

I was actually wondering how long it would take Mr Resource to sniff this one out.

How goes it, Alex?

Stu.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:annas
ID: 6867371
Thank you all very much for your input. I had tried different names for the resource, including MIDI and RC_DATA. I thought that these names were reserved words and had to be used for either midi files or (in the case of RC_DATA) untyped data. I had create the res file from the .rc file by simply dragging the rc file on top of brcc32. in windows explorer. I like Steves idea also about putting the .rc file in the source and letting the compiler rebuild it each time.

Stu, if you could email me that zipped project file you spoke of i sure would appreciate it my email is p3aul@bellsouth.net

I'm not going to sign off on the question just yet in case i have more difficulties, but again thanks very much
Paul
0
 
LVL 15

Expert Comment

by:simonet
ID: 6867666
Hello Stuart! It's been quite a while, hasn't it?
So, how are things in the opposite time zone?!

Annas,

from the source you provided, things seems to be working as it should. The few catches on using resoures are:

- you actually link the .RES file to the Delphi project, not the script (.RC). I don't about Delphi 6, but as far as I know only BCB projects allow you to link the .RC file.


- People often forget to compile the resource scripts. Don't.

- You only need to add the link to the resource binaries ONCE in the entire project. I usually add all the resources in the .DPR file (just to keep consistency).

- There cannot be 2+ resources with the same name (even if with different cases), even if they are linked from different .RES file. When this happens the Delphi compiler will choose one and dump the other, generating a compiler error message.

- You can use ANY resource type you want. The point is that all RC_xxxx are predefined resource types, and must be accessed using the RC_xxxx constants. Everything else ("custom" resource types) must be specified as pchars.

Just a silly question: do other MIDI files play correctly on your machine?

Try the project I mentioned in my last post and see if it works for you. If so, it's pretty easy to adapt the source code from it to your own project. The only changes are:
- the module where the resource is is now hInstance
- the type of the resource is the resource type you specified
- the same for the name of the resource


Yours,

Alex
0
 
LVL 3

Expert Comment

by:tongalite
ID: 6867924
Hi annas,

Here is some info I did for another question but it's relevent to your question as well.
Hope this helps.
****************************************
{ //CREATING RESOURCE FILES// 2001 by Tongalite.

             

FIRST - Create a resource folder for this and future resource files. e.g. bmps. jpeg, avi, wav. midi. etc.

The  code example used below is for loading ICONS from a RES file>>>>

 

<<<HOW TO CREATE A USEFUL RESOURCE FOLDER>>>

(1) create a new folder on desktop, name it -
    RESOURCES.

(2) Open your Delphi/Bin folder and copy these
    two files to your newly created RESOURCES
    folder :- Brcc32 and Rw32core.dll

(3) Place two icons eg :-  A.ico & B.ico into
    your RESOURCES folder

(4) Open Notepad and type the following:
  ICON_1 ICON "A.ico"
  ICON_2 ICON "B.ico"

 
[NOTE:- The first reference above, ICON_1 & ICON_2 -
is what you will use in your code to access the
resource.

Reference 2:- ICON is the file description (could be
anything)

and reference three:- "A.ico" & "B.ico" - is the actual name of the file/s you've compiled into your resource file.

Other examples you could add in rc.files could be:-

MyPic BMP "Clouds.bmp"

MyTune RCDATA "Canyon.mid"

MySound WAVE "Chimes.wav"

MyImage JPEG "MyPhoto.jpg"

etc.]


(5) Next, save text file as MyRes, this is called
    a rc.file. Place it in your RESOURCES folder

(6) You now have an rc. text file called MyRes,
    drag and drop this file on
    Brcc32.exe. [The resource compiler - Brcc32.exe
    will look in your RESOURCES folder for the
    files referenced in the rc.text file you created.
    if the files are found, a file called MyRes.RES
    will be automatically created. The name of the
    file must match exactly the description in the
    rc.text file or else nothing will happen]
(7) Open a new Delphi project drop two TImage
    containers and 2 buttons on your Form1

(8) paste the code below into your Unit1and SAVE
    your project

(9) place the MyRes.RES file into your Delphi
    Project folder

(10) Now you have to tell Delphi that you want to
     use resources. Do this by adding a  compiler
     directive like this :- {$R MyRes.RES} Insert
     the directive into your Unit1 code directly
     below  {$R *.DFM}so you have this :-

     {$R *.DFM}

     {$R MyRes.RES} // See code below

/////////////////////////////////////////
Here is the code you will need....
Delete everything in your Unit1 and copy
and paste this into your Unit
/////////////////////////////////////////

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls, ExtCtrls;

type
 TForm1 = class(TForm)
   Image1: TImage;
   Image2: TImage;
   Button1: TButton;
   Button2: TButton;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.DFM}
{$R myres.res}//
procedure TForm1.Button1Click(Sender: TObject);

begin

    Image1.Picture.Icon.Handle := LoadIcon(HInstance ,'ICON_1');

end;

procedure TForm1.Button2Click(Sender: TObject);
begin
    Image2.picture.icon.handle:=loadicon(Hinstance,'ICON_2');
end;

end.
/////////////////////////////////////////
Have fun
Tongalite

0
 

Author Comment

by:annas
ID: 6868828
Sucess at last! ah sweet sucess! I used Stu's code the first time without changing anything and it worked beautifully. After comparing the code I had originally I think the problem may have been in not using the savetofile method. I don't know why it flagged the error at: ResStr := TResourceStream.Create(hInstance, 'MYMIDI','MIDI'); Though

Anyway I have saved each of your tips in my delphi tips folder and I hope the experts system gives you each a hundred points for your help, for you all have been extreamly helpful!
Paul :)  
0
 

Author Comment

by:annas
ID: 6868840
Oh one more question I wanted to ask!
Is there a way to play the file from memory and not have to save it back to disk first?
Paul :)
0
 
LVL 5

Expert Comment

by:Gwena
ID: 6868988
listening :-)
0
 
LVL 3

Expert Comment

by:SteveWaite
ID: 6869695
How about
TMemoryStream?
0
 

Author Comment

by:annas
ID: 6870146
Tmemorystream? is that the buffer area where the file is stored in memory?
Does Tmemorystream take an address and length as input?
Paul
PS I did find a way to delete the file when I closed the application using the deletefile method. That works great but I would like a way to use the file from memory so i didn't write something on someone's harddrive.
Paul :)
0
 

Author Comment

by:annas
ID: 6870437
Tmemorystream? is that the buffer area where the file is stored in memory?
Does Tmemorystream take an address and length as input?
Paul
PS I did find a way to delete the file when I closed the application using the deletefile method. That works great but I would like a way to use the file from memory so i didn't write something on someone's harddrive.
Paul :)
0
 

Author Comment

by:annas
ID: 6872110
Oh well i was hoping for an answer to that last question but I think I can do the job now and just delete the file when I'm finished. Since Stu provided the answer i used I guess he gets the prize! Again thanks so much people!
If anyone cares to email me the answer to accessing the midi file from memory my adress is p3aul@bell south.net
Paul :)
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Suggested Solutions

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

707 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

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now