]>
Commit | Line | Data |
---|---|---|
a660d684 KB |
1 | \section{The wxWindows resource system}\label{resourceformats} |
2 | ||
f6bcfd97 | 3 | wxWindows has an optional {\it resource file} facility, |
a660d684 KB |
4 | which allows separation of dialog, menu, bitmap and icon specifications |
5 | from the application code. | |
6 | ||
7 | It is similar in principle to the Windows resource file (whose ASCII form is | |
8 | suffixed .RC and whose binary form is suffixed .RES). The wxWindows resource | |
9 | file is currently ASCII-only, suffixed .WXR. Note that under Windows, | |
10 | the .WXR file does not {\it replace} the native Windows resource file, | |
11 | it merely supplements it. There is no existing native resource format in X | |
12 | (except for the defaults file, which has limited expressive power). | |
13 | ||
a660d684 KB |
14 | For details of functions for manipulating resource files and loading |
15 | user interface elements, see \helpref{wxWindows resource functions}{resourcefuncs}. | |
16 | ||
f6bcfd97 BP |
17 | You can use Dialog Editor to create resource files. Unfortunately neither |
18 | Dialog Editor nor the .WXR format currently cover all wxWindows controls; | |
19 | some are missing, such as wxSpinCtrl, wxSpinButton, wxListCtrl, wxTreeCtrl and others. | |
20 | ||
21 | Note that in later versions of wxWindows, this resource format will be replaced | |
22 | by XML specifications that can also include sizers. | |
23 | ||
a660d684 KB |
24 | \subsection{The format of a .WXR file} |
25 | ||
f6bcfd97 | 26 | A wxWindows resource file may look a little odd at first. It is C++ |
a660d684 | 27 | compatible, comprising mostly of static string variable declarations with |
f6bcfd97 | 28 | wxExpr syntax within the string. |
a660d684 KB |
29 | |
30 | Here's a sample .WXR file: | |
31 | ||
32 | \begin{verbatim} | |
33 | /* | |
34 | * wxWindows Resource File | |
a660d684 KB |
35 | * |
36 | */ | |
37 | ||
38 | #include "noname.ids" | |
39 | ||
f6bcfd97 BP |
40 | static char *my_resource = "bitmap(name = 'my_resource',\ |
41 | bitmap = ['myproject', wxBITMAP_TYPE_BMP_RESOURCE, 'WINDOWS'],\ | |
42 | bitmap = ['myproject.xpm', wxBITMAP_TYPE_XPM, 'X'])."; | |
a660d684 KB |
43 | |
44 | static char *menuBar11 = "menu(name = 'menuBar11',\ | |
45 | menu = \ | |
46 | [\ | |
47 | ['&File', 1, '', \ | |
48 | ['&Open File', 2, 'Open a file'],\ | |
49 | ['&Save File', 3, 'Save a file'],\ | |
50 | [],\ | |
51 | ['E&xit', 4, 'Exit program']\ | |
52 | ],\ | |
53 | ['&Help', 5, '', \ | |
54 | ['&About', 6, 'About this program']\ | |
55 | ]\ | |
56 | ])."; | |
57 | ||
58 | static char *project_resource = "icon(name = 'project_resource',\ | |
59 | icon = ['project', wxBITMAP_TYPE_ICO_RESOURCE, 'WINDOWS'],\ | |
60 | icon = ['project_data', wxBITMAP_TYPE_XBM, 'X'])."; | |
61 | ||
62 | static char *panel3 = "dialog(name = 'panel3',\ | |
63 | style = '',\ | |
64 | title = 'untitled',\ | |
65 | button_font = [14, 'wxSWISS', 'wxNORMAL', 'wxBOLD', 0],\ | |
66 | label_font = [10, 'wxSWISS', 'wxNORMAL', 'wxNORMAL', 0],\ | |
67 | x = 0, y = 37, width = 292, height = 164,\ | |
f6bcfd97 BP |
68 | control = [1000, wxButton, 'OK', '', 'button5', 23, 34, -1, -1, 'my_resource'],\ |
69 | control = [1001, wxStaticText, 'A Label', '', 'message7', 166, 61, -1, -1, 'my_resource'],\ | |
70 | control = [1002, wxTextCtrl, 'Text', 'wxTE_MULTITEXT', 'text8', 24, 110, -1, -1])."; | |
a660d684 KB |
71 | \end{verbatim} |
72 | ||
73 | As you can see, C++-style comments are allowed, and apparently include files | |
74 | are supported too: but this is a special case, where the included file | |
75 | is a file of defines shared by the C++ application code and resource file | |
76 | to relate identifiers (such as FILE\_OPEN) to integers. | |
77 | ||
f6bcfd97 | 78 | Each {\it resource object} is of standard \helpref{wxExpr}{wxexpr} syntax, that is, |
a660d684 KB |
79 | an object name such as {\bf dialog} or {\bf icon}, then an open |
80 | parenthesis, a list of comma-delimited attribute/value pairs, a closing | |
81 | parenthesis, and a full stop. Backslashes are required to escape newlines, | |
82 | for the benefit of C++ syntax. If double quotation marks are used to | |
83 | delimit strings, they need to be escaped with backslash within a C++ string | |
f6bcfd97 | 84 | (so it is easier to use single quotation marks instead). |
a660d684 | 85 | |
f6bcfd97 | 86 | \normalbox{{\it A note on string syntax:} A string that begins with |
a660d684 KB |
87 | an alphabetic character, and contains only alphanumeric characters, |
88 | hyphens and underscores, need not be quoted at all. Single quotes and double | |
89 | quotes may be used to delimit more complex strings. In fact, single-quoted | |
90 | and no-quoted strings are actually called {\it words}, but are treated | |
91 | as strings for the purpose of the resource system.} | |
92 | ||
93 | A resource file like this is typically included in the application main file, | |
94 | as if it were a normal C++ file. This eliminates the need for a separate | |
95 | resource file to be distributed alongside the executable. However, the | |
f6bcfd97 BP |
96 | resource file can be dynamically loaded if desired (useful for non-C++ |
97 | languages such as Python). | |
a660d684 KB |
98 | |
99 | Once included, the resources need to be `parsed' (interpreted), because | |
100 | so far the data is just a number of static string variables. The function\rtfsp | |
101 | {\bf ::wxResourceParseData} is called early on in initialization of the application | |
102 | (usually in {\bf wxApp::OnInit}) with a variable as argument. This may need to be | |
103 | called a number of times, one for each variable. However, more than one | |
104 | resource `object' can be stored in one string variable at a time, so you can | |
105 | get all your resources into one variable if you want to. | |
106 | ||
107 | {\bf ::wxResourceParseData} parses the contents of the resource, ready for use | |
108 | by functions such as {\bf ::wxResourceCreateBitmap} and {\bf wxPanel::LoadFromResource}. | |
109 | ||
110 | If a wxWindows resource object (such as a bitmap resource) refers to a | |
f6bcfd97 BP |
111 | C++ data structure, such as static XPM data, a further call ({\bf ::wxResourceRegisterBitmapData}) needs |
112 | to be made on initialization to tell | |
a660d684 KB |
113 | wxWindows about this data. The wxWindows resource object will refer to a |
114 | string identifier, such as `project\_data' in the example file above. | |
115 | This identifier will be looked up in a table to get the C++ static data | |
116 | to use for the bitmap or icon. | |
117 | ||
118 | In the C++ fragment below, the WXR resource file is included, | |
119 | and appropriate resource initialization is carried out in {\bf OnInit}. | |
120 | Note that at this stage, no actual wxWindows dialogs, menus, bitmaps or | |
121 | icons are created; their `templates' are merely being set up for later | |
122 | use. | |
123 | ||
124 | \begin{verbatim} | |
125 | /* | |
f6bcfd97 BP |
126 | * File: project.cpp |
127 | * Purpose: main application module | |
a660d684 KB |
128 | */ |
129 | ||
f6bcfd97 BP |
130 | #include "wx/wx.h" |
131 | #include "project.h" | |
a660d684 KB |
132 | |
133 | // Includes the dialog, menu etc. resources | |
f6bcfd97 | 134 | #include "project.wxr" |
a660d684 | 135 | |
f6bcfd97 BP |
136 | // Includes XPM data |
137 | #include "project.xpm" | |
a660d684 | 138 | |
f6bcfd97 | 139 | IMPLEMENT_APP(AppClass) |
a660d684 KB |
140 | |
141 | // Called to initialize the program | |
f6bcfd97 | 142 | bool AppClass::OnInit() |
a660d684 | 143 | { |
a660d684 | 144 | wxResourceRegisterBitmapData("project_data", project_bits, project_width, project_height); |
f6bcfd97 | 145 | |
a660d684 | 146 | wxResourceParseData(menuBar11); |
f6bcfd97 | 147 | wxResourceParseData(my_resource); |
a660d684 KB |
148 | wxResourceParseData(project_resource); |
149 | wxResourceParseData(panel3); | |
150 | ... | |
f6bcfd97 BP |
151 | |
152 | return TRUE; | |
a660d684 KB |
153 | } |
154 | \end{verbatim} | |
155 | ||
f6bcfd97 BP |
156 | The following code shows a dialog: |
157 | ||
158 | \begin{verbatim} | |
159 | // project.wxr contains dialog1 | |
160 | MyDialog *dialog = new MyDialog; | |
161 | if (dialog->LoadFromResource(this, "dialog1")) | |
162 | { | |
163 | wxTextCtrl *text = (wxTextCtrl *)wxFindWindowByName("text3", dialog); | |
164 | if (text) | |
165 | text->SetValue("wxWindows resource demo"); | |
166 | dialog->ShowModal(); | |
167 | } | |
168 | dialog->Destroy(); | |
169 | \end{verbatim} | |
170 | ||
171 | Please see also the resource sample. | |
a660d684 KB |
172 | |
173 | \subsection{Dialog resource format} | |
174 | ||
175 | A dialog resource object may be used for either panels or dialog boxes, and | |
176 | consists of the following attributes. In the following, a {\it font specification}\rtfsp | |
177 | is a list consisting of point size, family, style, weight, underlined, optional facename. | |
178 | ||
179 | \begin{twocollist}\itemsep=0pt | |
180 | \twocolitemruled{Attribute}{Value} | |
f6bcfd97 | 181 | \twocolitem{id}{The integer identifier of the resource.} |
a660d684 KB |
182 | \twocolitem{name}{The name of the resource.} |
183 | \twocolitem{style}{Optional dialog box or panel window style.} | |
184 | \twocolitem{title}{The title of the dialog box (unused if a panel).}. | |
185 | \twocolitem{modal}{Whether modal: 1 if modal, 0 if modeless, absent if a panel resource.} | |
e7240349 GT |
186 | \twocolitem{use\_dialog\_units}{If 1, use dialog units (dependent on the dialog font size) for control sizes and positions.} |
187 | \twocolitem{use\_system\_defaults}{If 1, override colours and fonts to use system settings instead.} | |
a660d684 KB |
188 | \twocolitem{button\_font}{The font used for control buttons: a list comprising point size (integer), |
189 | family (string), font style (string), font weight (string) and underlining (0 or 1).} | |
190 | \twocolitem{label\_font}{The font used for control labels: a list comprising point size (integer), | |
f6bcfd97 | 191 | family (string), font style (string), font weight (string) and underlining (0 or 1). Now obsolete; use button\_font instead.} |
a660d684 KB |
192 | \twocolitem{x}{The x position of the dialog or panel.} |
193 | \twocolitem{y}{The y position of the dialog or panel.} | |
194 | \twocolitem{width}{The width of the dialog or panel.} | |
195 | \twocolitem{height}{The height of the dialog or panel.} | |
f6bcfd97 BP |
196 | \twocolitem{background\_colour}{The background colour of the dialog or panel.} |
197 | \twocolitem{label\_colour}{The default label colour for the children of the dialog or panel. Now obsolete; use button\_colour instead.} | |
198 | \twocolitem{button\_colour}{The default button text colour for the children of the dialog or panel.} | |
a660d684 KB |
199 | \end{twocollist} |
200 | ||
201 | Then comes zero or more attributes named `control' for each control | |
202 | (panel item) on the dialog or panel. The value is a list of further | |
203 | elements. In the table below, the names in the first column correspond to | |
204 | the first element of the value list, and the second column details the | |
f6bcfd97 BP |
205 | remaining elements of the list. Note that titles for some controls are obsolete |
206 | (they don't have titles), but the syntax is retained for backward compatibility. | |
a660d684 KB |
207 | |
208 | \begin{twocollist}\itemsep=0pt | |
209 | \twocolitemruled{Control}{Values} | |
f6bcfd97 BP |
210 | \twocolitem{wxButton}{id (integer), title (string), window style (string), name (string), x, y, width, height, button bitmap resource (optional string), button font spec} |
211 | \twocolitem{wxCheckBox}{id (integer), title (string), window style (string), name (string), x, y, width, height, default value (optional integer, 1 or 0), label font spec} | |
212 | \twocolitem{wxChoice}{id (integer), title (string), window style (string), name (string), x, y, width, height, values (optional list of strings), label font spec, button font spec} | |
213 | \twocolitem{wxComboBox}{id (integer), title (string), window style (string), name (string), x, y, width, height, default text value, values (optional list of strings), label font spec, button font spec} | |
214 | \twocolitem{wxGauge}{id (integer), title (string), window style (string), name (string), x, y, width, height, value (optional integer), range (optional integer), label font spec, button font spec} | |
215 | \twocolitem{wxStaticBox}{id (integer), title (string), window style (string), name (string), x, y, width, height, label font spec} | |
216 | \twocolitem{wxListBox}{id (integer), title (string), window style (string), name (string), x, y, width, height, values (optional list of strings), multiple (optional string, wxSINGLE or wxMULTIPLE), | |
a660d684 | 217 | label font spec, button font spec} |
f6bcfd97 BP |
218 | \twocolitem{wxStaticText}{id (integer), title (string), window style (string), name (string), x, y, width, height, message bitmap resource (optional string), label font spec} |
219 | \twocolitem{wxRadioBox}{id (integer), title (string), window style (string), name (string), x, y, width, height, values (optional list of strings), number of rows or cols, | |
a660d684 | 220 | label font spec, button font spec} |
f6bcfd97 BP |
221 | \twocolitem{wxRadioButton}{id (integer), title (string), window style (string), name (string), x, y, width, height, default value (optional integer, 1 or 0), label font spec} |
222 | \twocolitem{wxScrollBar}{id (integer), title (string), window style (string), name (string), x, y, width, height, value (optional integer), | |
a660d684 | 223 | page length (optional integer), object length (optional integer), view length (optional integer)} |
f6bcfd97 | 224 | \twocolitem{wxSlider}{id (integer), title (string), window style (string), name (string), x, y, width, height, value (optional integer), minimum (optional integer), maximum (optional integer), |
a660d684 | 225 | label font spec, button font spec} |
f6bcfd97 | 226 | \twocolitem{wxTextCtrl}{id (integer), title (string), window style (string), name (string), x, y, width, height, default value (optional string), |
a660d684 KB |
227 | label font spec, button font spec} |
228 | \end{twocollist} | |
229 | ||
230 | \subsection{Menubar resource format} | |
231 | ||
232 | A menubar resource object consists of the following attributes. | |
233 | ||
234 | \begin{twocollist}\itemsep=0pt | |
235 | \twocolitemruled{Attribute}{Value} | |
236 | \twocolitem{name}{The name of the menubar resource.} | |
237 | \twocolitem{menu}{A list containing all the menus, as detailed below.} | |
238 | \end{twocollist} | |
239 | ||
240 | The value of the {\bf menu} attribute is a list of menu item specifications, where each menu | |
241 | item specification is itself a list comprising: | |
242 | ||
243 | \begin{itemize}\itemsep=0pt | |
244 | \item title (a string) | |
245 | \item menu item identifier (a string or non-zero integer, see below) | |
246 | \item help string (optional) | |
247 | \item 0 or 1 for the `checkable' parameter (optional) | |
248 | \item optionally, further menu item specifications if this item is a pulldown menu. | |
249 | \end{itemize} | |
250 | ||
251 | If the menu item specification is the empty list ([]), this is interpreted as a menu separator. | |
252 | ||
253 | If further (optional) information is associated with each menu item in a future release of wxWindows, | |
254 | it will be placed after the help string and before the optional pulldown menu specifications. | |
255 | ||
256 | Note that the menu item identifier must be an integer if the resource is being | |
257 | included as C++ code and then parsed on initialisation. Unfortunately,\rtfsp | |
258 | \verb$#$define substitution is not performed inside strings, and | |
259 | therefore the program cannot know the mapping. However, if the .WXR file | |
260 | is being loaded dynamically, wxWindows will attempt to replace string | |
261 | identifiers with \verb$#$defined integers, because it is able to parse | |
262 | the included \verb$#$defines. | |
263 | ||
264 | \subsection{Bitmap resource format} | |
265 | ||
266 | A bitmap resource object consists of a name attribute, and one or more {\bf bitmap} attributes. | |
267 | There can be more than one of these to allow specification of bitmaps that are optimum for the | |
268 | platform and display. | |
269 | ||
270 | \begin{itemize}\itemsep=0pt | |
271 | \item Bitmap name or filename. | |
272 | \item Type of bitmap; for example, wxBITMAP\_TYPE\_BMP\_RESOURCE. See class reference under {\bf wxBitmap} for | |
273 | a full list). | |
274 | \item Platform this bitmap is valid for; one of WINDOWS, X, MAC and ANY. | |
275 | \item Number of colours (optional). | |
276 | \item X resolution (optional). | |
277 | \item Y resolution (optional). | |
278 | \end{itemize} | |
279 | ||
280 | \subsection{Icon resource format} | |
281 | ||
282 | An icon resource object consists of a name attribute, and one or more {\bf icon} attributes. | |
283 | There can be more than one of these to allow specification of icons that are optimum for the | |
284 | platform and display. | |
285 | ||
286 | \begin{itemize}\itemsep=0pt | |
287 | \item Icon name or filename. | |
288 | \item Type of icon; for example, wxBITMAP\_TYPE\_ICO\_RESOURCE. See class reference under {\bf wxBitmap} for | |
289 | a full list). | |
290 | \item Platform this bitmap is valid for; one of WINDOWS, X, MAC and ANY. | |
291 | \item Number of colours (optional). | |
292 | \item X resolution (optional). | |
293 | \item Y resolution (optional). | |
294 | \end{itemize} | |
295 | ||
a660d684 KB |
296 | \subsection{Resource format design issues} |
297 | ||
298 | The .WXR file format is a recent addition and subject to change. | |
299 | The use of an ASCII resource file format may seem rather inefficient, but this | |
300 | choice has a number of advantages: | |
301 | ||
302 | \begin{itemize}\itemsep=0pt | |
303 | \item Since it is C++ compatible, it can be included into an application's source code, | |
304 | eliminating the problems associated with distributing a separate resource file | |
305 | with the executable. However, it can also be loaded dynamically from a file, which will be required | |
306 | for non-C++ programs that use wxWindows. | |
307 | \item No extra binary file format and separate converter need be maintained for the wxWindows project | |
308 | (although others are welcome to add the equivalent of the Windows `rc' resource | |
309 | parser and a binary format). | |
310 | \item It would be difficult to append a binary resource component onto an executable | |
311 | in a portable way. | |
f6bcfd97 BP |
312 | \item The file format is essentially the \helpref{wxExpr}{wxexpr} object format, for which |
313 | a parser already exists, so parsing is easy. For those programs that use wxExpr | |
a660d684 KB |
314 | anyway, the size overhead of the parser is minimal. |
315 | \end{itemize} | |
316 | ||
317 | The disadvantages of the approach include: | |
318 | ||
319 | \begin{itemize}\itemsep=0pt | |
320 | \item Parsing adds a small execution overhead to program initialization. | |
321 | \item Under 16-bit Windows especially, global data is at a premium. | |
322 | Using a .RC resource table for some wxWindows resource data may be a partial solution, | |
323 | although .RC strings are limited to 255 characters. | |
324 | \item Without a resource preprocessor, it is not possible to substitute integers | |
325 | for identifiers (so menu identifiers have to be written as integers in the resource | |
326 | object, in addition to providing \verb$#$defines for application code convenience). | |
327 | \end{itemize} | |
328 | ||
329 | \subsection{Compiling the resource system} | |
330 | ||
9a05fd8d | 331 | To enable the resource system, set {\bf wxUSE\_WX\_RESOURCES} to 1 in setup.h. |
a660d684 | 332 |