⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 user_guide.html

📁 Delphi 资源文件的使用控件
💻 HTML
📖 第 1 页 / 共 4 页
字号:
  <span class="pascal-comment">// Position data ready for reading</span>
  Entry.Data.Position := 0;
  ...
<span class="pascal-kw">end</span>;</pre>
<p>The only point of note here is the use of one of the normal idioms is writing 
	a string to a stream: we can't just do <code>WriteBuffer(Text, Length(Text))</code>, 
	but must either specify <code>Text[1]</code> or <code>PChar(Text)^</code>. Since 
	this is an attribute of <em>TStream</em> rather than the resource file code, 
	it is outside the scope of this document to discuss why!</p>
<p>Now let's look at how we add more text to the end of the resource data:</p>
<pre><span class="pascal-kw">var</span>
  Entry: TPJResourceEntry;
  Text: string;
<span class="pascal-kw">begin</span>
  ...
  <span class="pascal-comment">// Make sure Entry references a resource object</span>
  ...
  <span class="pascal-comment">// Move to end of existing data</span>
  Entry.Data.Seek(0, soFromEnd);
  <span class="pascal-comment">// Write new text</span>
  Text := ' From DelphiDabbler';
  Entry.Data.WriteBuffer(Text[1], Length(Text));
  Text := #13#10'www.delphidabbler.com';
  Entry.Data.WriteBuffer(Text[1], Length(Text));
  <span class="pascal-comment">// Reposition stream to start</span>
  Entry.Data.Position := 0;
  ...
<span class="pascal-kw">end</span>;</pre>
<p>Here we move the stream pointer to the end of the stream so the text we write 
	is appended to any existing data. Given the two examples above the data ends 
	up holding the following two lines of text:</p>
<pre>Hello World from DelphiDabbler
www.delphidabbler.com</pre>
<p class="gototop"><a href="#Top">Back to top</a></p>
<h4><a name="eg6"></a>Example 6: Adding a new resources to a file </h4>
<p>We can add a new resource to an existing file using <em>TPJResourceFile</em>'s 
	<em>AddEntry</em> method. The new resource must be unqiuely named within the 
	resource file (i.e. its combined resource type, name and language id must be 
	unique) otherwise an exception will be raised. There are two versions of the 
	<em>AddEntry</em> method - the first simply adds a new empty resource with zeroed 
	header properties while the second version adds a renamed copy of an existing 
	resource. Both versions of <em>AddEntry</em> take an optional language identifier. 
	If this is not specified the resource is language neutral (<em>LanguageID</em> 
	= 0).</p>
<p>The following code snippet adds four new resource to an existing resource file 
	object:</p>
<ol>
	<li>An empty, language neutral, <code>RCDATA</code> resource with ordinal name 
		42. The <em>MemoryFlags</em> property is then set to &quot;Discardable&quot; 
		and its data is set to &quot;Hello World&quot;</li>
	<li>A new language neutral <code>RCDATA</code> resource that is a copy of the 
		first entry but named <code>FORTYTWO</code>. This resource has the same <em>MemoryFlags</em> 
		and <em>Data</em>.</li>
	<li>A new <code>RCDATA</code> resource also named <code>FORTYTWO</code> but 
		with language ID of $0809. Again this resource is a copy of the first resource.</li>
	<li>A new empty <code>RCDATA</code> resource named 42 with language ID of $0809.</li>
</ol>
<pre><span class="pascal-kw">var</span>
  ResFile: TPJResourceFile;
  Entry1, Entry2,
  Entry3, Entry4: TPJResourceEntry;
<span class="pascal-kw">const</span>
  s42 = 'FORTYTWO';
  ord42 = MakeIntResource(42);
  sHello = 'Hello World';
<span class="pascal-kw">begin</span>
  ...
  <span class="pascal-comment">// Assume ResFile references a valid object</span>
  ...
  <span class="pascal-comment">// Create 1st entry: empty</span>
  Entry1 := fResFile.AddEntry(RT_RCDATA, ord42);
  <span class="pascal-comment">// now set mem flags and data</span>
  Entry1.MemoryFlags := RES_MF_DISCARDABLE;
  Entry1.Data.WriteBuffer(PChar(sHello)^, Length(sHello));
  Entry1.Data.Position := 0;
  <span class="pascal-comment">// Create 2nd entry as copy of entry 1</span>
  Entry2 := fResFile.AddEntry(Entry1, s42);
  <span class="pascal-comment">// Create 3rd entry as copy of entry 1 with language id</span>
  Entry3 := fResFile.AddEntry(Entry1, s42, $0809);
  <span class="pascal-comment">// Create 4th entry: empty with language id</span>
  Entry4 := fResFile.AddEntry(RT_RCDATA, ord42, $0809);
  ...
  <span class="pascal-comment">// Do something with the entries</span>
  ...
<span class="pascal-kw">end</span>;</pre>
<p>The entries we have created have the following properties:</p>
<table border="0" cellspacing="1" cellpadding="3" class="bodytableframe">
	<tr> 
		<th align="left">&nbsp;</th>
		<th>Entry 1</th>
		<th>Entry 2</th>
		<th>Entry 3</th>
		<th>Entry 4</th>
	</tr>
	<tr class="bodytablebody"> 
		<th align="left">Type</th>
		<td><code>RT_RCDATA</code></td>
		<td><code>RT_RCDATA</code></td>
		<td><code>RT_RCDATA</code></td>
		<td><code>RT_RCDATA</code></td>
	</tr>
	<tr class="bodytablebody"> 
		<th align="left">Name</th>
		<td>42</td>
		<td><code>FORTYTWO</code></td>
		<td><code>FORTYTWO</code></td>
		<td>42</td>
	</tr>
	<tr class="bodytablebody"> 
		<th align="left">LanguageID</th>
		<td>0</td>
		<td>0</td>
		<td>$0809</td>
		<td>$0809</td>
	</tr>
	<tr class="bodytablebody"> 
		<th align="left">MemoryFlags</th>
		<td>$0100</td>
		<td>$0100</td>
		<td>$0100</td>
		<td>0</td>
	</tr>
	<tr class="bodytablebody"> 
		<th align="left">Data</th>
		<td>&quot;Hello World&quot;</td>
		<td>&quot;Hello World&quot;</td>
		<td>&quot;Hello World&quot;</td>
		<td>&lt;empty&gt;</td>
	</tr>
</table>
<p class="gototop"><a href="#Top">Back to top</a></p>
<h4><a name="eg7"></a>Example 7: Checking is a resource exists </h4>
<p>We noted above that an exception is raised in a duplicate resource is added 
	to a file. To prevent this we may need to check if a resource exists and we 
	can do this with the <em>EntryExists</em> method of <em>TPJResourceFile</em> 
	as follows:</p>
<pre><span class="pascal-kw">var</span>
  ResFile: TPJResourceFile;
  Entry: TPJResourceEntry;
<span class="pascal-kw">begin</span>
  ...
  <span class="pascal-comment">// Assume ResFile references a valid object</span>
  ...
  <span class="pascal-kw">if not</span> ResFile.EntryExists(RT_RCDATA, 'FORTYTWO', $0809) <span class="pascal-kw">then</span>
    Entry := ResFile.AddEntry(RT_RCDATA, 'FORTYTWO', $0809);
  ...
<span class="pascal-kw">end</span>;</pre>
<p>Note that the language id parameter to <em>EntryExists</em> is optional and 
	if ommitted the function checks if any resource with the given type and name 
	exists. Furthermore, specifying nil for the resource name makes the routine 
	check if any resource of the given type exists. So to check if a resource file 
	contains any <code>RCDATA</code> resources use:</p>
<pre><span class="pascal-kw">if</span> ResFile.EntryExists(RT_RCDATA, <span class="pascal-kw">nil</span>) <span class="pascal-kw">then</span>
  <span class="pascal-comment">// We have RCDATA resources in the file</span></pre>
<p class="gototop"><a href="#Top">Back to top</a></p>
<h4><a name="eg8"></a>Example 8: Deleting resources</h4>
<p>We can delete all resources from a resource file simply by calling the <em>Clear</em> 
	method of <em>TPJResourceFile</em>. In addition to deleting the resources it 
	also frees all the <em>TPJResourceEntry</em> instances.</p>
<pre><span class="pascal-kw">var</span>
  ResFile: TPJResourceFile;
<span class="pascal-kw">begin</span>
  ...
  <span class="pascal-comment">// Assume ResFile is a valid resource file object</span>
  ...
  <span class="pascal-comment">// Delete all resources</span>
  ResFile.Clear;
  ...
<span class="pascal-kw">end</span>;</pre>
<p>A single resource can be deleted from the resource file using the <em>TPJResourceFile.DeleteEntry</em> 
	method. This checks if the file contains the resource and deletes it if so. 
	However, the resource entry object is not freed. While this behaviour may be 
	useful, it is not recommended. The preferred method is simply to free the resource 
	entry instance. Freeing a <em>TPJResourceEntry</em> object autmatically removes 
	it from the resource file.</p>
<p>So, to remove a single resource <em>ResEntry</em> from the resource file use 
	the following code:</p>
<pre><span class="pascal-kw">var</span>
  Entry: TPJResourceEntry;
<span class="pascal-kw">begin</span>
  ...
  <span class="pascal-comment">// Assume ResEntry references a valid object</span>
  ...
  <span class="pascal-comment">// Delete the object from its resource file</span>
  Entry.Free;
  ...
<span class="pascal-kw">end</span>;</pre>
<p class="gototop"><a href="#Top">Back to top</a></p>
<h4><a name="eg9"></a>Example 9: Saving a resource file </h4>
<p>Now that we have learned how to modify a resource file, it's time to know how 
	to save it. We simply use the <em>SaveToFile</em> or <em>SaveToStream</em> methods 
	of <em>TPJResourceFile</em>. The following code shows how to use <em>SaveToFile</em>:</p>
<pre><span class="pascal-kw">var</span>
  ResFile: TPJResourceFile;
<span class="pascal-kw">begin</span>
  <span class="pascal-comment">// Assume ResFile references a valid object</span>
  ...
  <span class="pascal-comment">// Save the file to 'MyResource.res'</span>
  ResFile.SaveToFile('MyResource.res');
<span class="pascal-kw">end</span>;</pre>
<p class="gototop"><a href="#Top">Back to top</a></p>
<h4><a name="eg10"></a>Example 10: A practical example </h4>
<p>Having given some contrived examples of most of the functionality in the <em>PJResFile</em> 
	unit, let us close by presenting a useful example that uses several of the methods 
	we have reviewed.</p>
<p>We will create a routine that takes a list of HTML and related files and create 
	a resource file which has a unique resource HTML resource for each file. Such 
	resources can be used for display in Internet Explorer, using the res:// protocol. 
	See my article &quot;<a href="http://www.delphidabbler.com/articles.php?article=10"><!--<a href="/articles.php?article=10">-->How
	to create and use HTML resource files</a>&quot; for more information on this subject.</p>
<p>Here is the code of the routine: </p>
<pre><span class="pascal-kw">procedure</span> BuildHTMLResFile(<span class="pascal-kw">const</span> Files: TStrings;
  <span class="pascal-kw">const</span> ResFileName: <span class="pascal-kw">string</span>);
<span class="pascal-kw">var</span>
  ResFile: TPJResourceFile; <span class="pascal-comment">// res file object</span>
  Entry: TPJResourceEntry;  <span class="pascal-comment">// a resource entry</span>
  ResName: string;          <span class="pascal-comment">// a resource name</span>
  SrcFileName: string;      <span class="pascal-comment">// a source file name</span>
  SrcStm: TFileStream;      <span class="pascal-comment">// source file stream</span>
  FileIdx: Integer;         <span class="pascal-comment">// loops thru Files</span>
<span class="pascal-kw">begin</span>
  <span class="pascal-comment">// Create new empty resource file object</span>
  ResFile := TPJResourceFile.Create;
  <span class="pascal-kw">try</span>
    <span class="pascal-comment">// Loop thru all source files</span>
    <span class="pascal-kw">for</span> FileIdx := 0 <span class="pascal-kw">to</span> Pred(Files.Count) <span class="pascal-kw">do</span>
    <span class="pascal-kw">begin</span>
      <span class="pascal-comment">// Record source file name</span>
      SrcFileName := Files[FileIdx];
      <span class="pascal-comment">// Get resource name from source name</span>
      ResName := ExtractFileName(SrcFileName);
      <span class="pascal-comment">// Ensure res name is not a duplicate</span>
      <span class="pascal-kw">while</span> ResFile.EntryExists(
        RT_HTML, PChar(ResName), $0809
      ) <span class="pascal-kw">do</span>
        ResName := '_' + ResName;
      <span class="pascal-comment">// Create new resource</span>
      Entry := ResFile.AddEntry(
        RT_HTML, PChar(ResName), $0809
      );
      <span class="pascal-comment">// Copy source file into resource data</span>
      SrcStm := TFileStream.Create(SrcFileName, fmOpenRead);
      <span class="pascal-kw">try</span>
        Entry.Data.CopyFrom(SrcStm, 0);
        Entry.Data.Position := 0;
      <span class="pascal-kw">finally</span>
        SrcStm.Free;
      <span class="pascal-kw">end</span>;
    <span class="pascal-kw">end</span>;
    <span class="pascal-comment">// Save resource file</span>
    ResFile.SaveToFile(ResFileName);
  <span class="pascal-kw">finally</span>
    <span class="pascal-comment">// Free resource file object</span>
    ResFile.Free;
  <span class="pascal-kw">end</span>;
<span class="pascal-kw">end</span>;</pre>
<p>This routine is passed a list of files that are to be included in the resource 
	file (as a string list). The name of the output file is also provided. We first 
	create a new resource file object to store the HTML resources. We then loop 
	through all the files in the list and add a new resource for each file. The 
	resource is named with the name of the file (file name only, no path). To ensure 
	the resource names are not duplicated we repeatedly append underscore characters 
	to duplicate names until they are unique. Having got a unique resource name 
	we create a new entry with the required name and then copy the file's contents 
	into the resource data. Finally we save the resource file and free the resource 
	file object.</p>
<p class="gototop"><a href="#Top">Back to top</a></p>
<!-- for stand-alone file -->
<p>This user guide and the software it refers to are copyright &copy; Peter
Johnson,2004.
<a href="http://www.delphidabbler.com/">http://www.delphidabbler.com/</a>.</p>
</body>
</html>
<!-- END -->

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -