wxWidgetsで画面デザインを定義する.xrcファイルを読み込んでGUIを作成する。
<?xml version="1.0" ?> <resource version="2.3.0.1"> <!-- トップレベルはコントロールである必要がある。パネルを作成。 --> <object class="wxPanel" name="myMainPanel">
<!-- レイアウト用のサイザーを作成 --> <object class="wxBoxSizer" name="myBoxSizer"> <orient>wxVERTICAL</orient> <!-- レイアウト方法の指定 -->
<!-- コントロールは sizeritem に入れる --> <object class="sizeritem"> <!-- 左側と上側に15pxの余白を入れる --> <flag>wxLEFT|wxTOP</flag> <border>15</border> <!-- このコントロールはサイザーのサイズ変更で大きさが変わらない --> <option>0</option>
<!-- 名前 myButton を追加 --> <object class="wxButton" name="myButton"> <label>ボタン</label> <size>100,30</size> </object>
</object>
<!-- コントロールは sizeritem に入れる --> <object class="sizeritem"> <!-- 上下左右の余白は15px --> <flag>wxALL|wxEXPAND</flag> <border>15</border> <!-- このコントロールはサイザーのサイズ変更で大きさが変わる --> <option>1</option>
<object class="wxTextCtrl" name="mytext1"> <label>ボタン</label> <size>100,30</size> <!-- サイザーが有効なのでサイズは無視される --> </object>
</object>
</object>
</object> </resource>
// https://docs.wxwidgets.org/3.0/overview_helloworld.html // プリプロセッサに以下二つを追加 // __WXMSW__ // WXUSINGDLL // サブシステムをWindowsに設定(WinMainで呼び出すので) // Windows (/SUBSYSTEM:WINDOWS) #ifndef WX_PRECOMP #include <wx/wx.h> #endif #include <wx/gdicmn.h> // wxPointに必要 #include <wx/frame.h> // wxFrameに必要 #pragma comment(lib,"wxbase32u.lib") #pragma comment(lib,"wxbase32u_net.lib") #pragma comment(lib,"wxbase32u_xml.lib") #pragma comment(lib,"wxmsw32u_adv.lib") #pragma comment(lib,"wxmsw32u_aui.lib") #pragma comment(lib,"wxmsw32u_core.lib") #pragma comment(lib,"wxmsw32u_gl.lib") #pragma comment(lib,"wxmsw32u_html.lib") #pragma comment(lib,"wxmsw32u_media.lib") #pragma comment(lib,"wxmsw32u_propgrid.lib") #pragma comment(lib,"wxmsw32u_qa.lib") #pragma comment(lib,"wxmsw32u_ribbon.lib") #pragma comment(lib,"wxmsw32u_richtext.lib") #pragma comment(lib,"wxmsw32u_stc.lib") #pragma comment(lib,"wxmsw32u_webview.lib") #pragma comment(lib,"wxmsw32u_xrc.lib") ///////////////////////////////////// ///////////////////////////////////// ///////////////////////////////////// #include <wx/xrc/xmlres.h> // ウィンドウ作成 class MyFrame : public wxFrame { public:
void PostCreate() { wxXmlResource::Get()->InitAllHandlers();// 初期化 wxXmlResource::Get()->Load(R"(C:\test\layout.xrc)"); // ファイル読み込み wxXmlResource::Get()->LoadPanel(this, "myMainPanel"); // GUIの作成 this->Layout(); // レイアウトの更新 }
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) : wxFrame(NULL, wxID_ANY, title, pos, size) { // CallAfter : 現在処理中のイベントが終わったらPostCreateを実行 // コンストラクタはウィンドウ生成イベント扱い CallAfter(&MyFrame::PostCreate); } private: }; ///////////////////////////////////// ///////////////////////////////////// ///////////////////////////////////// // wxWidgetsのアプリケーション作成 class MyApp : public wxApp { public: virtual bool OnInit() { MyFrame* frame = new MyFrame("Hello World", wxPoint(50, 50), wxSize(450, 340)); frame->Show(true); return true; } }; ///////////////////////////////////// ///////////////////////////////////// ///////////////////////////////////// // WinMainをマクロで定義 wxIMPLEMENT_APP(MyApp);
パネルにはLoadPanelがあるが、すべてのコントロールにLoad***が用意されているわけではない。LoadObject関数を使って、部品名とその部品のクラスを指定して読み込む。
<?xml version="1.0" ?> <resource version="2.3.0.1"> <!-- 名前 myButton を追加 --> <object class="wxButton" name="myButton"> <label>ボタン</label> <size>300,30</size> </object> </resource>
void PostCreate() { wxXmlResource::Get()->InitAllHandlers();// 初期化 wxXmlResource::Get()->Load(R"(C:\test\button.xrc)"); // ファイル読み込み wxWindow* btn = (wxWindow*)wxXmlResource::Get()->LoadObject(this, "myButton"/*識別子*/, "wxButton"/*クラス*/); // boxsizerの追加 wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); this->SetSizer(sizer); sizer->Add(btn, 0, wxALL, 10); this->Layout(); // レイアウトの更新 }
原則として、メモリ上のテキストを読み込む方法はない。しかし、wxWidgetsにはメモリ上に仮想的なファイルを作成する機能があるので、これを使って仮想的な.xrcファイルを作れば実現できる。
仮想ファイルを作るために、fs_mem.h が必要。
#include <wx/fs_mem.h>
void PostCreate() { wxXmlResource::Get()->InitAllHandlers(); wxString layout_xrc =
R"(<?xml version="1.0" ?> <resource version="2.3.0.1"> <object class="wxPanel" name="myPanel"> <object class="wxBoxSizer"> <orient>wxVERTICAL</orient> <object class="sizeritem"> <object class="wxTextCtrl" name="text"/> <option>0</option> <size>100,30</size> <flag>wxALL</flag> <border>10</border> </object> </object> </object> </resource> )"
; wxFileSystem::AddHandler(new wxMemoryFSHandler); wxMemoryFSHandler::AddFile("myxrc", layout_xrc.GetData().AsWChar(), layout_xrc.size()*2); wxXmlResource::Get()->Load("memory:myxrc"); wxWindow* mysizer = wxXmlResource::Get()->LoadPanel(this, "myPanel"); this->Layout(); // レイアウトの更新 }