dbfb85a765
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@32252 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
514 lines
18 KiB
TeX
514 lines
18 KiB
TeX
% Note: -e/C++ header generation documentation added by
|
|
% Eduardo Marques <edrdo@netcabo.pt>
|
|
%
|
|
\section{XML-based resource system overview}\label{xrcoverview}
|
|
|
|
Classes: \helpref{wxXmlResource}{wxxmlresource}, \helpref{wxXmlResourceHandler}{wxxmlresourcehandler}
|
|
|
|
The XML-based resource system, known as XRC, allows user interface elements such as
|
|
dialogs, menu bars and toolbars, to be stored in text files and loaded into
|
|
the application at run-time. XRC files can also be compiled into binary XRS files or C++
|
|
code (the former makes it possible to store all resources in a single file and the latter
|
|
is useful when you want to embed the resources into the executable).
|
|
|
|
There are several advantages to using XRC resources.
|
|
|
|
\begin{itemize}\itemsep=0pt
|
|
\item Recompiling and linking an application is not necessary if the
|
|
resources change.
|
|
\item If you use a dialog designer that generates C++ code, it can be hard
|
|
to reintegrate this into existing C++ code. Separation of resources and code
|
|
is a more elegant solution.
|
|
\item You can choose between different alternative resource files at run time, if necessary.
|
|
\item The XRC format uses sizers for flexibility, allowing dialogs to be resizable
|
|
and highly portable.
|
|
\item The XRC format is a wxWidgets standard,
|
|
and can be generated or postprocessed by any program that understands it. As it is based
|
|
on the XML standard, existing XML editors can be used for simple editing purposes.
|
|
\end{itemize}
|
|
|
|
XRC was written by Vaclav Slavik.
|
|
|
|
\subsection{XRC concepts}\label{xrcconcepts}
|
|
|
|
These are the typical steps for using XRC files in your application.
|
|
|
|
\begin{itemize}\itemsep=0pt
|
|
\item Include the appropriate headers: normally "wx/xrc/xmlres.h" will suffice;
|
|
\item If you are going to use \helpref{XRS files}{binaryresourcefiles}, install
|
|
wxFileSystem ZIP handler first with {\tt wxFileSystem::AddHandler(new wxZipFSHandler);}
|
|
\item call {\tt wxXmlResource::Get()->InitAllHandlers()} from your wxApp::OnInit function,
|
|
and then call {\tt wxXmlResource::Get()->Load("myfile.xrc")} to load the resource file;
|
|
\item to create a dialog from a resource, create it using the default constructor, and then
|
|
load it using for example {\tt wxXmlResource::Get()->LoadDialog(\&dlg, this, "dlg1");}
|
|
\item set up event tables as usual but use the {\tt XRCID(str)} macro to translate from XRC string names
|
|
to a suitable integer identifier, for example {\tt EVT\_MENU(XRCID("quit"), MyFrame::OnQuit)}.
|
|
\end{itemize}
|
|
|
|
To create an XRC file, you can use one of the following methods.
|
|
|
|
\begin{itemize}\itemsep=0pt
|
|
\item Create the file by hand;
|
|
\item use \urlref{wxDesigner}{http://www.roebling.de}, a commercial dialog designer/RAD tool;
|
|
\item use \urlref{DialogBlocks}{http://www.anthemion.co.uk/dialogblocks}, a commercial dialog editor;
|
|
\item use \urlref{XRCed}{http://xrced.sf.net}, a wxPython-based
|
|
dialog editor that you can find in the {\tt wxPython/tools} subdirectory of the wxWidgets
|
|
CVS archive;
|
|
\item use \urlref{wxGlade}{http://wxglade.sf.net}, a GUI designer written in wxPython. At the moment it can generate Python, C++ and XRC;
|
|
\item convert WIN32 RC files to XRC with the tool in {\tt contrib/utils/convertrc}.
|
|
\end{itemize}
|
|
|
|
A complete list of third-party tools that write to XRC can be found at \urlref{www.wxwidgets.org/lnk\_tool.htm}{http://www.wxwidgets.org/lnk\_tool.in}.
|
|
|
|
It is highly recommended that you use a resource editing tool, since it's fiddly writing
|
|
XRC files by hand.
|
|
|
|
You can use \helpref{wxXmlResource::Load}{wxxmlresourceload} in a number of ways.
|
|
You can pass an XRC file (XML-based text resource file)
|
|
or a \helpref{zip-compressed file}{binaryresourcefiles} (extension ZIP or XRS) containing other XRC.
|
|
|
|
You can also use \helpref{embedded C++ resources}{embeddedresource}
|
|
|
|
\subsection{Using binary resource files}\label{binaryresourcefiles}
|
|
|
|
To compile binary resource files, use the command-line wxrc utility. It takes one or more file parameters
|
|
(the input XRC files) and the following switches and options:
|
|
\begin{itemize}\itemsep=0pt
|
|
\item -h (--help): show a help message
|
|
\item -v (--verbose): show verbose logging information
|
|
\item -c (--cpp-code): write C++ source rather than a XRS file
|
|
\item -e (--extra-cpp-code): if used together with -c, generates C++ header file
|
|
containing class definitions for the windows defined by the XRC file (see special subsection)
|
|
\item -u (--uncompressed): do not compress XML files (C++ only)
|
|
\item -g (--gettext): output underscore-wrapped strings that poEdit or gettext can scan. Outputs to stdout, or a file if -o is used
|
|
\item -n (--function) <name>: specify C++ function name (use with -c)
|
|
\item -o (--output) <filename>: specify the output file, such as resource.xrs or resource.cpp
|
|
\item -l (--list-of-handlers) <filename>: output a list of necessary handlers to this file
|
|
\end{itemize}
|
|
|
|
For example:
|
|
\begin{verbatim}
|
|
% wxrc resource.xrc
|
|
% wxrc resource.xrc -o resource.xrs
|
|
% wxrc resource.xrc -v -c -o resource.cpp
|
|
\end{verbatim}
|
|
|
|
\wxheading{Note}
|
|
|
|
XRS file is essentially a renamed ZIP archive which means that you can manipulate
|
|
it with standard ZIP tools. Note that if you are using XRS files, you have
|
|
to initialize the \helpref{wxFileSystem}{wxfilesystem} ZIP handler first! It is a simple
|
|
thing to do:
|
|
|
|
\begin{verbatim}
|
|
#include <wx/filesys.h>
|
|
#include <wx/fs_zip.h>
|
|
...
|
|
wxFileSystem::AddHandler(new wxZipFSHandler);
|
|
\end{verbatim}
|
|
|
|
\subsection{Using embedded resources}\label{embeddedresource}
|
|
|
|
It is sometimes useful to embed resources in the executable itself instead
|
|
of loading an external file (e.g. when your app is small and consists only of one
|
|
exe file). XRC provides means to convert resources into regular C++ file that
|
|
can be compiled and included in the executable.
|
|
|
|
Use the {\tt -c} switch to
|
|
{\tt wxrc} utility to produce C++ file with embedded resources. This file will
|
|
contain a function called {\it InitXmlResource} (unless you override this with
|
|
a command line switch). Use it to load the resource:
|
|
|
|
\begin{verbatim}
|
|
extern void InitXmlResource(); // defined in generated file
|
|
...
|
|
wxXmlResource::Get()->InitAllHandlers();
|
|
InitXmlResource();
|
|
...
|
|
\end{verbatim}
|
|
|
|
\subsection{XRC C++ sample}\label{xrccppsample}
|
|
|
|
This is the C++ source file (xrcdemo.cpp) for the XRC sample.
|
|
|
|
\begin{verbatim}
|
|
#include "wx/wx.h"
|
|
#include "wx/image.h"
|
|
#include "wx/xrc/xmlres.h"
|
|
|
|
// the application icon
|
|
#if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__)
|
|
#include "rc/appicon.xpm"
|
|
#endif
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// private classes
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Define a new application type, each program should derive a class from wxApp
|
|
class MyApp : public wxApp
|
|
{
|
|
public:
|
|
// override base class virtuals
|
|
// ----------------------------
|
|
|
|
// this one is called on application startup and is a good place for the app
|
|
// initialization (doing it here and not in the ctor allows to have an error
|
|
// return: if OnInit() returns false, the application terminates)
|
|
virtual bool OnInit();
|
|
};
|
|
|
|
// Define a new frame type: this is going to be our main frame
|
|
class MyFrame : public wxFrame
|
|
{
|
|
public:
|
|
// ctor(s)
|
|
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
|
|
|
|
// event handlers (these functions should _not_ be virtual)
|
|
void OnQuit(wxCommandEvent& event);
|
|
void OnAbout(wxCommandEvent& event);
|
|
void OnDlg1(wxCommandEvent& event);
|
|
void OnDlg2(wxCommandEvent& event);
|
|
|
|
private:
|
|
// any class wishing to process wxWidgets events must use this macro
|
|
DECLARE_EVENT_TABLE()
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// event tables and other macros for wxWidgets
|
|
// ----------------------------------------------------------------------------
|
|
|
|
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
|
EVT_MENU(XRCID("menu_quit"), MyFrame::OnQuit)
|
|
EVT_MENU(XRCID("menu_about"), MyFrame::OnAbout)
|
|
EVT_MENU(XRCID("menu_dlg1"), MyFrame::OnDlg1)
|
|
EVT_MENU(XRCID("menu_dlg2"), MyFrame::OnDlg2)
|
|
END_EVENT_TABLE()
|
|
|
|
IMPLEMENT_APP(MyApp)
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// the application class
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// 'Main program' equivalent: the program execution "starts" here
|
|
bool MyApp::OnInit()
|
|
{
|
|
wxImage::AddHandler(new wxGIFHandler);
|
|
wxXmlResource::Get()->InitAllHandlers();
|
|
wxXmlResource::Get()->Load("rc/resource.xrc");
|
|
|
|
MyFrame *frame = new MyFrame("XML resources demo",
|
|
wxPoint(50, 50), wxSize(450, 340));
|
|
frame->Show(true);
|
|
return true;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// main frame
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// frame constructor
|
|
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
|
|
: wxFrame((wxFrame *)NULL, -1, title, pos, size)
|
|
{
|
|
SetIcon(wxICON(appicon));
|
|
|
|
SetMenuBar(wxXmlResource::Get()->LoadMenuBar("mainmenu"));
|
|
SetToolBar(wxXmlResource::Get()->LoadToolBar(this, "toolbar"));
|
|
}
|
|
|
|
// event handlers
|
|
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
// true is to force the frame to close
|
|
Close(true);
|
|
}
|
|
|
|
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxString msg;
|
|
msg.Printf( _T("This is the about dialog of XML resources demo.\n")
|
|
_T("Welcome to %s"), wxVERSION_STRING);
|
|
|
|
wxMessageBox(msg, "About XML resources demo", wxOK | wxICON_INFORMATION, this);
|
|
}
|
|
|
|
void MyFrame::OnDlg1(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxDialog dlg;
|
|
wxXmlResource::Get()->LoadDialog(&dlg, this, "dlg1");
|
|
dlg.ShowModal();
|
|
}
|
|
|
|
void MyFrame::OnDlg2(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxDialog dlg;
|
|
wxXmlResource::Get()->LoadDialog(&dlg, this, "dlg2");
|
|
dlg.ShowModal();
|
|
}
|
|
\end{verbatim}
|
|
|
|
\subsection{XRC resource file sample}\label{xrcsample}
|
|
|
|
This is the XML file (resource.xrc) for the XRC sample.
|
|
|
|
\begin{verbatim}
|
|
<?xml version="1.0"?>
|
|
<resource version="2.3.0.1">
|
|
<object class="wxMenuBar" name="mainmenu">
|
|
<style>wxMB_DOCKABLE</style>
|
|
<object class="wxMenu" name="menu_file">
|
|
<label>_File</label>
|
|
<style>wxMENU_TEAROFF</style>
|
|
<object class="wxMenuItem" name="menu_about">
|
|
<label>_About...</label>
|
|
<bitmap>filesave.gif</bitmap>
|
|
</object>
|
|
<object class="separator"/>
|
|
<object class="wxMenuItem" name="menu_dlg1">
|
|
<label>Dialog 1</label>
|
|
</object>
|
|
<object class="wxMenuItem" name="menu_dlg2">
|
|
<label>Dialog 2</label>
|
|
</object>
|
|
<object class="separator"/>
|
|
<object class="wxMenuItem" name="menu_quit">
|
|
<label>E_xit\tAlt-X</label>
|
|
</object>
|
|
</object>
|
|
</object>
|
|
<object class="wxToolBar" name="toolbar">
|
|
<style>wxTB_FLAT|wxTB_DOCKABLE</style>
|
|
<margins>2,2</margins>
|
|
<object class="tool" name="menu_open">
|
|
<bitmap>fileopen.gif</bitmap>
|
|
<tooltip>Open catalog</tooltip>
|
|
</object>
|
|
<object class="tool" name="menu_save">
|
|
<bitmap>filesave.gif</bitmap>
|
|
<tooltip>Save catalog</tooltip>
|
|
</object>
|
|
<object class="tool" name="menu_update">
|
|
<bitmap>update.gif</bitmap>
|
|
<tooltip>Update catalog - synchronize it with sources</tooltip>
|
|
</object>
|
|
<separator/>
|
|
<object class="tool" name="menu_quotes">
|
|
<bitmap>quotes.gif</bitmap>
|
|
<toggle>1</toggle>
|
|
<tooltip>Display quotes around the string?</tooltip>
|
|
</object>
|
|
<object class="separator"/>
|
|
<object class="tool" name="menu_fuzzy">
|
|
<bitmap>fuzzy.gif</bitmap>
|
|
<tooltip>Toggled if selected string is fuzzy translation</tooltip>
|
|
<toggle>1</toggle>
|
|
</object>
|
|
</object>
|
|
<object class="wxDialog" name="dlg1">
|
|
<object class="wxBoxSizer">
|
|
<object class="sizeritem">
|
|
<object class="wxBitmapButton">
|
|
<bitmap>fuzzy.gif</bitmap>
|
|
<focus>fileopen.gif</focus>
|
|
</object>
|
|
</object>
|
|
<object class="sizeritem">
|
|
<object class="wxPanel">
|
|
<object class="wxStaticText">
|
|
<label>fdgdfgdfgdfg</label>
|
|
</object>
|
|
<style>wxSUNKEN_BORDER</style>
|
|
</object>
|
|
<flag>wxALIGN_CENTER</flag>
|
|
</object>
|
|
<object class="sizeritem">
|
|
<object class="wxButton">
|
|
<label>Buttonek</label>
|
|
</object>
|
|
<border>10d</border>
|
|
<flag>wxALL</flag>
|
|
</object>
|
|
<object class="sizeritem">
|
|
<object class="wxHtmlWindow">
|
|
<htmlcode><h1>Hi,</h1>man</htmlcode>
|
|
<size>100,45d</size>
|
|
</object>
|
|
</object>
|
|
<object class="sizeritem">
|
|
<object class="wxNotebook">
|
|
<object class="notebookpage">
|
|
<object class="wxPanel">
|
|
<object class="wxBoxSizer">
|
|
<object class="sizeritem">
|
|
<object class="wxHtmlWindow">
|
|
<htmlcode>Hello, we are inside a <u>NOTEBOOK</u>...</htmlcode>
|
|
<size>50,50d</size>
|
|
</object>
|
|
<option>1</option>
|
|
</object>
|
|
</object>
|
|
</object>
|
|
<label>Page</label>
|
|
</object>
|
|
<object class="notebookpage">
|
|
<object class="wxPanel">
|
|
<object class="wxBoxSizer">
|
|
<object class="sizeritem">
|
|
<object class="wxHtmlWindow">
|
|
<htmlcode>Hello, we are inside a <u>NOTEBOOK</u>...</htmlcode>
|
|
<size>50,50d</size>
|
|
</object>
|
|
</object>
|
|
</object>
|
|
</object>
|
|
<label>Page 2</label>
|
|
</object>
|
|
<usenotebooksizer>1</usenotebooksizer>
|
|
</object>
|
|
<flag>wxEXPAND</flag>
|
|
</object>
|
|
<orient>wxVERTICAL</orient>
|
|
</object>
|
|
</object>
|
|
<object class="wxDialog" name="dlg2">
|
|
<object class="wxBoxSizer">
|
|
<orient>wxVERTICAL</orient>
|
|
<object class="sizeritem" name="dfgdfg">
|
|
<object class="wxTextCtrl">
|
|
<size>200,200d</size>
|
|
<style>wxTE_MULTILINE|wxSUNKEN_BORDER</style>
|
|
<value>Hello, this is an ordinary multiline\n textctrl....</value>
|
|
</object>
|
|
<option>1</option>
|
|
<flag>wxEXPAND|wxALL</flag>
|
|
<border>10</border>
|
|
</object>
|
|
<object class="sizeritem">
|
|
<object class="wxBoxSizer">
|
|
<object class="sizeritem">
|
|
<object class="wxButton" name="wxID_OK">
|
|
<label>Ok</label>
|
|
<default>1</default>
|
|
</object>
|
|
</object>
|
|
<object class="sizeritem">
|
|
<object class="wxButton" name="wxID_CANCEL">
|
|
<label>Cancel</label>
|
|
</object>
|
|
<border>10</border>
|
|
<flag>wxLEFT</flag>
|
|
</object>
|
|
</object>
|
|
<flag>wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_RIGHT</flag>
|
|
<border>10</border>
|
|
</object>
|
|
</object>
|
|
<title>Second testing dialog</title>
|
|
</object>
|
|
</resource>
|
|
\end{verbatim}
|
|
|
|
\subsection{XRC file format}\label{xrcfileformat}
|
|
|
|
Please see Technical Note 14 (docs/tech/tn0014.txt) in your wxWidgets
|
|
distribution.
|
|
|
|
\subsection{C++ header file generation}\label{xrccppheader}
|
|
|
|
Using the {\tt -e} switch together with {\tt -c}, a C++ header file is written
|
|
containing class definitions for the GUI windows defined in the XRC file.
|
|
This code generation can make it easier to use XRC and automate program
|
|
development.
|
|
The classes can be used as basis for development, freeing the
|
|
programmer from dealing with most of the XRC specifics (e.g. {\tt XRCCTRL}).
|
|
|
|
For each top level window defined in the XRC file a C++ class definition is
|
|
generated, containing as class members the named widgets of the window.
|
|
A default constructor for each class is also generated. Inside the constructor
|
|
all XRC loading is done and all class members representing widgets are initialized.
|
|
|
|
A simple example will help understand how the scheme works. Suppose you have
|
|
a XRC file defining a top level window {\tt TestWnd\_Base}, which subclasses {\tt wxFrame} (any
|
|
other class like {\tt wxDialog} will do also), and has subwidgets {\tt wxTextCtrl} A and {\tt wxButton} B.
|
|
The XRC file and corresponding class definition in the header file will be something like:
|
|
|
|
\begin{verbatim}
|
|
<?xml version="1.0"?>
|
|
<resource version="2.3.0.1">
|
|
<object class="wxFrame" name="TestWnd_Base">
|
|
<size>-1,-1</size>
|
|
<title>Test</title>
|
|
<object class="wxBoxSizer">
|
|
<orient>wxHORIZONTAL</orient>
|
|
<object class="sizeritem">
|
|
<object class="wxTextCtrl" name="A">
|
|
<label>Test label</label>
|
|
</object>
|
|
</object>
|
|
<object class="sizeritem">
|
|
<object class="wxButton" name="B">
|
|
<label>Test button</label>
|
|
</object>
|
|
</object>
|
|
</object>
|
|
</object>
|
|
</resource>
|
|
|
|
|
|
class TestWnd_Base : public wxFrame {
|
|
protected:
|
|
wxTextCtrl* A;
|
|
wxButton* B;
|
|
|
|
private:
|
|
void InitWidgetsFromXRC(){
|
|
wxXmlResource::Get()->LoadObject(this,NULL,"TestWnd","wxFrame");
|
|
A = XRCCTRL(*this,"A",wxTextCtrl);
|
|
B = XRCCTRL(*this,"B",wxButton);
|
|
}
|
|
public:
|
|
TestWnd::TestWnd(){
|
|
InitWidgetsFromXRC();
|
|
}
|
|
};
|
|
\end{verbatim}
|
|
|
|
The generated window class can be used as basis for the full window class. The
|
|
class members which represent widgets may be accessed by name instead of using
|
|
{\tt XRCCTRL} every time you wish to reference them (note that they are {\tt protected} class members),
|
|
though you must still use {\tt XRCID} to refer to widget IDs in the event
|
|
table.
|
|
|
|
Example:
|
|
|
|
\begin{verbatim}
|
|
#include "resource.h"
|
|
|
|
class TestWnd : public TestWnd_Base {
|
|
public:
|
|
TestWnd(){
|
|
// A, B already initialised at this point
|
|
A->SetValue("Updated in TestWnd::TestWnd");
|
|
B->SetValue("Nice :)");
|
|
}
|
|
void OnBPressed(wxEvent& event){
|
|
Close();
|
|
}
|
|
DECLARE_EVENT_TABLE();
|
|
};
|
|
|
|
BEGIN_EVENT_TABLE(TestWnd,TestWnd_Base)
|
|
EVT_BUTTON(XRCID("B"),TestWnd::OnBPressed)
|
|
END_EVENT_TABLE()
|
|
|
|
\end{verbatim}
|
|
|
|
\subsection{Adding new resource handlers}\label{newresourcehandlers}
|
|
|
|
Coming soon.
|
|
|