• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 517
  • Last Modified:

I need an easily maintainable way to compile some text into my Delphi application

 I just developed a class that will let me use text to describe a complex set of business object interactions.  Currently I have about 60 lines in my description and I expect it to get larger.  I have not had much reason to try to compile in any text this size in the past.

  I know I can make it a ResourceString, but that would mean converting my text (which contains single quotes and CRLFs) into a Delphi style string.  This would loose the readability / editability of the text.  I could also code it to be added to a string list, but get the same lack of readabilty / editability.

  I considered making a form with a memo on it and using it's Lines property.  This would allow me to use Delphi's code editor to edit the text while easily compiling it into my application.  This does carry extra overhead for defining an otherwize useless form.

  Ideally I would want to be able to tell the Delphi compiler to compile in a text file as a resource.  I figured that with all the other experts here someone else must have had a similar issue, so I am looking for ideas.  The best one gets the points.  I am giving 500 points because I need it for a current project that is under a deadline.
0
developmentguru
Asked:
developmentguru
  • 9
  • 5
  • 5
  • +1
1 Solution
 
MerijnBSr. Software EngineerCommented:
what about GNU Gettext: http://dybdahl.dk/dxgettext/docs/
0
 
2266180Commented:
thah's easy )

just create a file named "the_text.rc" *you can name it anyway you like it) and add the following line:

THETEXT RC_DATA "path and name of txt file with "

then in your project file (dpr) you add the folloing line right before uses clause:

{$R 'the_text.res' 'the_text.rc'}

obviously, if you changed the rc filename, it changes here as well ;)

then, in your form constructor or wherever you are loading you stuff, you add soemthing like this:

the_text:tstringlist; delcare this in the private section of your form or somewhere accessible
....
var
r:tresourcestream;
begin
  the_text:=tstringlist.create;
  r:=tresourcestream.create(hinstance, 'THETEXT', RT_RCDATA);// if you changed the THETEXT from the .rc file then update here as well
  try
    the_text.loadfromstream(r);
  finally
    freeandnil(r);
  end;
end;

then in your destructor or somehwere do:

freeandnil(the_text);

I wrote evrything directly in the browser so if you have any problems that you cannot fix, just ask (will probably be typos) ;)
0
 
developmentguruPresidentAuthor Commented:
MerijnB:
  I looked at the link you posted and it is interesting.  I am currently trying to store one version of the string and may need to store more than one in the future.  I think if that happens it will likely go into a database record instead.  Useful info, but not for me at this point.

ciuly:
  Will I not need to run a resource compiler each time my text changes (prior to compiling my exe)?  If the Delphi compiler handles recompiling the resource each time then this will be ideal for what I need right now.  I will wait to see your response.
0
Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

 
JohnjcesCommented:
I am just curious, but if you load your resource into a TSTringList, you do not lose your CR/LF or single quotes. A StringList will put each line on its own line using the CR/LF for the next line in the stringlist. Makes for long lines and I have had no problems with quotes in a text string. My only problem with quotes is when constructing a string at run time say for an SQL query.

Using Ciuly's code, you could also compile it in as an RTF and use more control characters and would keep readability for long lines. Then at runtime you could load it into, if you had to, an invisible RTF memo.

Just a thought.

John
0
 
JohnjcesCommented:
By...

"then in your project file (dpr) you add the folloing line right before uses clause:

{$R 'the_text.res' 'the_text.rc'}"

it will recompile the resource everytime you build the application.

John
0
 
2266180Commented:
" Will I not need to run a resource compiler each time my text changes (prior to compiling my exe)?"

no, it iwll be run automatically when delphi is compiling the exe. that's why i gave it you that way ;)
0
 
developmentguruPresidentAuthor Commented:
Johnjces:

  I actually thought of loading it into a TStringList, but that was just to reuse the code that does the load.  My parsing routine will take a string as input and recognize the line breaks as needed.  The readability issue is only for myself and any other developer who comes behind me.  I would want them to be able to easily load up the .txt file in the editor, make changes, and recompile.

  A little more project background... The project I am working on needs to be able to load and save wizard style information in varying record connection formats across 12 database tables.  By definiing the business rules via text I can change the rules easily.  On load I need to be able to determine all of the mathing records across all tables, attempt to load and connect them as indicated in the database tables, look for disconnected records, and finally determine if the set of information meets the current business rules.  I will then be able to use the same set of business rules to determine which farmes to build as the user uses the wizard portion.  The same logic will be used during the save process where I need to start by lookig up the in use IDs across all tables it could save to.  This gives me a pool of IDs to draw on as I write records back to each table.  When the process of writing the records is done I will be able to delete the records who's IDs remain in the table lists.

  As you can see the definition could need modification in the future, but for now my plan is to compile in the "current" definition.  If the Definition changes and I attempt to load an older set of information then I will offer the user the option of opening it in read only mode.  This gives me a current or not current means of dealing with what could be many sets of logic.  I can avoid code bloat by either 1) using the current - not current approach, or 2) Placing my list of definitions in separate database records so that my code can adapt to all previous versions.  Either way, defining the logic as text works.  The only bloat then would be for maintaining individual wizard frames that are no longer used, but remain for backward compatability.  I could place the frame definitions in a BPL so that they are only loaded as needed...

  Sorry if that is TMI (Too much info), but I figure more is better than not enough.
0
 
JohnjcesCommented:
Just my .02 cents....

But it seems that a recompile/build of your code because one rule changes simply seems like a lot of extra effort and developer time, when it would be easier and less time consuming (and I am all about easier and less time :)) to send out just a text file with your business rules to your users, or when your app starts check for new rules somewhere on some server.

If you are worried about users messing with the rules, you could obfuscate it with a simple encryption/decryption routine.

John
0
 
developmentguruPresidentAuthor Commented:
I get a
[DCC Error] E1026 File not found: 'WizardRules.Rres'

I created the WizardRules.rc and WizardRules.txt

I did a Project | View Source and placed the line

{$R 'WizardRules.res' 'WizardRules.rc'}

before the uses clause.

So far it is not compiling in, but quitting the compile stating that it cannot find the .RES file.  Perhaps some compiler setting I need to turn on?
0
 
developmentguruPresidentAuthor Commented:
The Rres is s typo...  the error is
[DCC Error] E1026 File not found: 'WizardRules.res'
0
 
JohnjcesCommented:
Your WizardRules.rc file contains:

1 24 WizardRules.txt

one line only?

Sounds like the resource isn't being created. Hmmm.

John
0
 
2266180Commented:
well I tested on a project and it works. is the WizardRules.rc in the same folder as the dpr? is the WizardRules.txt in the same folder as the dpr and rc?
I tested with delphi 7. what's your version?
0
 
developmentguruPresidentAuthor Commented:
I tried changing the one line in the RC file to the following and still no joy.

WizardRulesV1 RC_DATA "c:\projects\Wizard UI Experiment\WizardRules.txt"

All the files are in the same directory (File | Save As comes up to the same directory on each)

I am on Delphi 2007 Enterprise.
0
 
developmentguruPresidentAuthor Commented:
I wonder if CodeGear's move to using the Microsoft build utility might have something to do with it not auto compiling any more...  I will try to manually compile it.
0
 
2266180Commented:
that might be a problem. though I would expect there be an error.

there is an easier way to check if it's a bug or something that chaged:
- place the caret on the $R and then press ctrl+f1
- see in the helk file if you have the option of specifying the rc file as the source or not.
in delphi 7 it appears like this:
Syntax      {$R filename}
{$RESOURCE filename}{$R *.xxx}
{$R filename.res filename.rc}

in worse case scenario, you could just make a build.bat file and enter the build command there:

brcc32 WizardRules.rc
dcc32 project.dpr

one small matter: I hope your project is not called WizardRules.dpr is it? because then you are overriding the project resource file which is bad.
0
 
developmentguruPresidentAuthor Commented:
The Delphi help does state that the syntax works for specifying the RES and RC files.
The project is SalesSupport.dpr
I manually ran the brcc32.exe WizardRules.rc and it went through.  The application compiles with the $R directive now.  The creation of the resource stream fails with the following error:

Project SalesSupport.exe raised exception class EResNotFound with message 'Resource WizardRulesV1 not found'.
0
 
2266180Commented:
maybe it's

WizardRulesV1 RCDATA WizardRules.txt

?
(no underscore). let me know if that's not it and I'll fire up a small demo to test
0
 
developmentguruPresidentAuthor Commented:
Thanks for sticking with me til it worked.
0
 
developmentguruPresidentAuthor Commented:
I appreciate your input johnjces and will be looking into alternatives on how to get the text to the user at a later stage.  I awarded ciuly the points since he answered the question best.  Thanks both for your efforts.
0
 
JohnjcesCommented:
No problem! I enjoy it and boy do I learn from it!

John
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 9
  • 5
  • 5
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now