-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patharticle-3.html
142 lines (111 loc) · 11 KB
/
article-3.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
---
article: 3
title: "How to read data embedded in your program's resources"
summary: "Having embedded files and/or data in your executable (article #2) you need to get them out again - read on!"
meta-title: "Use Delphi Pascal to read data embedded in a program's resources | How to"
meta-desc: "An article that shows how to use Delphi Pascal to extract data files that were previously compiled into in a Windows program's resources."
link-prev: "/articles/article-2"
index: true
redirect_from:
- /articles/3
---
<section id="intro">
<h2>Why do it?</h2>
<p>In a <a href="./article-2">previous article</a> we dealt with why and how to embed data from a file in your program's resources. If we do that we're going to want to extract it again.</p>
</section>
<section id="method">
<h2>How it's done</h2>
<p>This article assumes that the data you embedded was in the <var>RCDATA</var> format. This is a user-defined data format so we also assume that you know how to decode the format.</p>
<p>Reading it back from the resource is very simple due to the <var>TResourceStream</var> class that ships with Delphi. You create a <var>TResourceStream</var> in one of two ways:</p>
<div class="frame">
<div class="code-pascal">
<pre class="line"><span class="linenum"> 1</span><span class="kwd">var</span></pre>
<pre
class="line"><span class="linenum"> 2</span><span class="space"> </span><span class="ident">RS</span><span class="sym">:</span><span class="space"> </span><span class="ident">TResourceStream</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 3</span><span class="kwd">begin</span></pre>
<pre
class="line"><span class="linenum"> 4</span><span class="space"> </span><span class="comment">// Do this if the resource is named</span></pre>
<pre
class="line"><span class="linenum"> 5</span><span class="space"> </span><span class="ident">RS</span><span class="space"> </span><span class="sym">:=</span><span class="space"> </span><span class="ident">TResourceStream</span><span class="sym">.</span><span class="ident">Create</span><span class="sym">(</span></pre>
<pre
class="line"><span class="linenum"> 6</span><span class="space"> </span><span class="ident">HInstance</span><span class="sym">,</span><span class="space"> </span><span class="comment">// your app or DLL instance handle</span></pre>
<pre
class="line"><span class="linenum"> 7</span><span class="space"> </span><span class="ident">ResourceName</span><span class="sym">,</span><span class="space"> </span><span class="comment">// string containing resource name</span></pre>
<pre
class="line"><span class="linenum"> 8</span><span class="space"> </span><span class="ident">RT_RCDATA</span><span class="sym">)</span><span class="sym">;</span><span class="space"> </span><span class="comment">// identifies RCDATA resource type</span></pre>
<pre
class="line"><span class="linenum"> 9</span><span class="space"> </span><span class="comment">// ... or do this if it is identified by an ordinal </span></pre>
<pre
class="line"><span class="linenum"> 10</span><span class="space"> </span><span class="comment">// value (per my article on writing the data)</span></pre>
<pre
class="line"><span class="linenum"> 11</span><span class="space"> </span><span class="ident">RS</span><span class="space"> </span><span class="sym">:=</span><span class="space"> </span><span class="ident">TResourceStream</span><span class="sym">.</span><span class="ident">CreateFromID</span><span class="sym">(</span></pre>
<pre
class="line"><span class="linenum"> 12</span><span class="space"> </span><span class="ident">HInstance</span><span class="sym">,</span><span class="space"> </span><span class="comment">// as above</span></pre>
<pre
class="line"><span class="linenum"> 13</span><span class="space"> </span><span class="ident">ResourceID</span><span class="sym">,</span><span class="space"> </span><span class="comment">// Word identifier</span></pre>
<pre
class="line"><span class="linenum"> 14</span><span class="space"> </span><span class="ident">RT_RCDATA</span><span class="sym">)</span><span class="sym">;</span><span class="space"> </span><span class="comment">// as above</span></pre>
<pre class="line"><span class="linenum"> 15</span><span class="kwd">end</span><span class="sym">;</span></pre>
</div>
<div class="caption">Listing 1</div>
</div>
<p>You now just use the stream to read the data as if it was coming from a file. You can't write to a <var>TResourceStream</var> as data embedded in an executable file is read only.</p>
<p>To copy your embedded file into another stream (say <var>Stm</var> of type <var>TStream</var>) you can use this code:</p>
<div class="frame">
<div class="code-pascal">
<pre
class="line"><span class="linenum"> 1</span><span class="ident">Stm</span><span class="sym">.</span><span class="ident">CopyFrom</span><span class="sym">(</span><span class="ident">RS</span><span class="sym">,</span><span class="space"> </span><span class="ident">RS</span><span class="sym">.</span><span class="ident">Size</span><span class="sym">)</span><span class="sym">;</span></pre>
</div>
<div class="caption">Listing 2</div>
</div>
<p>As an example, say we have a program that includes a resource file that contains an <var>RCDATA</var> resource which has a copy of a rich text file inside it. The program displays the embedded rich text in a rich edit component. This is the code we need:</p>
<div class="frame">
<div class="code-pascal">
<pre class="line"><span class="linenum"> 1</span><span class="kwd">var</span></pre>
<pre
class="line"><span class="linenum"> 2</span><span class="space"> </span><span class="ident">RS</span><span class="sym">:</span><span class="space"> </span><span class="ident">TResourceStream</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 3</span><span class="kwd">begin</span></pre>
<pre
class="line"><span class="linenum"> 4</span><span class="space"> </span><span class="comment">// Create resource stream (resource id is 100)</span></pre>
<pre
class="line"><span class="linenum"> 5</span><span class="space"> </span><span class="ident">RS</span><span class="space"> </span><span class="sym">:=</span><span class="space"> </span><span class="ident">TResourceStream</span><span class="sym">.</span><span class="ident">CreateFromID</span><span class="sym">(</span><span class="ident">HInstance</span><span class="sym">,</span></pre>
<pre
class="line"><span class="linenum"> 6</span><span class="space"> </span><span class="num">100</span><span class="sym">,</span><span class="space"> </span><span class="ident">RT_RCDATA</span><span class="sym">)</span><span class="sym">;</span></pre>
<pre
class="line"><span class="linenum"> 7</span><span class="space"> </span><span class="kwd">try</span></pre>
<pre
class="line"><span class="linenum"> 8</span><span class="space"> </span><span class="comment">// Load the rich edit component</span></pre>
<pre
class="line"><span class="linenum"> 9</span><span class="space"> </span><span class="ident">RichEdit1</span><span class="sym">.</span><span class="ident">Lines</span><span class="sym">.</span><span class="ident">LoadFromStream</span><span class="sym">(</span><span class="ident">RS</span><span class="sym">)</span><span class="sym">;</span></pre>
<pre
class="line"><span class="linenum"> 10</span><span class="space"> </span><span class="kwd">finally</span></pre>
<pre
class="line"><span class="linenum"> 11</span><span class="space"> </span><span class="comment">// Free the stream</span></pre>
<pre
class="line"><span class="linenum"> 12</span><span class="space"> </span><span class="ident">RS</span><span class="sym">.</span><span class="ident">Free</span><span class="sym">;</span></pre>
<pre
class="line"><span class="linenum"> 13</span><span class="space"> </span><span class="kwd">end</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 14</span><span class="kwd">end</span><span class="sym">;</span></pre>
</div>
<div class="caption">Listing 3</div>
</div>
</section>
<section id="demo">
<h2>Demo Code</h2>
<p>A demo program to accompany this article (and the related <a href="./article-2">article</a>) can be found in the <code><a href="https://github.com/delphidabbler/article-demos">delphidabbler/article-demos</a></code> Git repository on GitHub.</p>
<p>You can view the code in the <code><a href="https://github.com/delphidabbler/article-demos/tree/master/article-02%2B03">article-02+03</a></code> sub-directory. Alternatively download a zip file containing all the available demos by going to the repository's landing page and clicking the <em>Clone or download</em> button and selecting <em>Download ZIP</em>.</p>
<p>The demo demonstrates what has been described here. It contains a pair of projects. The first is a program that embeds a supplied rich text file in a resource file. The second program includes the resource file and displays the rich text in a rich edit component.</p>
<div class="callout callout-info">
<p><span class="fa fa-code fa-x-pad-right fa-2x fa-pull-left fa-border text-muted"></span>This source code is merely a proof of concept and is intended only to illustrate this article. It is not designed for use in its current form in finished applications. The code is provided on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.</p>
<p>The demo is open source. See the demo's <a href="https://github.com/delphidabbler/article-demos/blob/master/article-02%2B03/LICENSE.md">LICENSE.md</a> file for licensing details.</p>
</div>
</section>
<section id="feedback">
<h2>Feedback</h2>
<p>I hope you found this article useful.</p>
<p>If you have any observations, comments, or have found any errors there are two places you can report them.</p>
<ol class="wide">
<li>For anything to do with the article content, <em>but not the downloadable demo code</em>, please use this website's <a href="https://github.com/delphidabbler/delphidabbler.github.io/issues">Issues page</a> on GitHub. Make sure you mention that the issue relates to "article #3".</li>
<li>For bugs in the demo code see the <code>article-demo</code> project's <code><a href="https://github.com/delphidabbler/article-demos/blob/master/README.md#bug-reports">README.md</a></code> file for details of how to report them.</li>
</ol>
</section>