338 lines
16 KiB
TeX
338 lines
16 KiB
TeX
|
\section{The wxWindows resource system}\label{resourceformats}
|
||
|
|
||
|
From version 1.61, wxWindows has an optional {\it resource file} facility,
|
||
|
which allows separation of dialog, menu, bitmap and icon specifications
|
||
|
from the application code.
|
||
|
|
||
|
It is similar in principle to the Windows resource file (whose ASCII form is
|
||
|
suffixed .RC and whose binary form is suffixed .RES). The wxWindows resource
|
||
|
file is currently ASCII-only, suffixed .WXR. Note that under Windows,
|
||
|
the .WXR file does not {\it replace} the native Windows resource file,
|
||
|
it merely supplements it. There is no existing native resource format in X
|
||
|
(except for the defaults file, which has limited expressive power).
|
||
|
|
||
|
Using wxWindows resources for panels and dialogs has an effect on how
|
||
|
you deal with panel item callbacks: you can't specify a callback function in
|
||
|
a resource file, so how do you achieve the same effect as with programmatic
|
||
|
panel construction? The solution is similar to that adopted by Windows, which
|
||
|
is to use the {\it parent} panel or dialog to intercept user events.
|
||
|
|
||
|
From 1.61, wxWindows routes panel item events that do not have a callback
|
||
|
to the \helpref{OnCommand}{wxwindowoncommand} member of the panel (or dialog). So, to use
|
||
|
panel or dialog resources, you need to derive a new class and override the
|
||
|
default (empty) OnCommand member. The first argument is a reference
|
||
|
to a wxWindow, and the second is a reference to a wxCommandEvent. Check the
|
||
|
name of the panel item that's generating an event by using the \helpref{wxWindow::GetName}{wxwindowgetname}\rtfsp
|
||
|
function and a string comparison function such as \helpref{wxStringEq}{wxstringeq}.
|
||
|
You may need to cast the reference to an appropriate specific type to perform
|
||
|
some operations.
|
||
|
|
||
|
To obtain a pointer to a panel item when you only have the name (for example,
|
||
|
when you need to set a value of a text item from outside of the {\bf OnCommand} function),
|
||
|
use the function \helpref{wxFindWindowByName}{wxfindwindowbyname}.
|
||
|
|
||
|
For details of functions for manipulating resource files and loading
|
||
|
user interface elements, see \helpref{wxWindows resource functions}{resourcefuncs}.
|
||
|
|
||
|
\subsection{The format of a .WXR file}
|
||
|
|
||
|
A wxWindows resource file may look a little odd at first. It's C++
|
||
|
compatible, comprising mostly of static string variable declarations with
|
||
|
PrologIO syntax within the string.
|
||
|
|
||
|
Here's a sample .WXR file:
|
||
|
|
||
|
\begin{verbatim}
|
||
|
/*
|
||
|
* wxWindows Resource File
|
||
|
* Written by wxBuilder
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include "noname.ids"
|
||
|
|
||
|
static char *aiai_resource = "bitmap(name = 'aiai_resource',\
|
||
|
bitmap = ['aiai', wxBITMAP_TYPE_BMP_RESOURCE, 'WINDOWS'],\
|
||
|
bitmap = ['aiai.xpm', wxBITMAP_TYPE_XPM, 'X']).";
|
||
|
|
||
|
static char *menuBar11 = "menu(name = 'menuBar11',\
|
||
|
menu = \
|
||
|
[\
|
||
|
['&File', 1, '', \
|
||
|
['&Open File', 2, 'Open a file'],\
|
||
|
['&Save File', 3, 'Save a file'],\
|
||
|
[],\
|
||
|
['E&xit', 4, 'Exit program']\
|
||
|
],\
|
||
|
['&Help', 5, '', \
|
||
|
['&About', 6, 'About this program']\
|
||
|
]\
|
||
|
]).";
|
||
|
|
||
|
static char *project_resource = "icon(name = 'project_resource',\
|
||
|
icon = ['project', wxBITMAP_TYPE_ICO_RESOURCE, 'WINDOWS'],\
|
||
|
icon = ['project_data', wxBITMAP_TYPE_XBM, 'X']).";
|
||
|
|
||
|
static char *panel3 = "dialog(name = 'panel3',\
|
||
|
style = '',\
|
||
|
title = 'untitled',\
|
||
|
button_font = [14, 'wxSWISS', 'wxNORMAL', 'wxBOLD', 0],\
|
||
|
label_font = [10, 'wxSWISS', 'wxNORMAL', 'wxNORMAL', 0],\
|
||
|
x = 0, y = 37, width = 292, height = 164,\
|
||
|
control = [wxButton, 'OK', '', 'button5', 23, 34, -1, -1, 'aiai_resource'],\
|
||
|
control = [wxMessage, 'A Label', '', 'message7', 166, 61, -1, -1, 'aiai_resource'],\
|
||
|
control = [wxText, 'Text', 'wxVERTICAL_LABEL', 'text8', 24, 110, -1, -1]).";
|
||
|
\end{verbatim}
|
||
|
|
||
|
As you can see, C++-style comments are allowed, and apparently include files
|
||
|
are supported too: but this is a special case, where the included file
|
||
|
is a file of defines shared by the C++ application code and resource file
|
||
|
to relate identifiers (such as FILE\_OPEN) to integers.
|
||
|
|
||
|
Each {\it resource object} is of standard PrologIO syntax, that is,
|
||
|
an object name such as {\bf dialog} or {\bf icon}, then an open
|
||
|
parenthesis, a list of comma-delimited attribute/value pairs, a closing
|
||
|
parenthesis, and a full stop. Backslashes are required to escape newlines,
|
||
|
for the benefit of C++ syntax. If double quotation marks are used to
|
||
|
delimit strings, they need to be escaped with backslash within a C++ string
|
||
|
(so it's easier to use single quotation marks instead).
|
||
|
|
||
|
\normalbox{{\it A note on PrologIO string syntax:} A string that begins with
|
||
|
an alphabetic character, and contains only alphanumeric characters,
|
||
|
hyphens and underscores, need not be quoted at all. Single quotes and double
|
||
|
quotes may be used to delimit more complex strings. In fact, single-quoted
|
||
|
and no-quoted strings are actually called {\it words}, but are treated
|
||
|
as strings for the purpose of the resource system.}
|
||
|
|
||
|
A resource file like this is typically included in the application main file,
|
||
|
as if it were a normal C++ file. This eliminates the need for a separate
|
||
|
resource file to be distributed alongside the executable. However, the
|
||
|
resource file can be dynamically loaded if desired (for example by a non-C++
|
||
|
language such as CLIPS, Prolog or Python).
|
||
|
|
||
|
Once included, the resources need to be `parsed' (interpreted), because
|
||
|
so far the data is just a number of static string variables. The function\rtfsp
|
||
|
{\bf ::wxResourceParseData} is called early on in initialization of the application
|
||
|
(usually in {\bf wxApp::OnInit}) with a variable as argument. This may need to be
|
||
|
called a number of times, one for each variable. However, more than one
|
||
|
resource `object' can be stored in one string variable at a time, so you can
|
||
|
get all your resources into one variable if you want to.
|
||
|
|
||
|
{\bf ::wxResourceParseData} parses the contents of the resource, ready for use
|
||
|
by functions such as {\bf ::wxResourceCreateBitmap} and {\bf wxPanel::LoadFromResource}.
|
||
|
|
||
|
If a wxWindows resource object (such as a bitmap resource) refers to a
|
||
|
C++ data structure, such as static XBM or XPM data, a further call ({\bf
|
||
|
::wxResourceRegisterBitmapData}) needs to be made on initialization to tell
|
||
|
wxWindows about this data. The wxWindows resource object will refer to a
|
||
|
string identifier, such as `project\_data' in the example file above.
|
||
|
This identifier will be looked up in a table to get the C++ static data
|
||
|
to use for the bitmap or icon.
|
||
|
|
||
|
In the C++ fragment below, the WXR resource file is included,
|
||
|
and appropriate resource initialization is carried out in {\bf OnInit}.
|
||
|
Note that at this stage, no actual wxWindows dialogs, menus, bitmaps or
|
||
|
icons are created; their `templates' are merely being set up for later
|
||
|
use.
|
||
|
|
||
|
\begin{verbatim}
|
||
|
/*
|
||
|
* File: noname.cc
|
||
|
* Purpose: main application module, generated by wxBuilder.
|
||
|
*/
|
||
|
|
||
|
#include "wx.h"
|
||
|
#include "wx_help.h"
|
||
|
#include "noname.h"
|
||
|
|
||
|
// Includes the dialog, menu etc. resources
|
||
|
#include "noname.wxr"
|
||
|
|
||
|
// Includes XBM data
|
||
|
#include "project.xbm"
|
||
|
|
||
|
// Declare an instance of the application: allows the program to start
|
||
|
AppClass theApp;
|
||
|
|
||
|
// Called to initialize the program
|
||
|
wxFrame *AppClass::OnInit(void)
|
||
|
{
|
||
|
#ifdef wx_x
|
||
|
wxResourceRegisterBitmapData("project_data", project_bits, project_width, project_height);
|
||
|
#endif
|
||
|
wxResourceParseData(menuBar11);
|
||
|
wxResourceParseData(aiai_resource);
|
||
|
wxResourceParseData(project_resource);
|
||
|
wxResourceParseData(panel3);
|
||
|
...
|
||
|
}
|
||
|
\end{verbatim}
|
||
|
|
||
|
|
||
|
\subsection{Dialog resource format}
|
||
|
|
||
|
A dialog resource object may be used for either panels or dialog boxes, and
|
||
|
consists of the following attributes. In the following, a {\it font specification}\rtfsp
|
||
|
is a list consisting of point size, family, style, weight, underlined, optional facename.
|
||
|
|
||
|
\begin{twocollist}\itemsep=0pt
|
||
|
\twocolitemruled{Attribute}{Value}
|
||
|
\twocolitem{name}{The name of the resource.}
|
||
|
\twocolitem{style}{Optional dialog box or panel window style.}
|
||
|
\twocolitem{title}{The title of the dialog box (unused if a panel).}.
|
||
|
\twocolitem{modal}{Whether modal: 1 if modal, 0 if modeless, absent if a panel resource.}
|
||
|
\twocolitem{button\_font}{The font used for control buttons: a list comprising point size (integer),
|
||
|
family (string), font style (string), font weight (string) and underlining (0 or 1).}
|
||
|
\twocolitem{label\_font}{The font used for control labels: a list comprising point size (integer),
|
||
|
family (string), font style (string), font weight (string) and underlining (0 or 1).}
|
||
|
\twocolitem{x}{The x position of the dialog or panel.}
|
||
|
\twocolitem{y}{The y position of the dialog or panel.}
|
||
|
\twocolitem{width}{The width of the dialog or panel.}
|
||
|
\twocolitem{height}{The height of the dialog or panel.}
|
||
|
\twocolitem{background\_colour}{The background colour of the dialog or panel. Only valid if the style includes wxUSER\_COLOURS.}
|
||
|
\twocolitem{label\_colour}{The default label colour for the children of the dialog or panel. Only valid if the style includes wxUSER\_COLOURS.}
|
||
|
\twocolitem{button\_colour}{The default button text colour for the children of the dialog or panel. Only valid if the style includes wxUSER\_COLOURS.}
|
||
|
\twocolitem{label\_font}{Font spec}
|
||
|
\twocolitem{button\_font}{Font spec}
|
||
|
\end{twocollist}
|
||
|
|
||
|
Then comes zero or more attributes named `control' for each control
|
||
|
(panel item) on the dialog or panel. The value is a list of further
|
||
|
elements. In the table below, the names in the first column correspond to
|
||
|
the first element of the value list, and the second column details the
|
||
|
remaining elements of the list.
|
||
|
|
||
|
\begin{twocollist}\itemsep=0pt
|
||
|
\twocolitemruled{Control}{Values}
|
||
|
\twocolitem{wxButton}{title (string), window style (string), name (string), x, y, width, height, button bitmap resource (optional string), button font spec}
|
||
|
\twocolitem{wxCheckBox}{title (string), window style (string), name (string), x, y, width, height, default value (optional integer, 1 or 0), label font spec}
|
||
|
\twocolitem{wxChoice}{title (string), window style (string), name (string), x, y, width, height, values (optional list of strings), label font spec, button font spec}
|
||
|
\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}
|
||
|
\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}
|
||
|
\twocolitem{wxGroupBox}{title (string), window style (string), name (string), x, y, width, height, label font spec}
|
||
|
\twocolitem{wxListBox}{title (string), window style (string), name (string), x, y, width, height, values (optional list of strings), multiple (optional string, wxSINGLE or wxMULTIPLE),
|
||
|
label font spec, button font spec}
|
||
|
\twocolitem{wxMessage}{title (string), window style (string), name (string), x, y, width, height, message bitmap resource (optional string), label font spec}
|
||
|
\twocolitem{wxMultiText}{title (string), window style (string), name (string), x, y, width, height, default value (optional string),
|
||
|
label font spec, button font spec}
|
||
|
\twocolitem{wxRadioBox}{title (string), window style (string), name (string), x, y, width, height, values (optional list of strings), number of rows or cols,
|
||
|
label font spec, button font spec}
|
||
|
\twocolitem{wxRadioButton}{title (string), window style (string), name (string), x, y, width, height, default value (optional integer, 1 or 0), label font spec}
|
||
|
\twocolitem{wxScrollBar}{title (string), window style (string), name (string), x, y, width, height, value (optional integer),
|
||
|
page length (optional integer), object length (optional integer), view length (optional integer)}
|
||
|
\twocolitem{wxSlider}{title (string), window style (string), name (string), x, y, width, height, value (optional integer), minimum (optional integer), maximum (optional integer),
|
||
|
label font spec, button font spec}
|
||
|
\twocolitem{wxText}{title (string), window style (string), name (string), x, y, width, height, default value (optional string),
|
||
|
label font spec, button font spec}
|
||
|
\end{twocollist}
|
||
|
|
||
|
\subsection{Menubar resource format}
|
||
|
|
||
|
A menubar resource object consists of the following attributes.
|
||
|
|
||
|
\begin{twocollist}\itemsep=0pt
|
||
|
\twocolitemruled{Attribute}{Value}
|
||
|
\twocolitem{name}{The name of the menubar resource.}
|
||
|
\twocolitem{menu}{A list containing all the menus, as detailed below.}
|
||
|
\end{twocollist}
|
||
|
|
||
|
The value of the {\bf menu} attribute is a list of menu item specifications, where each menu
|
||
|
item specification is itself a list comprising:
|
||
|
|
||
|
\begin{itemize}\itemsep=0pt
|
||
|
\item title (a string)
|
||
|
\item menu item identifier (a string or non-zero integer, see below)
|
||
|
\item help string (optional)
|
||
|
\item 0 or 1 for the `checkable' parameter (optional)
|
||
|
\item optionally, further menu item specifications if this item is a pulldown menu.
|
||
|
\end{itemize}
|
||
|
|
||
|
If the menu item specification is the empty list ([]), this is interpreted as a menu separator.
|
||
|
|
||
|
If further (optional) information is associated with each menu item in a future release of wxWindows,
|
||
|
it will be placed after the help string and before the optional pulldown menu specifications.
|
||
|
|
||
|
Note that the menu item identifier must be an integer if the resource is being
|
||
|
included as C++ code and then parsed on initialisation. Unfortunately,\rtfsp
|
||
|
\verb$#$define substitution is not performed inside strings, and
|
||
|
therefore the program cannot know the mapping. However, if the .WXR file
|
||
|
is being loaded dynamically, wxWindows will attempt to replace string
|
||
|
identifiers with \verb$#$defined integers, because it is able to parse
|
||
|
the included \verb$#$defines.
|
||
|
|
||
|
\subsection{Bitmap resource format}
|
||
|
|
||
|
A bitmap resource object consists of a name attribute, and one or more {\bf bitmap} attributes.
|
||
|
There can be more than one of these to allow specification of bitmaps that are optimum for the
|
||
|
platform and display.
|
||
|
|
||
|
\begin{itemize}\itemsep=0pt
|
||
|
\item Bitmap name or filename.
|
||
|
\item Type of bitmap; for example, wxBITMAP\_TYPE\_BMP\_RESOURCE. See class reference under {\bf wxBitmap} for
|
||
|
a full list).
|
||
|
\item Platform this bitmap is valid for; one of WINDOWS, X, MAC and ANY.
|
||
|
\item Number of colours (optional).
|
||
|
\item X resolution (optional).
|
||
|
\item Y resolution (optional).
|
||
|
\end{itemize}
|
||
|
|
||
|
\subsection{Icon resource format}
|
||
|
|
||
|
An icon resource object consists of a name attribute, and one or more {\bf icon} attributes.
|
||
|
There can be more than one of these to allow specification of icons that are optimum for the
|
||
|
platform and display.
|
||
|
|
||
|
\begin{itemize}\itemsep=0pt
|
||
|
\item Icon name or filename.
|
||
|
\item Type of icon; for example, wxBITMAP\_TYPE\_ICO\_RESOURCE. See class reference under {\bf wxBitmap} for
|
||
|
a full list).
|
||
|
\item Platform this bitmap is valid for; one of WINDOWS, X, MAC and ANY.
|
||
|
\item Number of colours (optional).
|
||
|
\item X resolution (optional).
|
||
|
\item Y resolution (optional).
|
||
|
\end{itemize}
|
||
|
|
||
|
|
||
|
\subsection{Resource format design issues}
|
||
|
|
||
|
The .WXR file format is a recent addition and subject to change.
|
||
|
The use of an ASCII resource file format may seem rather inefficient, but this
|
||
|
choice has a number of advantages:
|
||
|
|
||
|
\begin{itemize}\itemsep=0pt
|
||
|
\item Since it is C++ compatible, it can be included into an application's source code,
|
||
|
eliminating the problems associated with distributing a separate resource file
|
||
|
with the executable. However, it can also be loaded dynamically from a file, which will be required
|
||
|
for non-C++ programs that use wxWindows.
|
||
|
\item No extra binary file format and separate converter need be maintained for the wxWindows project
|
||
|
(although others are welcome to add the equivalent of the Windows `rc' resource
|
||
|
parser and a binary format).
|
||
|
\item It would be difficult to append a binary resource component onto an executable
|
||
|
in a portable way.
|
||
|
\item The file format is essentially the PrologIO object format, for which
|
||
|
a parser already exists, so parsing is easy. For those programs that use PrologIO
|
||
|
anyway, the size overhead of the parser is minimal.
|
||
|
\end{itemize}
|
||
|
|
||
|
The disadvantages of the approach include:
|
||
|
|
||
|
\begin{itemize}\itemsep=0pt
|
||
|
\item Parsing adds a small execution overhead to program initialization.
|
||
|
\item Under 16-bit Windows especially, global data is at a premium.
|
||
|
Using a .RC resource table for some wxWindows resource data may be a partial solution,
|
||
|
although .RC strings are limited to 255 characters.
|
||
|
\item Without a resource preprocessor, it is not possible to substitute integers
|
||
|
for identifiers (so menu identifiers have to be written as integers in the resource
|
||
|
object, in addition to providing \verb$#$defines for application code convenience).
|
||
|
\end{itemize}
|
||
|
|
||
|
\subsection{Compiling the resource system}
|
||
|
|
||
|
To enable the resource system, set {\bf USE\_WX\_RESOURCES} to 1 in wx\_setup.h.
|
||
|
If your wxWindows makefile supports it, set the same name in the makefile to 1.
|
||
|
|
||
|
You will also need to compile the PrologIO utility (not always the easiest
|
||
|
task): you will need YACC, and LEX (or FLEX). DOS versions of these are
|
||
|
available on the AIAI ftp site under /pub/wxwin/tools.
|
||
|
|