And here do we create some controls on its main frame and a pop menu for the application as well as starting to be accustomed to working with sizers and an advanced page control component of wxWidgets.
- Open the previously created wxWidgets project.
- Specify "#include <wx/sizer.h>", "#include <wx/aui/auibook.h>" and "#include <wx/panel.h>" in its main header file.
- Now let us change the size of the main frame so that it could accommodate the controls to be created afterwards :
....
MainFrame(wxWindow *parent, wxWindowID id = wxID_ANY , const wxString &caption = wxEmptyString , const wxPoint &pos = wxDefaultPosition , const wxSize &size = wxSize(800, 600)); // Modify the size. void OnFrameClose(wxCloseEvent &event);
.... - Declare the following enumeration for the application's sections in its header file :
//-------------------- (4) -------------------: enum enSections { secGeneral, secDirs, Projects, cisections }; //----------------------------------------------------------------------------
- Declare the following variables for our controls in the private section of its header file :
//-------------------------------(4): wxSizer *m_szrhFrame; // the main sizer for the frame. wxAuiNotebook m_nbkSections; // left section page control. wxPanel m_pnlSections[cisections]; // each page for the left section control. wxSizer *m_szrvSections[cisections]; // sizers for each panel. wxString m_SSections[cisections]; // section page captions. wxStaticText m_lblSections[cisections]; // each label for each section. wxSizer *m_szrhSectionLabels[cisections]; // sizer for each section label. wxPanel m_pnlMain; // main panel for all main controls of the application. wxSizer *m_szrvMain; // sizer for the main panel. wxSizer *m_szrhMainLabel; // sizer for the horizontal label. wxStaticText m_lblMainPanel; // capton for the main panel. //-------------------------------(4).
- Declare the following method for our control creation in the header file :
void AllocFreeMainControls(bool bAlloc);
- Write down code for the controls creation in the main source file :
//---------------------------------------------------------------------------- void MainFrame::AllocFreeMainControls(bool bAlloc) { if (bAlloc) { m_szrhFrame = new wxBoxSizer(wxHORIZONTAL); this->SetSizer(m_szrhFrame); wxSize sz(wxDefaultSize); sz.x = 0x0100; m_nbkSections.Create(this, wxID_ANY, wxDefaultPosition, sz); wchar_t ws[0x20] = L"Page : "; wchar_t *pws = &ws[wcslen(ws)]; const wxColor *clrs[] = { wxWHITE, wxYELLOW, wxGREEN }; for (int i = 0x00; i < cisections; i++) { m_pnlSections[i].Create(this); m_pnlSections[i].SetBackgroundColour(*clrs[i]); m_szrvSections[i] = new wxBoxSizer(wxVERTICAL); m_pnlSections[i].SetSizer(m_szrvSections[i]); m_szrhSectionLabels[i] = new wxBoxSizer(wxHORIZONTAL); m_szrhSectionLabels[i]->AddStretchSpacer(); _itow(i + 0x01, pws, 0x0a); m_lblSections[i].Create(&m_pnlSections[i], wxID_ANY, ws); m_szrhSectionLabels[i]->Add(&m_lblSections[i] , 0x00, wxEXPAND | wxFIXED_MINSIZE | wxALL, 0x02); m_szrhSectionLabels[i]->AddStretchSpacer(); m_szrvSections[i]->AddStretchSpacer(); m_szrvSections[i]->Add(m_szrhSectionLabels[i], 0x00, wxEXPAND); m_szrvSections[i]->AddStretchSpacer(); m_nbkSections.AddPage(&m_pnlSections[i], m_SSections[i], false); m_nbkSections.Bind(wxEVT_AUINOTEBOOK_PAGE_CHANGED , &MainFrame::Onm_nbkSectionsChanged, this); } m_szrhFrame->Add(&m_nbkSections, 0x00 , wxEXPAND | wxFIXED_MINSIZE | wxALL, 0x02); m_pnlMain.Create(this); m_szrvMain = new wxBoxSizer(wxVERTICAL); m_pnlMain.SetSizer(m_szrvMain); m_szrhMainLabel = new wxBoxSizer(wxHORIZONTAL); m_lblMainPanel.Create(&m_pnlMain, wxID_ANY, L"Main Panel"); m_szrhMainLabel->AddStretchSpacer(); m_szrhMainLabel->Add(&m_lblMainPanel, 0x00 , wxEXPAND | wxFIXED_MINSIZE | wxALL, 0x02); m_szrhMainLabel->AddStretchSpacer(); m_szrvMain->AddStretchSpacer(); m_szrvMain->Add(m_szrhMainLabel, 0x00, wxEXPAND | wxALL, 0x02); m_szrvMain->AddStretchSpacer(); m_szrhFrame->Add(&m_pnlMain, 0x01, wxGROW | wxALL, 0x02); } else { m_szrhFrame->Detach(&m_pnlMain); for (int i = cisections - 0x01; i > -0x01; i--) { m_szrvSections[i]->Detach(m_szrhSectionLabels[i]); delete m_szrhSectionLabels[i]; m_szrhSectionLabels[i] = NULL; m_nbkSections.RemovePage(i); m_pnlSections[i].SetSizer(NULL); // Its sizer is destroyed automatically. m_szrvSections[i] = NULL; } m_szrhMainLabel->Detach(&m_lblMainPanel); m_szrvMain->Detach(m_szrhMainLabel); delete m_szrhMainLabel; m_szrhMainLabel = NULL; m_pnlMain.SetSizer(NULL); m_szrvMain = NULL; m_szrhFrame->Detach(&m_pnlMain); m_szrhFrame->Detach(&m_nbkSections); this->SetSizer(NULL); m_szrhFrame = NULL; } } //----------------------------------------------------------------------------
- Write down code for each section change event handler :
//---------------------------------------------------------------------------- void MainFrame::Onm_nbkSectionsChanged(wxAuiNotebookEvent &evt) { int isel = m_nbkSections.GetSelection(); ProcSectionChange((wxPanel *)m_nbkSections.GetPage(isel), (enSections)isel); } //---------------------------------------------------------------------------- void MainFrame::ProcSectionChange(wxPanel *pnl, enSections sec) { m_lblMainPanel.SetLabel(m_lblSections[sec].GetLabel() + L" : " + m_nbkSections.GetPageText(sec)); } //----------------------------------------------------------------------------
- And add the following statement in the constructor of the main frame for our main controls creation :
... m_SSections[secDirs] = L"Directories"; m_SSections[secProjects] = L"Projects"; AllocFreeMainControls(true); AllocFreeMenuBar(true); ...
- Add the following statement in the frame close event handler for the controls removal :
... if (m_bmpStatus) delete m_bmpStatus; AllocFreeMenuBar(false); AllocFreeMainControls(false); ...
- Run the project and we could see the following more-or-less decent application :
But!
Its icon seems to be missing from the left-most side of its title bar!
Now it's time to give it some meaningful icons: - If an RC file already exists inside [Resource Files] open it via [View Code] context menu
or right-click on the [Resource Files] category inside Visual Studio's [Solution Explorer].
Choose [Add...] --> [Resource...].There will be a lot of statements in it, already. Then delete all of them to write only the following single statement line for our application icon :
aaaICON ICON "wx_Ico_bettered.ico"
- Add the following statement in the top of its main constructor for its icon assignment :
//---------------------------------------------------------------------------- MainFrame::MainFrame(wxWindow *parent, wxWindowID id , const wxString &caption, const wxPoint &pos, const wxSize &size) : wxFrame(parent, id, caption, pos, size) { SetIcon(wxIcon(_("aaaICON"))); m_bmpStatus = NULL; ...
Then prepare the named icon ("wx_Ico_bettered.ico") in the project directory.
And rebuild the project. - Run the project and we could see the icon appear on its title bar :
- Now it is time for its main popup menu creation. The popup menu will be brought up whenever a mouse right-click event occurs inside the main panel :
- Declare a wxMenu variable for the popup menu in the private: section of the header file :
wxMenu *m_mnpMain;
- Add the following case statement line to the previously created GetItemKind method in the private: section of the header file :
... case msLangJpn: return wxITEM_RADIO; case 0x00: //<-- case mfSepOpen: case mfSepExit: ...
- Add the following statement to its constructor :
... m_mnpMain = NULL; // <-- Required. ...
- As it is popped up from the Main Panel, AllocFreeMainControls method needs to be changed like so for the panel to create it on the spot just before its invocation :
... m_pnlMain.Create(this); m_szrvMain = new wxBoxSizer(wxVERTICAL); m_pnlMain.SetSizer(m_szrvMain); m_pnlMain.Bind(wxEVT_RIGHT_DOWN, &MainFrame::OnMainPanelMouseRDown, this); // <-- ...
- Now let's create a method for the actual popup menu creation :
//---------------------------------------------------------------------------- void MainFrame::AllocFreePopupMenu(bool bAlloc) { wxMenuItem *pmi; //-------------------------------------------------------------------- const int ciids[] = { mfOpen, 0x00, meUndo, meRedo, 0x00, mhAbout }; const int ciitems = sizeof(ciids) / sizeof(*ciids); //-------------------------------------------------------------------- if (bAlloc) { if (m_mnpMain) return; wxString *pSs[] = { &m_SMenuFiles[mfOpen - IDM_FILE_START] , NULL, &m_SMenuEdits[meUndo - IDM_EDIT_START] , &m_SMenuEdits[meRedo - IDM_EDIT_START], NULL , &m_SMenuHelps[mhAbout - IDM_HELP_START] }; wxMenuItem *pmiMain; wxItemKind ikKind; m_mnpMain = new wxMenu; for (int i = 0x00; i < ciitems; i++) { ikKind = GetItemKind(ciids[i]); pmi = new wxMenuItem(m_mnpMain, ciids[i] , pSs[i]?(*pSs[i]):wxEmptyString, wxEmptyString, ikKind); pmiMain = m_menubar.FindItem(ciids[i]); if (pmiMain) { pmi->SetBitmap(pmiMain->GetBitmap(true), true); } m_mnpMain->Append(pmi); this->Bind(wxEVT_MENU, &MainFrame::OnMenuClicks, this, ciids[i]); } m_pnlMain.Bind(wxEVT_CONTEXT_MENU, &MainFrame::OnMainContextMenu, this); } else if (m_mnpMain) { for (int i = ciitems - 0x01; i > -0x01; i--) { pmi = m_mnpMain->Remove(ciids[i]); delete pmi; } delete m_mnpMain; m_mnpMain = NULL; } } //----------------------------------------------------------------------------
- Write down the popup menu creation method inside the main panel's right mouse button down event handler :
//---------------------------------------------------------------------------- void MainFrame::OnMainPanelMouseRDown(wxMouseEvent &evt) { if (NULL == m_mnpMain) AllocFreePopupMenu(true); } //------------------------------------------------------------------------
- Let the main panel invoke the popup menu :
//---------------------------------------------------------------------------- void MainFrame::OnMainContextMenu(wxContextMenuEvent &evt) { if (m_mnpMain) ((wxWindow *)evt.GetEventObject())->PopupMenu(m_mnpMain); } //----------------------------------------------------------------------------
- Finally add the popup menu destruction statement inside the frame's destructor :
.... AllocFreeMenuBar(false); AllocFreeMainControls(false); AllocFreePopupMenu(false); ....
- Let the application be known to other applications by giving it a title in case any other application or process needs it.
Then let's add the following statement in the constructor :
SetTitle(L"wxWidgets Sample Application v0.1");
- Run the project and we could bring up its main popup menu by right-clicking on the main panel as shown below :
Job Done !
Download Source code for the project (Visual C++ 2013) : src_Test_Toolbar(+sb+mnb+mnp).7z (868 KB)
No comments:
Post a Comment