-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patharticle-4.html
190 lines (153 loc) · 29.1 KB
/
article-4.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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
---
article: 4
title: "How to remember a window's size, state and position"
summary: "When I open an application I like to have it remember the size and position of its window when it was last closed. Here's how to do it with Delphi forms."
meta-title: "Use Delphi Pascal to remember a window's size, state and position | How to"
meta-desc: "An article that describes how to use Delphi Pascal to save a window's size, state & position in the Windows registry."
index: true
redirect_from:
- /articles/4
---
<section id="intro">
<h2>Why do it?</h2>
<p>It's often useful to remember the size and state of your program's windows between executions. This article discusses how.</p>
</section>
<section id="method">
<h2>How it's done</h2>
<p>The method we're going to use is to save the position in the registry. I won't discuss details of how to access the registry from code in depth here. First of all, decide where in the registry you're going to keep the information. It's customary for applications to place information that varies between users in:</p>
<pre class="pre-scrollable">HKEY_CURRENT_USER\Software\MyCompany\MyProgram\X.X</pre>
<p>(where <code>X.X</code> is the version number of the program). We'll use such a key in this article.</p>
<p>You can save the window's current position and size when the program is closing down – the <var>OnDestroy</var> form event handler is a good place for this. The program then restores it's position from the registry (if it's been written yet) when opening – we use the form's <var>OnCreate</var> handler for that code.</p>
<p>There are complications when saving and restoring the window state. When the window is minimised, Delphi doesn't minimise the form – it hides it and displays the Application window in the taskbar. The method I've used causes a previously minimised window to flash on-screen briefly. I'd welcome ideas on any alternative approaches.†</p>
<aside>
<p class="alert alert-info "><span class="bg-primary"> † </span> The later releases of my <a href="/software/wdwstate">Window State Components</a> solve the minimisation problem. However the solution is quite involved. You are welcome to read the component code if you are interested.</p>
</aside>
<p>Another complication is that when a window is maximised Delphi updates the <var>Width</var>, <var>Height</var>, <var>Left</var> and <var>Top</var> properties of the form to the window's maximised size and position. This means that closing a maximised window stores the maximised size in the registry. When the program is run again it appears maximised, but when the user restores it they expect it to go to the previous normal size and position, but if we reloaded the <var>Left</var>, <var>Top</var>, <var>Height</var> and <var>Width</var> properties, the form won't shrink when restored. We get round this by using the Windows API to get the non-maximised size.</p>
<p>Here's the code – the comments should explain what's happening.</p>
<div class="frame" id="listing-1">
<div class="code-pascal">
<pre class="line"><span class="linenum"> 1</span><span class="kwd">const</span></pre>
<pre class="line"><span class="linenum"> 2</span><span class="space"> </span><span class="ident">CRegKey</span><span class="space"> </span><span class="sym">=</span><span class="space"> </span><span class="str">'Software\Demos\WdwStateDemo\1.0'</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 3</span><span class="space"> </span></pre>
<pre class="line"><span class="linenum"> 4</span><span class="comment">// Helper function to read registry values, and</span></pre>
<pre class="line"><span class="linenum"> 5</span><span class="comment">// deal with cases where no values exist</span></pre>
<pre class="line"><span class="linenum"> 6</span><span class="kwd">function</span><span class="space"> </span><span class="ident">ReadIntFromReg</span><span class="sym">(</span><span class="ident">Reg</span><span class="sym">:</span><span class="space"> </span><span class="ident">TRegistry</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 7</span><span class="space"> </span><span class="ident">Name</span><span class="sym">:</span><span class="space"> </span><span class="kwd">string</span><span class="sym">;</span><span class="space"> </span><span class="ident">Def</span><span class="sym">:</span><span class="space"> </span><span class="ident">Integer</span><span class="sym">)</span><span class="sym">:</span><span class="space"> </span><span class="ident">Integer</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 8</span><span class="space"> </span><span class="comment">{Reads integer with given name from registry</span></pre>
<pre class="line"><span class="linenum"> 9</span><span class="comment"> and returns it. If no such value exists, returns</span></pre>
<pre class="line"><span class="linenum"> 10</span><span class="comment"> Def default value}</span></pre>
<pre class="line"><span class="linenum"> 11</span><span class="kwd">begin</span></pre>
<pre class="line"><span class="linenum"> 12</span><span class="space"> </span><span class="kwd">if</span><span class="space"> </span><span class="ident">Reg</span><span class="sym">.</span><span class="ident">ValueExists</span><span class="sym">(</span><span class="ident">Name</span><span class="sym">)</span><span class="space"> </span><span class="kwd">then</span></pre>
<pre class="line"><span class="linenum"> 13</span><span class="space"> </span><span class="ident">Result</span><span class="space"> </span><span class="sym">:=</span><span class="space"> </span><span class="ident">Reg</span><span class="sym">.</span><span class="ident">ReadInteger</span><span class="sym">(</span><span class="ident">Name</span><span class="sym">)</span></pre>
<pre class="line"><span class="linenum"> 14</span><span class="space"> </span><span class="kwd">else</span></pre>
<pre class="line"><span class="linenum"> 15</span><span class="space"> </span><span class="ident">Result</span><span class="space"> </span><span class="sym">:=</span><span class="space"> </span><span class="ident">Def</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 16</span><span class="kwd">end</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 17</span><span class="space"> </span></pre>
<pre class="line"><span class="linenum"> 18</span><span class="kwd">procedure</span><span class="space"> </span><span class="ident">TForm1</span><span class="sym">.</span><span class="ident">FormDestroy</span><span class="sym">(</span><span class="ident">Sender</span><span class="sym">:</span><span class="space"> </span><span class="ident">TObject</span><span class="sym">)</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 19</span><span class="kwd">var</span></pre>
<pre class="line"><span class="linenum"> 20</span><span class="space"> </span><span class="ident">Reg</span><span class="sym">:</span><span class="space"> </span><span class="ident">TRegistry</span><span class="sym">;</span><span class="space"> </span><span class="comment">// the registry</span></pre>
<pre class="line"><span class="linenum"> 21</span><span class="space"> </span><span class="ident">State</span><span class="sym">:</span><span class="space"> </span><span class="ident">Integer</span><span class="sym">;</span><span class="space"> </span><span class="comment">// state of window</span></pre>
<pre class="line"><span class="linenum"> 22</span><span class="space"> </span><span class="ident">Pl</span><span class="space"> </span><span class="sym">:</span><span class="space"> </span><span class="ident">TWindowPlacement</span><span class="sym">;</span><span class="space"> </span><span class="comment">// used for API call</span></pre>
<pre class="line"><span class="linenum"> 23</span><span class="space"> </span><span class="ident">R</span><span class="sym">:</span><span class="space"> </span><span class="ident">TRect</span><span class="sym">;</span><span class="space"> </span><span class="comment">// used for window pos</span></pre>
<pre class="line"><span class="linenum"> 24</span><span class="kwd">begin</span></pre>
<pre class="line"><span class="linenum"> 25</span><span class="space"> </span><span class="comment">{Calculate window's normal size and position</span></pre>
<pre class="line"><span class="linenum"> 26</span><span class="comment"> using Windows API call - the form's Width, Height,</span></pre>
<pre class="line"><span class="linenum"> 27</span><span class="comment"> Top and Left properties will give maximised window</span></pre>
<pre class="line"><span class="linenum"> 28</span><span class="comment"> size if form is maximised, which is not what we</span></pre>
<pre class="line"><span class="linenum"> 29</span><span class="comment"> want here}</span></pre>
<pre class="line"><span class="linenum"> 30</span><span class="space"> </span><span class="ident">Pl</span><span class="sym">.</span><span class="ident">Length</span><span class="space"> </span><span class="sym">:=</span><span class="space"> </span><span class="ident">SizeOf</span><span class="sym">(</span><span class="ident">TWindowPlacement</span><span class="sym">)</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 31</span><span class="space"> </span><span class="ident">GetWindowPlacement</span><span class="sym">(</span><span class="ident">Self</span><span class="sym">.</span><span class="ident">Handle</span><span class="sym">,</span><span class="space"> </span><span class="sym">@</span><span class="ident">Pl</span><span class="sym">)</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 32</span><span class="space"> </span><span class="ident">R</span><span class="space"> </span><span class="sym">:=</span><span class="space"> </span><span class="ident">Pl</span><span class="sym">.</span><span class="ident">rcNormalPosition</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 33</span><span class="space"> </span><span class="ident">Reg</span><span class="space"> </span><span class="sym">:=</span><span class="space"> </span><span class="ident">TRegistry</span><span class="sym">.</span><span class="ident">Create</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 34</span><span class="space"> </span><span class="kwd">try</span></pre>
<pre class="line"><span class="linenum"> 35</span><span class="space"> </span><span class="comment">// Open required key - create if doesn't exist</span></pre>
<pre class="line"><span class="linenum"> 36</span><span class="space"> </span><span class="ident">Reg</span><span class="sym">.</span><span class="ident">RootKey</span><span class="space"> </span><span class="sym">:=</span><span class="space"> </span><span class="ident">HKEY_CURRENT_USER</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 37</span><span class="space"> </span><span class="ident">Reg</span><span class="sym">.</span><span class="ident">OpenKey</span><span class="sym">(</span><span class="ident">CRegKey</span><span class="sym">,</span><span class="space"> </span><span class="ident">True</span><span class="sym">)</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 38</span><span class="space"> </span><span class="comment">// Write window size and position</span></pre>
<pre class="line"><span class="linenum"> 39</span><span class="space"> </span><span class="ident">Reg</span><span class="sym">.</span><span class="ident">WriteInteger</span><span class="sym">(</span><span class="str">'Width'</span><span class="sym">,</span><span class="space"> </span><span class="ident">R</span><span class="sym">.</span><span class="ident">Right</span><span class="sym">-</span><span class="ident">R</span><span class="sym">.</span><span class="ident">Left</span><span class="sym">)</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 40</span><span class="space"> </span><span class="ident">Reg</span><span class="sym">.</span><span class="ident">WriteInteger</span><span class="sym">(</span><span class="str">'Height'</span><span class="sym">,</span><span class="space"> </span><span class="ident">R</span><span class="sym">.</span><span class="ident">Bottom</span><span class="sym">-</span><span class="ident">R</span><span class="sym">.</span><span class="ident">Top</span><span class="sym">)</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 41</span><span class="space"> </span><span class="ident">Reg</span><span class="sym">.</span><span class="ident">WriteInteger</span><span class="sym">(</span><span class="str">'Left'</span><span class="sym">,</span><span class="space"> </span><span class="ident">R</span><span class="sym">.</span><span class="ident">Left</span><span class="sym">)</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 42</span><span class="space"> </span><span class="ident">Reg</span><span class="sym">.</span><span class="ident">WriteInteger</span><span class="sym">(</span><span class="str">'Top'</span><span class="sym">,</span><span class="space"> </span><span class="ident">R</span><span class="sym">.</span><span class="ident">Top</span><span class="sym">)</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 43</span><span class="space"> </span><span class="comment">// Write out state of window</span></pre>
<pre class="line"><span class="linenum"> 44</span><span class="space"> </span><span class="comment">{Record window state (maximised, minimised or</span></pre>
<pre class="line"><span class="linenum"> 45</span><span class="comment"> normal) - special case when minimised since form</span></pre>
<pre class="line"><span class="linenum"> 46</span><span class="comment"> window is simply hidden when minimised, and</span></pre>
<pre class="line"><span class="linenum"> 47</span><span class="comment"> application window is actually the one</span></pre>
<pre class="line"><span class="linenum"> 48</span><span class="comment"> minimised - so we check to see if application</span></pre>
<pre class="line"><span class="linenum"> 49</span><span class="comment"> window *is* minimised and act accordingly}</span></pre>
<pre class="line"><span class="linenum"> 50</span><span class="space"> </span><span class="kwd">if</span><span class="space"> </span><span class="ident">IsIconic</span><span class="sym">(</span><span class="ident">Application</span><span class="sym">.</span><span class="ident">Handle</span><span class="sym">)</span><span class="space"> </span><span class="kwd">then</span></pre>
<pre class="line"><span class="linenum"> 51</span><span class="space"> </span><span class="comment">{minimised - write that state}</span></pre>
<pre class="line"><span class="linenum"> 52</span><span class="space"> </span><span class="ident">State</span><span class="space"> </span><span class="sym">:=</span><span class="space"> </span><span class="ident">Ord</span><span class="sym">(</span><span class="ident">wsMinimized</span><span class="sym">)</span></pre>
<pre class="line"><span class="linenum"> 53</span><span class="space"> </span><span class="kwd">else</span></pre>
<pre class="line"><span class="linenum"> 54</span><span class="space"> </span><span class="comment">{not minimised - we can rely on window state</span></pre>
<pre class="line"><span class="linenum"> 55</span><span class="comment"> of form}</span></pre>
<pre class="line"><span class="linenum"> 56</span><span class="space"> </span><span class="ident">State</span><span class="space"> </span><span class="sym">:=</span><span class="space"> </span><span class="ident">Ord</span><span class="sym">(</span><span class="ident">Self</span><span class="sym">.</span><span class="ident">WindowState</span><span class="sym">)</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 57</span><span class="space"> </span><span class="ident">Reg</span><span class="sym">.</span><span class="ident">WriteInteger</span><span class="sym">(</span><span class="str">'State'</span><span class="sym">,</span><span class="space"> </span><span class="ident">State</span><span class="sym">)</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 58</span><span class="space"> </span><span class="kwd">finally</span></pre>
<pre class="line"><span class="linenum"> 59</span><span class="space"> </span><span class="ident">Reg</span><span class="sym">.</span><span class="ident">Free</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 60</span><span class="space"> </span><span class="kwd">end</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 61</span><span class="kwd">end</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 62</span><span class="space"> </span></pre>
<pre class="line"><span class="linenum"> 63</span><span class="kwd">procedure</span><span class="space"> </span><span class="ident">TForm1</span><span class="sym">.</span><span class="ident">FormCreate</span><span class="sym">(</span><span class="ident">Sender</span><span class="sym">:</span><span class="space"> </span><span class="ident">TObject</span><span class="sym">)</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 64</span><span class="kwd">var</span></pre>
<pre class="line"><span class="linenum"> 65</span><span class="space"> </span><span class="ident">Reg</span><span class="sym">:</span><span class="space"> </span><span class="ident">TRegistry</span><span class="sym">;</span><span class="space"> </span><span class="comment">// the registry</span></pre>
<pre class="line"><span class="linenum"> 66</span><span class="space"> </span><span class="ident">State</span><span class="sym">:</span><span class="space"> </span><span class="ident">Integer</span><span class="sym">;</span><span class="space"> </span><span class="comment">// state of window</span></pre>
<pre class="line"><span class="linenum"> 67</span><span class="kwd">begin</span></pre>
<pre class="line"><span class="linenum"> 68</span><span class="space"> </span><span class="ident">Reg</span><span class="space"> </span><span class="sym">:=</span><span class="space"> </span><span class="ident">TRegistry</span><span class="sym">.</span><span class="ident">Create</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 69</span><span class="space"> </span><span class="kwd">try</span></pre>
<pre class="line"><span class="linenum"> 70</span><span class="space"> </span><span class="comment">// Open required key - exit if it doesn't exist</span></pre>
<pre class="line"><span class="linenum"> 71</span><span class="space"> </span><span class="ident">Reg</span><span class="sym">.</span><span class="ident">RootKey</span><span class="space"> </span><span class="sym">:=</span><span class="space"> </span><span class="ident">HKEY_CURRENT_USER</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 72</span><span class="space"> </span><span class="kwd">if</span><span class="space"> </span><span class="kwd">not</span><span class="space"> </span><span class="ident">Reg</span><span class="sym">.</span><span class="ident">OpenKey</span><span class="sym">(</span><span class="ident">CRegKey</span><span class="sym">,</span><span class="space"> </span><span class="ident">False</span><span class="sym">)</span><span class="space"> </span><span class="kwd">then</span><span class="space"> </span><span class="ident">Exit</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 73</span><span class="space"> </span><span class="comment">// Read the window size and position</span></pre>
<pre class="line"><span class="linenum"> 74</span><span class="space"> </span><span class="comment">// - designed form sizes are defaults</span></pre>
<pre class="line"><span class="linenum"> 75</span><span class="space"> </span><span class="ident">Self</span><span class="sym">.</span><span class="ident">Width</span><span class="space"> </span><span class="sym">:=</span><span class="space"> </span><span class="ident">ReadIntFromReg</span><span class="sym">(</span><span class="ident">Reg</span><span class="sym">,</span><span class="space"> </span><span class="str">'Width'</span><span class="sym">,</span><span class="space"> </span><span class="ident">Self</span><span class="sym">.</span><span class="ident">Width</span><span class="sym">)</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 76</span><span class="space"> </span><span class="ident">Self</span><span class="sym">.</span><span class="ident">Height</span><span class="space"> </span><span class="sym">:=</span><span class="space"> </span><span class="ident">ReadIntFromReg</span><span class="sym">(</span><span class="ident">Reg</span><span class="sym">,</span><span class="space"> </span><span class="str">'Height'</span><span class="sym">,</span><span class="space"> </span><span class="ident">Self</span><span class="sym">.</span><span class="ident">Height</span><span class="sym">)</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 77</span><span class="space"> </span><span class="ident">Self</span><span class="sym">.</span><span class="ident">Left</span><span class="space"> </span><span class="sym">:=</span><span class="space"> </span><span class="ident">ReadIntFromReg</span><span class="sym">(</span><span class="ident">Reg</span><span class="sym">,</span><span class="space"> </span><span class="str">'Left'</span><span class="sym">,</span><span class="space"> </span><span class="ident">Self</span><span class="sym">.</span><span class="ident">Left</span><span class="sym">)</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 78</span><span class="space"> </span><span class="ident">Self</span><span class="sym">.</span><span class="ident">Top</span><span class="space"> </span><span class="sym">:=</span><span class="space"> </span><span class="ident">ReadIntFromReg</span><span class="sym">(</span><span class="ident">Reg</span><span class="sym">,</span><span class="space"> </span><span class="str">'Top'</span><span class="sym">,</span><span class="space"> </span><span class="ident">Self</span><span class="sym">.</span><span class="ident">Top</span><span class="sym">)</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 79</span><span class="space"> </span><span class="comment">// Now get window state and restore</span></pre>
<pre class="line"><span class="linenum"> 80</span><span class="space"> </span><span class="ident">State</span><span class="space"> </span><span class="sym">:=</span><span class="space"> </span><span class="ident">ReadIntFromReg</span><span class="sym">(</span><span class="ident">Reg</span><span class="sym">,</span><span class="space"> </span><span class="str">'State'</span><span class="sym">,</span><span class="space"> </span><span class="ident">Ord</span><span class="sym">(</span><span class="ident">wsNormal</span><span class="sym">)</span><span class="sym">)</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 81</span><span class="space"> </span><span class="comment">{check if window was minimised - we have special</span></pre>
<pre class="line"><span class="linenum"> 82</span><span class="comment"> processing for minimised state since Delphi</span></pre>
<pre class="line"><span class="linenum"> 83</span><span class="comment"> doesn't minimise windows - it uses application</span></pre>
<pre class="line"><span class="linenum"> 84</span><span class="comment"> window instead}</span></pre>
<pre class="line"><span class="linenum"> 85</span><span class="space"> </span><span class="kwd">if</span><span class="space"> </span><span class="ident">State</span><span class="space"> </span><span class="sym">=</span><span class="space"> </span><span class="ident">Ord</span><span class="sym">(</span><span class="ident">wsMinimized</span><span class="sym">)</span><span class="space"> </span><span class="kwd">then</span></pre>
<pre class="line"><span class="linenum"> 86</span><span class="space"> </span><span class="kwd">begin</span></pre>
<pre class="line"><span class="linenum"> 87</span><span class="space"> </span><span class="comment">{we need to set visible true else form won't</span></pre>
<pre class="line"><span class="linenum"> 88</span><span class="comment"> restore properly - but this causes a brief</span></pre>
<pre class="line"><span class="linenum"> 89</span><span class="comment"> display of form.</span></pre>
<pre class="line"><span class="linenum"> 90</span><span class="comment"> Any ideas on how to stop this?}</span></pre>
<pre class="line"><span class="linenum"> 91</span><span class="space"> </span><span class="ident">Self</span><span class="sym">.</span><span class="ident">Visible</span><span class="space"> </span><span class="sym">:=</span><span class="space"> </span><span class="ident">True</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 92</span><span class="space"> </span><span class="ident">Application</span><span class="sym">.</span><span class="ident">Minimize</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 93</span><span class="space"> </span><span class="kwd">end</span></pre>
<pre class="line"><span class="linenum"> 94</span><span class="space"> </span><span class="kwd">else</span></pre>
<pre class="line"><span class="linenum"> 95</span><span class="space"> </span><span class="ident">Self</span><span class="sym">.</span><span class="ident">WindowState</span><span class="space"> </span><span class="sym">:=</span><span class="space"> </span><span class="ident">TWindowState</span><span class="sym">(</span><span class="ident">State</span><span class="sym">)</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 96</span><span class="space"> </span><span class="kwd">finally</span></pre>
<pre class="line"><span class="linenum"> 97</span><span class="space"> </span><span class="ident">Reg</span><span class="sym">.</span><span class="ident">Free</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 98</span><span class="space"> </span><span class="kwd">end</span><span class="sym">;</span></pre>
<pre class="line"><span class="linenum"> 99</span><span class="kwd">end</span><span class="sym">;</span></pre>
</div>
<div class="caption">Listing 1</div>
</div>
</section>
<section id="example">
<h2>Worked Example</h2>
<p>A demo project that demonstrates what we've described in this article can be found on 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-04">article-04</a></code> sub-directory. Alternatively download a zip file containing all the 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>
<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-04/LICENSE.md">LICENSE.md</a> file for licensing details.</p>
</div>
</section>
<section id="component">
<h2>Component</h2>
<p>My <a href="/software/wdwstate">TPJRegWdwState component</a> encapsulates all this functionality on behalf of the form that owns it. A sister component, <var>TPJWdwState</var>, is included that works with ini files rather than the registry.</p>
</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 #4".</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>