]>
Commit | Line | Data |
---|---|---|
a660d684 KB |
1 | \section{The wxWindows resource system}\label{resourceformats} |
2 | ||
3 | From version 1.61, wxWindows has an optional {\it resource file} facility, | |
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 | ||
14 | Using wxWindows resources for panels and dialogs has an effect on how | |
15 | you deal with panel item callbacks: you can't specify a callback function in | |
16 | a resource file, so how do you achieve the same effect as with programmatic | |
17 | panel construction? The solution is similar to that adopted by Windows, which | |
18 | is to use the {\it parent} panel or dialog to intercept user events. | |
19 | ||
20 | From 1.61, wxWindows routes panel item events that do not have a callback | |
21 | to the \helpref{OnCommand}{wxwindowoncommand} member of the panel (or dialog). So, to use | |
22 | panel or dialog resources, you need to derive a new class and override the | |
23 | default (empty) OnCommand member. The first argument is a reference | |
24 | to a wxWindow, and the second is a reference to a wxCommandEvent. Check the | |
25 | name of the panel item that's generating an event by using the \helpref{wxWindow::GetName}{wxwindowgetname}\rtfsp | |
26 | function and a string comparison function such as \helpref{wxStringEq}{wxstringeq}. | |
27 | You may need to cast the reference to an appropriate specific type to perform | |
28 | some operations. | |
29 | ||
30 | To obtain a pointer to a panel item when you only have the name (for example, | |
31 | when you need to set a value of a text item from outside of the {\bf OnCommand} function), | |
32 | use the function \helpref{wxFindWindowByName}{wxfindwindowbyname}. | |
33 | ||
34 | For details of functions for manipulating resource files and loading | |
35 | user interface elements, see \helpref{wxWindows resource functions}{resourcefuncs}. | |
36 | ||
37 | \subsection{The format of a .WXR file} | |
38 | ||
39 | A wxWindows resource file may look a little odd at first. It's C++ | |
40 | compatible, comprising mostly of static string variable declarations with | |
41 | PrologIO syntax within the string. | |
42 | ||
43 | Here's a sample .WXR file: | |
44 | ||
45 | \begin{verbatim} | |
46 | /* | |
47 | * wxWindows Resource File | |
48 | * Written by wxBuilder | |
49 | * | |
50 | */ | |
51 | ||
52 | #include "noname.ids" | |
53 | ||
54 | static char *aiai_resource = "bitmap(name = 'aiai_resource',\ | |
55 | bitmap = ['aiai', wxBITMAP_TYPE_BMP_RESOURCE, 'WINDOWS'],\ | |
56 | bitmap = ['aiai.xpm', wxBITMAP_TYPE_XPM, 'X'])."; | |
57 | ||
58 | static char *menuBar11 = "menu(name = 'menuBar11',\ | |
59 | menu = \ | |
60 | [\ | |
61 | ['&File', 1, '', \ | |
62 | ['&Open File', 2, 'Open a file'],\ | |
63 | ['&Save File', 3, 'Save a file'],\ | |
64 | [],\ | |
65 | ['E&xit', 4, 'Exit program']\ | |
66 | ],\ | |
67 | ['&Help', 5, '', \ | |
68 | ['&About', 6, 'About this program']\ | |
69 | ]\ | |
70 | ])."; | |
71 | ||
72 | static char *project_resource = "icon(name = 'project_resource',\ | |
73 | icon = ['project', wxBITMAP_TYPE_ICO_RESOURCE, 'WINDOWS'],\ | |
74 | icon = ['project_data', wxBITMAP_TYPE_XBM, 'X'])."; | |
75 | ||
76 | static char *panel3 = "dialog(name = 'panel3',\ | |
77 | style = '',\ | |
78 | title = 'untitled',\ | |
79 | button_font = [14, 'wxSWISS', 'wxNORMAL', 'wxBOLD', 0],\ | |
80 | label_font = [10, 'wxSWISS', 'wxNORMAL', 'wxNORMAL', 0],\ | |
81 | x = 0, y = 37, width = 292, height = 164,\ | |
82 | control = [wxButton, 'OK', '', 'button5', 23, 34, -1, -1, 'aiai_resource'],\ | |
83 | control = [wxMessage, 'A Label', '', 'message7', 166, 61, -1, -1, 'aiai_resource'],\ | |
84 | control = [wxText, 'Text', 'wxVERTICAL_LABEL', 'text8', 24, 110, -1, -1])."; | |
85 | \end{verbatim} | |
86 | ||
87 | As you can see, C++-style comments are allowed, and apparently include files | |
88 | are supported too: but this is a special case, where the included file | |
89 | is a file of defines shared by the C++ application code and resource file | |
90 | to relate identifiers (such as FILE\_OPEN) to integers. | |
91 | ||
92 | Each {\it resource object} is of standard PrologIO syntax, that is, | |
93 | an object name such as {\bf dialog} or {\bf icon}, then an open | |
94 | parenthesis, a list of comma-delimited attribute/value pairs, a closing | |
95 | parenthesis, and a full stop. Backslashes are required to escape newlines, | |
96 | for the benefit of C++ syntax. If double quotation marks are used to | |
97 | delimit strings, they need to be escaped with backslash within a C++ string | |
98 | (so it's easier to use single quotation marks instead). | |
99 | ||
100 | \normalbox{{\it A note on PrologIO string syntax:} A string that begins with | |
101 | an alphabetic character, and contains only alphanumeric characters, | |
102 | hyphens and underscores, need not be quoted at all. Single quotes and double | |
103 | quotes may be used to delimit more complex strings. In fact, single-quoted | |
104 | and no-quoted strings are actually called {\it words}, but are treated | |
105 | as strings for the purpose of the resource system.} | |
106 | ||
107 | A resource file like this is typically included in the application main file, | |
108 | as if it were a normal C++ file. This eliminates the need for a separate | |
109 | resource file to be distributed alongside the executable. However, the | |
110 | resource file can be dynamically loaded if desired (for example by a non-C++ | |
111 | language such as CLIPS, Prolog or Python). | |
112 | ||
113 | Once included, the resources need to be `parsed' (interpreted), because | |
114 | so far the data is just a number of static string variables. The function\rtfsp | |
115 | {\bf ::wxResourceParseData} is called early on in initialization of the application | |
116 | (usually in {\bf wxApp::OnInit}) with a variable as argument. This may need to be | |
117 | called a number of times, one for each variable. However, more than one | |
118 | resource `object' can be stored in one string variable at a time, so you can | |
119 | get all your resources into one variable if you want to. | |
120 | ||
121 | {\bf ::wxResourceParseData} parses the contents of the resource, ready for use | |
122 | by functions such as {\bf ::wxResourceCreateBitmap} and {\bf wxPanel::LoadFromResource}. | |
123 | ||
124 | If a wxWindows resource object (such as a bitmap resource) refers to a | |
125 | C++ data structure, such as static XBM or XPM data, a further call ({\bf | |
126 | ::wxResourceRegisterBitmapData}) needs to be made on initialization to tell | |
127 | wxWindows about this data. The wxWindows resource object will refer to a | |
128 | string identifier, such as `project\_data' in the example file above. | |
129 | This identifier will be looked up in a table to get the C++ static data | |
130 | to use for the bitmap or icon. | |
131 | ||
132 | In the C++ fragment below, the WXR resource file is included, | |
133 | and appropriate resource initialization is carried out in {\bf OnInit}. | |
134 | Note that at this stage, no actual wxWindows dialogs, menus, bitmaps or | |
135 | icons are created; their `templates' are merely being set up for later | |
136 | use. | |
137 | ||
138 | \begin{verbatim} | |
139 | /* | |
140 | * File: noname.cc | |
141 | * Purpose: main application module, generated by wxBuilder. | |
142 | */ | |
143 | ||
144 | #include "wx.h" | |
145 | #include "wx_help.h" | |
146 | #include "noname.h" | |
147 | ||
148 | // Includes the dialog, menu etc. resources | |
149 | #include "noname.wxr" | |
150 | ||
151 | // Includes XBM data | |
152 | #include "project.xbm" | |
153 | ||
154 | // Declare an instance of the application: allows the program to start | |
155 | AppClass theApp; | |
156 | ||
157 | // Called to initialize the program | |
158 | wxFrame *AppClass::OnInit(void) | |
159 | { | |
160 | #ifdef wx_x | |
161 | wxResourceRegisterBitmapData("project_data", project_bits, project_width, project_height); | |
162 | #endif | |
163 | wxResourceParseData(menuBar11); | |
164 | wxResourceParseData(aiai_resource); | |
165 | wxResourceParseData(project_resource); | |
166 | wxResourceParseData(panel3); | |
167 | ... | |
168 | } | |
169 | \end{verbatim} | |
170 | ||
171 | ||
172 | \subsection{Dialog resource format} | |
173 | ||
174 | A dialog resource object may be used for either panels or dialog boxes, and | |
175 | consists of the following attributes. In the following, a {\it font specification}\rtfsp | |
176 | is a list consisting of point size, family, style, weight, underlined, optional facename. | |
177 | ||
178 | \begin{twocollist}\itemsep=0pt | |
179 | \twocolitemruled{Attribute}{Value} | |
180 | \twocolitem{name}{The name of the resource.} | |
181 | \twocolitem{style}{Optional dialog box or panel window style.} | |
182 | \twocolitem{title}{The title of the dialog box (unused if a panel).}. | |
183 | \twocolitem{modal}{Whether modal: 1 if modal, 0 if modeless, absent if a panel resource.} | |
184 | \twocolitem{button\_font}{The font used for control buttons: a list comprising point size (integer), | |
185 | family (string), font style (string), font weight (string) and underlining (0 or 1).} | |
186 | \twocolitem{label\_font}{The font used for control labels: a list comprising point size (integer), | |
187 | family (string), font style (string), font weight (string) and underlining (0 or 1).} | |
188 | \twocolitem{x}{The x position of the dialog or panel.} | |
189 | \twocolitem{y}{The y position of the dialog or panel.} | |
190 | \twocolitem{width}{The width of the dialog or panel.} | |
191 | \twocolitem{height}{The height of the dialog or panel.} | |
192 | \twocolitem{background\_colour}{The background colour of the dialog or panel. Only valid if the style includes wxUSER\_COLOURS.} | |
193 | \twocolitem{label\_colour}{The default label colour for the children of the dialog or panel. Only valid if the style includes wxUSER\_COLOURS.} | |
194 | \twocolitem{button\_colour}{The default button text colour for the children of the dialog or panel. Only valid if the style includes wxUSER\_COLOURS.} | |
195 | \twocolitem{label\_font}{Font spec} | |
196 | \twocolitem{button\_font}{Font spec} | |
197 | \end{twocollist} | |
198 | ||
199 | Then comes zero or more attributes named `control' for each control | |
200 | (panel item) on the dialog or panel. The value is a list of further | |
201 | elements. In the table below, the names in the first column correspond to | |
202 | the first element of the value list, and the second column details the | |
203 | remaining elements of the list. | |
204 | ||
205 | \begin{twocollist}\itemsep=0pt | |
206 | \twocolitemruled{Control}{Values} | |
207 | \twocolitem{wxButton}{title (string), window style (string), name (string), x, y, width, height, button bitmap resource (optional string), button font spec} | |
208 | \twocolitem{wxCheckBox}{title (string), window style (string), name (string), x, y, width, height, default value (optional integer, 1 or 0), label font spec} | |
209 | \twocolitem{wxChoice}{title (string), window style (string), name (string), x, y, width, height, values (optional list of strings), label font spec, button font spec} | |
210 | \twocolitem{wxComboBox}{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} | |
211 | \twocolitem{wxGauge}{title (string), window style (string), name (string), x, y, width, height, value (optional integer), range (optional integer), label font spec, button font spec} | |
212 | \twocolitem{wxGroupBox}{title (string), window style (string), name (string), x, y, width, height, label font spec} | |
213 | \twocolitem{wxListBox}{title (string), window style (string), name (string), x, y, width, height, values (optional list of strings), multiple (optional string, wxSINGLE or wxMULTIPLE), | |
214 | label font spec, button font spec} | |
215 | \twocolitem{wxMessage}{title (string), window style (string), name (string), x, y, width, height, message bitmap resource (optional string), label font spec} | |
216 | \twocolitem{wxMultiText}{title (string), window style (string), name (string), x, y, width, height, default value (optional string), | |
217 | label font spec, button font spec} | |
218 | \twocolitem{wxRadioBox}{title (string), window style (string), name (string), x, y, width, height, values (optional list of strings), number of rows or cols, | |
219 | label font spec, button font spec} | |
220 | \twocolitem{wxRadioButton}{title (string), window style (string), name (string), x, y, width, height, default value (optional integer, 1 or 0), label font spec} | |
221 | \twocolitem{wxScrollBar}{title (string), window style (string), name (string), x, y, width, height, value (optional integer), | |
222 | page length (optional integer), object length (optional integer), view length (optional integer)} | |
223 | \twocolitem{wxSlider}{title (string), window style (string), name (string), x, y, width, height, value (optional integer), minimum (optional integer), maximum (optional integer), | |
224 | label font spec, button font spec} | |
225 | \twocolitem{wxText}{title (string), window style (string), name (string), x, y, width, height, default value (optional string), | |
226 | label font spec, button font spec} | |
227 | \end{twocollist} | |
228 | ||
229 | \subsection{Menubar resource format} | |
230 | ||
231 | A menubar resource object consists of the following attributes. | |
232 | ||
233 | \begin{twocollist}\itemsep=0pt | |
234 | \twocolitemruled{Attribute}{Value} | |
235 | \twocolitem{name}{The name of the menubar resource.} | |
236 | \twocolitem{menu}{A list containing all the menus, as detailed below.} | |
237 | \end{twocollist} | |
238 | ||
239 | The value of the {\bf menu} attribute is a list of menu item specifications, where each menu | |
240 | item specification is itself a list comprising: | |
241 | ||
242 | \begin{itemize}\itemsep=0pt | |
243 | \item title (a string) | |
244 | \item menu item identifier (a string or non-zero integer, see below) | |
245 | \item help string (optional) | |
246 | \item 0 or 1 for the `checkable' parameter (optional) | |
247 | \item optionally, further menu item specifications if this item is a pulldown menu. | |
248 | \end{itemize} | |
249 | ||
250 | If the menu item specification is the empty list ([]), this is interpreted as a menu separator. | |
251 | ||
252 | If further (optional) information is associated with each menu item in a future release of wxWindows, | |
253 | it will be placed after the help string and before the optional pulldown menu specifications. | |
254 | ||
255 | Note that the menu item identifier must be an integer if the resource is being | |
256 | included as C++ code and then parsed on initialisation. Unfortunately,\rtfsp | |
257 | \verb$#$define substitution is not performed inside strings, and | |
258 | therefore the program cannot know the mapping. However, if the .WXR file | |
259 | is being loaded dynamically, wxWindows will attempt to replace string | |
260 | identifiers with \verb$#$defined integers, because it is able to parse | |
261 | the included \verb$#$defines. | |
262 | ||
263 | \subsection{Bitmap resource format} | |
264 | ||
265 | A bitmap resource object consists of a name attribute, and one or more {\bf bitmap} attributes. | |
266 | There can be more than one of these to allow specification of bitmaps that are optimum for the | |
267 | platform and display. | |
268 | ||
269 | \begin{itemize}\itemsep=0pt | |
270 | \item Bitmap name or filename. | |
271 | \item Type of bitmap; for example, wxBITMAP\_TYPE\_BMP\_RESOURCE. See class reference under {\bf wxBitmap} for | |
272 | a full list). | |
273 | \item Platform this bitmap is valid for; one of WINDOWS, X, MAC and ANY. | |
274 | \item Number of colours (optional). | |
275 | \item X resolution (optional). | |
276 | \item Y resolution (optional). | |
277 | \end{itemize} | |
278 | ||
279 | \subsection{Icon resource format} | |
280 | ||
281 | An icon resource object consists of a name attribute, and one or more {\bf icon} attributes. | |
282 | There can be more than one of these to allow specification of icons that are optimum for the | |
283 | platform and display. | |
284 | ||
285 | \begin{itemize}\itemsep=0pt | |
286 | \item Icon name or filename. | |
287 | \item Type of icon; for example, wxBITMAP\_TYPE\_ICO\_RESOURCE. See class reference under {\bf wxBitmap} for | |
288 | a full list). | |
289 | \item Platform this bitmap is valid for; one of WINDOWS, X, MAC and ANY. | |
290 | \item Number of colours (optional). | |
291 | \item X resolution (optional). | |
292 | \item Y resolution (optional). | |
293 | \end{itemize} | |
294 | ||
295 | ||
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. | |
312 | \item The file format is essentially the PrologIO object format, for which | |
313 | a parser already exists, so parsing is easy. For those programs that use PrologIO | |
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 | ||
331 | To enable the resource system, set {\bf USE\_WX\_RESOURCES} to 1 in wx\_setup.h. | |
332 | If your wxWindows makefile supports it, set the same name in the makefile to 1. | |
333 | ||
334 | You will also need to compile the PrologIO utility (not always the easiest | |
335 | task): you will need YACC, and LEX (or FLEX). DOS versions of these are | |
336 | available on the AIAI ftp site under /pub/wxwin/tools. | |
337 |