1. 什么是XRC
XRC是基于XML的资源系统。它的基本出发点是将界面布局和程序逻辑分离,即将界面布局代码保存在分离的XML文件中,在程序中不涉及控件的创建和布局,只需要加载相应的资源并处理事件绑定即可。
2. XRC文件格式
<?xml version="1.0"?>
<resource version="2.3.0.1">
<object class="wxFrame" name="ID_MAIN_FRAME">
<size>200, 300</size>
…
</object>
</resource>
3. XRC文件中菜单资源的相关属性
wxMenuBar
style Menu bar style: wxMB_DOCKABLE
wxMenu
style Menu style: wxMENU_TEAROFF
label Text: label of the menu.
help Text: displayed help string.
wxMenuItem
style Menu style: wxMENU_TEAROFF
label Text: label of the menu.
accel Text: accelerator associated to this item ( Alt-X for example ).
help Text: displayed help string.
radio bool value(0/1): 1 if this item is a radio menu item.
checkable bool value(0/1): 1 if this item is a check menu item.
enabled bool value(0/1): 1 if this item is initially enabled.
checked bool value(0/1): 1 if this (check) item is initially checked.
bitmap Text: path to a bitmap to draw at the left of the item.
4. 使用XRC创建菜单
创建一个包含菜单布局信息的XML资源文件(.xrc):
// MenuBar.xrc
<?xml version="1.0" encoding="utf-8" ?>
<resource version="2.3.0.1" xmlns="http://www.wxwindows.org/wxxrc">
<object class="wxMenuBar" name="ID_MENUBAR">
<object class="wxMenu" name="ID_MENU_FILE">
<label>&File</label>
<object class="wxMenuItem" name="wxID_CLOSE">
<label>E&xit</label>
<accel>Ctrl+Q</accel>
<help>Quit the application</help>
</object>
</object>
<object class="wxMenu" name="ID_MENU_VIEW">
<label>&View</label>
</object>
<object class="wxMenu" name="ID_MENU_TOOLS">
<label>&Tools</label>
<object class="wxMenuItem" name="wxID_OPTIONS">
<label>&Options…</label>
</object>
</object>
<object class="wxMenu" name="ID_MENU_HELP">
<label>&Help</label>
<object class="wxMenuItem" name="wxID_CHECKFORUPDATES">
<label>Check for &Updates…</label>
</object>
<object class="separator" />
<object class="wxMenuItem" name="wxID_ABOUT">
<label>&About…</label>
</object>
</object>
</object>
</resource>
初始化并且加载资源文件
// MainApp.cpp
bool MainApp::OnInit()
{
wxXmlResource* pResource = wxXmlResource::Get();
pResource->AddHandler(new wxMenuBarXmlHandler);
pResource->AddHandler(new wxMenuXmlHandler);
pResource->Load(wxT("resources/MenuBar.xrc"));
…
}
// MainFrame.cpp
MainFrame::MainFrame(const wxString& title) : wxFrame(NULL, wxID_ANY, title)
{
m_menuBar = NULL;
InitMenuBar();
}
bool MainFrame::InitMenuBar()
{
if (m_menuBar)
{
SetMenuBar(NULL);
delete m_menuBar;
}
// Initialize the resource system
m_menuBar = wxXmlResource::Get()->LoadMenuBar(wxT("ID_MENUBAR"));
if (!m_menuBar)
{
wxLogError(wxT("Cannot load main menu from resource file"));
return false;
}
SetMenuBar(m_menuBar);
return true;
}
5. 在XRC菜单上添加动态子菜单
在资源文件中添加一个新的菜单项(wxID_LANGUAGES)
<object class="wxMenu" name="ID_MENU_VIEW">
<label>&View</label>
<object class="wxMenu" name="wxID_LANGUAGE">
<label>&Language</label>
<object class="wxMenuItem" name="wxID_LANGUAGES">
<label>Get Additional/Update language pack</label>
<help>Downloading Additional/Update language pack</help>
</object>
<object class="separator" />
</object>
</object>
// Initialize the resource system
m_menuBar = wxXmlResource::Get()->LoadMenuBar(wxT("ID_MENUBAR"));
if (!m_menuBar)
{
wxLogError(wxT("Cannot load main menu from resource file"));
return false;
}
/*
* 这里很奇怪,在XRC文件wxID_LANGUAGE的类型明明是wxMenu,可在这里确只能用wxMenuItem。
* 查看wxWidgets源代码发现XRC系统只会把最上层的class为wxMenu的object创建为wxMenu对象。
* 其它的则都被创建成了wxMenuItem对象。
*/
// 使用XRCID方法获取控件ID,创建动态子菜单
wxMenuItem* menuItem = m_menuBar->FindItem(XRCID("wxID_LANGUAGE"));
if (menuItem)
{
wxMenu* subMenu = menuItem->GetSubMenu();
subMenu->AppendRadioItem(wxID_LANGUAGE_LOWEST + 1, wxT("English"));
subMenu->AppendRadioItem(wxID_LANGUAGE_LOWEST + 2, wxT("Chinese(Simplified)"));
}
SetMenuBar(m_menuBar);
return true;