I am a novice in C++ and wxWidgets, and use wxFormBuilder to help me create the GUI.
I like the idea to put similar functions together in 1 module, which means that my apps have multiple modules.
One of the modules is for the GUI (it now contains code for the main Frame (with only a menu and taskbar) and
a Panel (with 2 StaticText controls and a button).
The button increments a counter and the value is shown in one of the StaticTexts on the Panel.
Sofar so good. (compiles without errors)
I can make the Panel show/Hide, but I seem to miss an essential piece of knowledge to make the Panel button work.
The ways I tried are all similar to the way the Main module is coded, but that is not working.
I understand how it works with GUI class elements in the same file.
However, I like to keep all GUI code in one module (GUIFrame.h/.cpp),
and all the 'function' code in e.g. the Panel module (MyPanel.h/.cpp).
Just because I am not sure where I make my mistake, I present all code in this post.
My aplologies if it is too much.
Hopefully someone can help me bridge my gap in knowledge about this way of working.
Regards,
Ruud
=== GUIFrame.h
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/string.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/menu.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/statusbr.h>
#include <wx/frame.h>
#include <wx/stattext.h>
#include <wx/button.h>
#include <wx/sizer.h>
#include <wx/panel.h>
///////////////////////////////////////////////////////////////////////////
#define idMenuQuit 1000
///////////////////////////////////////////////////////////////////////////////
/// Class GUIFrame
///////////////////////////////////////////////////////////////////////////////
class GUIFrame : public wxFrame
{
private:
protected:
wxMenuBar* mbar;
wxMenu* mainMenu;
wxStatusBar* statusBar;
// Virtual event handlers, overide them in your derived class
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
virtual void m_menuItemPanelMainOnMenuSelection( wxCommandEvent& event ) { event.Skip(); }
virtual void OnQuit( wxCommandEvent& event ) { event.Skip(); }
public:
GUIFrame( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Test application"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 500,500 ), long style = wxDEFAULT_FRAME_STYLE );
~GUIFrame();
};
///////////////////////////////////////////////////////////////////////////////
/// Class PanelMAIN
///////////////////////////////////////////////////////////////////////////////
class PanelMAIN : public wxPanel
{
private:
protected:
wxStaticText* m_staticText3;
// Virtual event handlers, overide them in your derived class
virtual void m_btn_Counter_OnButtonClick( wxCommandEvent& event ) { event.Skip(); }
public:
wxStaticText* m_staticTextPMain;
wxButton* m_buttonPMain;
PanelMAIN( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxPoint( 3,3 ), const wxSize& size = wxSize( 350,300 ), long style = wxBORDER_RAISED, const wxString& name = wxEmptyString );
~PanelMAIN();
};
==== GUIFrame.cpp
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif //__BORLANDC__
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif //WX_PRECOMP
#include "GUIFrame.h"
///////////////////////////////////////////////////////////////////////////
GUIFrame::GUIFrame( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
mbar = new wxMenuBar( 0 );
mainMenu = new wxMenu();
wxMenuItem* m_menuItemPanelMain;
m_menuItemPanelMain = new wxMenuItem( mainMenu, wxID_ANY, wxString( wxT("To Main Panel") ) , wxEmptyString, wxITEM_NORMAL );
mainMenu->Append( m_menuItemPanelMain );
wxMenuItem* menuFileQuit;
menuFileQuit = new wxMenuItem( mainMenu, idMenuQuit, wxString( wxT("&Quit") ) + wxT('\t') + wxT("Alt+F4"), wxT("Quit the application"), wxITEM_NORMAL );
mainMenu->Append( menuFileQuit );
mbar->Append( mainMenu, wxT("&Menu") );
this->SetMenuBar( mbar );
statusBar = this->CreateStatusBar( 2, wxSTB_SIZEGRIP, wxID_ANY );
// Connect Events
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( GUIFrame::OnClose ) );
mainMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIFrame::m_menuItemPanelMainOnMenuSelection ), this, m_menuItemPanelMain->GetId());
mainMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIFrame::OnQuit ), this, menuFileQuit->GetId());
}
GUIFrame::~GUIFrame()
{
// Disconnect Events
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( GUIFrame::OnClose ) );
}
PanelMAIN::PanelMAIN( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name )
{
this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_APPWORKSPACE ) );
wxBoxSizer* bSizer1;
bSizer1 = new wxBoxSizer( wxVERTICAL );
m_staticTextPMain = new wxStaticText( this, wxID_ANY, wxT("We are on PanelMAIN now"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextPMain->Wrap( -1 );
bSizer1->Add( m_staticTextPMain, 0, wxALL, 5 );
m_buttonPMain = new wxButton( this, wxID_ANY, wxT("Counter++"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer1->Add( m_buttonPMain, 0, wxALL, 5 );
m_staticText3 = new wxStaticText( this, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText3->Wrap( -1 );
bSizer1->Add( m_staticText3, 0, wxALL, 5 );
this->SetSizer( bSizer1 );
this->Layout();
// Connect Events
m_buttonPMain->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PanelMAIN::m_btn_Counter_OnButtonClick ), NULL, this );
}
PanelMAIN::~PanelMAIN()
{
// Disconnect Events
m_buttonPMain->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PanelMAIN::m_btn_Counter_OnButtonClick ), NULL, this );
}
==== wxPanelAPP.h
#ifndef WXPANELAPP_H
#define WXPANELAPP_H
#include <wx/app.h>
class wxPanelApp : public wxApp
{
public:
virtual bool OnInit();
};
#endif // WXPANELAPP_H
==== wxPanelAPP.cpp
#ifdef WX_PRECOMP
#include "wx_pch.h"
#endif
#ifdef __BORLANDC__
#pragma hdrstop
#endif //__BORLANDC__
#include "wxPanelApp.h"
#include "wxPanelMain.h"
IMPLEMENT_APP(wxPanelApp);
bool wxPanelApp::OnInit()
{
wxPanelFrame* frame = new wxPanelFrame(0L);
frame->SetIcon(wxICON(aaaa)); // To Set App Icon
frame->Show();
return true;
}
==== wxPanelMain.h
#ifndef WXPANELMAIN_H
#define WXPANELMAIN_H
#include "wxPanelApp.h"
#include "GUIFrame.h"
#include "MyPanel.h"
#include <iostream>
class wxPanelFrame: public GUIFrame
{
public:
wxPanelFrame(wxFrame *frame);
~wxPanelFrame();
wxPanel *m_wxpMain = new PanelMAIN(this, wxID_ANY);
private:
virtual void OnClose(wxCloseEvent& event);
virtual void OnQuit(wxCommandEvent& event);
void m_menuItemPanelMainOnMenuSelection( wxCommandEvent& event );
};
#endif // WXPANELMAIN_H
==== wxPanelMain.cpp
#ifdef WX_PRECOMP
#include "wx_pch.h"
#endif
#ifdef __BORLANDC__
#pragma hdrstop
#endif //__BORLANDC__
#include "wxPanelMain.h"
wxPanelFrame::wxPanelFrame(wxFrame *frame) : GUIFrame(frame)
{
#if wxUSE_STATUSBAR
statusBar->SetStatusText(_("Simple Panel Test"), 0);
#endif
// Hide the panel
m_wxpMain->Show(false);
}
wxPanelFrame::~wxPanelFrame()
{
}
void wxPanelFrame::OnClose(wxCloseEvent &event)
{
Destroy();
}
void wxPanelFrame::OnQuit(wxCommandEvent &event)
{
Destroy();
}
void wxPanelFrame::m_menuItemPanelMainOnMenuSelection( wxCommandEvent& event )
{
// Show the panel
m_wxpMain->Show(true);
}
==== MyPanel.h
#ifndef MYPANEL_H
#define MYPANEL_H
#include "GUIFrame.h"
#include <iostream>
class MyPanel : public PanelMAIN
{
public:
MyPanel(wxPanel *panel);
virtual ~MyPanel();
int i{0};
protected:
private:
void m_btn_Counter_OnButtonClick( wxCommandEvent& event );
};
#endif // MYPANEL_H
==== MyPanel.cpp
#include "MyPanel.h"
MyPanel::MyPanel(wxPanel *panel) : PanelMAIN(panel)
{
std::cout << "MyPanel::MyPanel /*CONSTRUCTOR*/\n";
}
MyPanel::~MyPanel()
{
std::cout << "MyPanel::~MyPanel /*DESTRUCTOR*/\n";
}
void MyPanel::m_btn_Counter_OnButtonClick( wxCommandEvent& event )
{
wxString wxs_Count{};
i++;
wxs_Count << i;
m_staticText3->SetLabelText(wxs_Count);
}
You define your event handler in your derived class MyPanel, but you never create and instance of it. The line
wxPanel *m_wxpMain = new PanelMAIN(this, wxID_ANY);
only creates on object of the base class.
You should change this to
MyPanel *m_wxpMain = new MyPanel(this);
You also have an problem with the constructor for MyPanel. The parent needs to be a wxWindow not wxPanel. So the declaration should be something like
MyPanel(wxWindow *panel);
and the body should look something like
MyPanel::MyPanel(wxWindow *panel) : PanelMAIN(panel)
{
std::cout << "MyPanel::MyPanel /*CONSTRUCTOR*/\n";
}
Related
This error is with wxWidgets 3.1.5, and SFML 2.5.1
I have the following code:
(main.cpp) :-
#include <SFML/Graphics.hpp>
#include <wx/wx.h>
#include "wxSfmlCanvas.h"
#include "main.h"
TestFrame::TestFrame() :
wxFrame(NULL, wxID_ANY, "SFML 2.5 w/ wxWidgets 3.1", wxDefaultPosition, wxSize(650, 490))
{
mCanvas = new TestSfmlCanvas(this, wxID_ANY, wxPoint(5, 25), wxSize(640, 480));
// Also add a button.
wxButton *button = new wxButton(
this,
wxID_ANY,
wxT("Toggle Size"),
wxPoint(5, 5)
);
button->Bind(wxEVT_BUTTON, [&](wxCommandEvent& arg) -> void {
mCanvas->toggleSize();
});
wxBoxSizer* mainSizer = new wxBoxSizer( wxVERTICAL );
mainSizer->Add(mCanvas, 6, wxALIGN_TOP | wxEXPAND);
mainSizer->Add(button, 0, wxALIGN_RIGHT | wxALIGN_BOTTOM);
SetSizerAndFit(mainSizer);
}
TestSfmlCanvas::TestSfmlCanvas(
wxWindow* Parent,
wxWindowID Id,
wxPoint& Position,
wxSize& Size,
long Style
) : wxSfmlCanvas(Parent, Id, Position, Size, Style),
mLarge(false)
{
// Load a texture and create a sprite.
mTexture.loadFromFile("data/ball.png");
mSprite = std::make_unique<sf::Sprite>(mTexture);
}
void
TestSfmlCanvas::OnUpdate()
{
clear(sf::Color(64, 196, 196));
draw(*mSprite);
}
void
TestSfmlCanvas::toggleSize()
{
if (mLarge) {
mSprite->setScale(sf::Vector2f(1.2f, 1.2f));
}
else {
mSprite->setScale(sf::Vector2f(0.5f, 0.5f));
}
mLarge = !mLarge;
}
IMPLEMENT_APP(TestApplication);
(and main.h) :-
#pragma once
#include <memory>
#include <SFML/Graphics.hpp>
#include <wx/wx.h>
#include <string>
#include "wxSfmlCanvas.h"
// Our overridden class that does some SFML drawing.
class TestSfmlCanvas : public wxSfmlCanvas
{
public:
TestSfmlCanvas(
wxWindow* Parent,
wxWindowID Id,
wxPoint& Position,
wxSize& Size,
long Style = 0
);
void toggleSize();
protected:
void OnUpdate() override;
private:
sf::Texture mTexture;
std::unique_ptr<sf::Sprite> mSprite;
bool mLarge;
};
// wx Frame to contain the main canvas control. Can have extra controls added to it as desired.
class TestFrame : public wxFrame
{
public :
TestFrame();
protected:
TestSfmlCanvas* mCanvas;
};
// Main wx Application instance.
class TestApplication : public wxApp
{
private :
virtual bool OnInit()
{
// Create the main window
TestFrame* MainFrame = new TestFrame;
MainFrame->Show();
return true;
}
};
(wxSFMLCanvas.h) :-
#pragma once
#include <SFML/Graphics.hpp>
#include <wx/wx.h>
#include <string>
class wxSfmlCanvas : public wxControl, public sf::RenderWindow
{
public:
wxSfmlCanvas(wxWindow* Parent = nullptr,
wxWindowID Id = -1,
//const wxPoint& Position = wxDefaultPosition,
const wxSize& Size = wxDefaultSize,
long Style = 0);
virtual ~wxSfmlCanvas();
protected:
virtual void OnUpdate();
void OnIdle(wxIdleEvent&);
void OnPaint(wxPaintEvent&);
void OnEraseBackground(wxEraseEvent&);
void OnSize(wxSizeEvent&);
DECLARE_EVENT_TABLE()
};
(wxSFMLCanvas.cpp) :-
#include "wxSfmlCanvas.h"
#include <wx/wx.h>
#include <string>
BEGIN_EVENT_TABLE(wxSfmlCanvas, wxControl)
EVT_PAINT(wxSfmlCanvas::OnPaint)
EVT_IDLE(wxSfmlCanvas::OnIdle)
EVT_ERASE_BACKGROUND(wxSfmlCanvas::OnEraseBackground)
EVT_SIZE(wxSfmlCanvas::OnSize)
END_EVENT_TABLE()
#ifdef __WXGTK__
#include <string>
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#include <wx/gtk/win_gtk.h>
#endif
wxSfmlCanvas::wxSfmlCanvas(wxWindow* Parent,
wxWindowID Id,
const wxPoint& Position,
const wxSize& Size,
long Style) :
wxControl(Parent, Id, Position, Size, Style)
{
#ifdef __WXGTK__
#else
sf::RenderWindow::create(GetHandle());
#endif
}
void wxSfmlCanvas::OnIdle(wxIdleEvent&)
{
// Send a paint message when the control is idle, to ensure maximum framerate
Refresh();
}
wxSfmlCanvas::~wxSfmlCanvas()
{
}
void wxSfmlCanvas::OnUpdate()
{
}
void wxSfmlCanvas::OnEraseBackground(wxEraseEvent&)
{
}
void wxSfmlCanvas::OnSize(wxSizeEvent& args)
{
// Set the size of the sfml rendering window
setSize(sf::Vector2u(args.GetSize().x, args.GetSize().y));
// Also adjust the viewport so that a pixel stays 1-to-1.
setView(sf::View(sf::FloatRect(0, 0, args.GetSize().x, args.GetSize().y)));
}
void wxSfmlCanvas::OnPaint(wxPaintEvent&)
{
// Prepare the control to be repainted
wxPaintDC Dc(this);
// Let the derived class do its specific stuff
OnUpdate();
// Display on screen
display();
}
With this code, I get the following compile errors:
Severity Code Description Project File Line Suppression State Error C4996 '_wgetenv': This function or variable may be unsafe. Consider using _wdupenv_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. ae D:\wxwidg\include\wx\wxcrt.h 1050
And 100 similar others.
Why? what did I do wrong for this?
wxWidgets is properly built, SFML and wx work fine on their own, but when combined, this error takes place for some reason.
The messages you show are not errors at all, they are static analyser warnings and can be safely ignored, the "unsafe" functions are not used in unsafe way inside wxWidgets.
I'm triying to color each tab on wxWidgets with a different color, like when you tag an Excel Sheet, is there a way to do that in the C++ version of wxWidgets, with or without AUI?
I don't think there is anything that will let you do this out of the box; but with an Aui notebook, you can write a custom tab art to color the tabs as you see fit. Here's a hideous example that I just threw together to demonstrate one way to do this:
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWidgets headers)
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include <wx/aui/auibook.h>
#include <map>
class MyTabArt:public wxAuiGenericTabArt
{
public:
MyTabArt():wxAuiGenericTabArt(){}
wxAuiTabArt* Clone()
{
return new MyTabArt(*this);
}
void AddTabColor(wxWindow* w, const wxColor& c)
{
m_tabColors[w] = c;
}
virtual void DrawTab(wxDC& dc, wxWindow* wnd, const wxAuiNotebookPage& page,
const wxRect& rect, int closeButtonState,
wxRect* outTabRect, wxRect* outButtonRect,
int* xExtent) wxOVERRIDE
{
wxSize tabSize = GetTabSize(dc, wnd, page.caption, page.bitmap,
page.active, closeButtonState, xExtent);
wxCoord tabHeight = m_tabCtrlHeight;
wxCoord tabWidth = tabSize.x;
wxCoord tabX = rect.x;
wxCoord tabY = rect.y + rect.height - tabHeight;
wxRect tabRect(tabX, tabY, tabWidth, tabHeight);
wxDCClipper clipper(dc, tabRect);
auto it = m_tabColors.find(page.window);
if ( it != m_tabColors.end() )
{
wxDCBrushChanger bchanger(dc, it->second);
wxDCPenChanger pchanger(dc, it->second);
dc.DrawRectangle(tabRect);
}
else
{
wxDCBrushChanger bchanger(dc, *wxGREEN);
wxDCPenChanger pchanger(dc, *wxGREEN);
dc.DrawRectangle(tabRect);
}
dc.DrawText(page.caption,tabRect.x,tabRect.y);
*outTabRect = tabRect;
}
private:
std::map<wxWindow*,wxColor> m_tabColors;
};
class MyFrame: public wxFrame
{
public:
MyFrame();
private:
};
MyFrame::MyFrame()
:wxFrame(NULL, wxID_ANY, "AUI Tab", wxDefaultPosition, wxSize(600, 400))
{
wxAuiNotebook * auiNotebook =
new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
wxPanel* panel1 = new wxPanel( auiNotebook, wxID_ANY );
wxPanel* panel2 = new wxPanel( auiNotebook, wxID_ANY );
auiNotebook->AddPage(panel1, "Page 1");
auiNotebook->AddPage(panel2, "Page 2");
MyTabArt* art = new MyTabArt();
art->AddTabColor(panel1, *wxRED);
art->AddTabColor(panel2, *wxBLUE);
auiNotebook->SetArtProvider(art);
}
class MyApp : public wxApp
{
public:
virtual bool OnInit()
{
::wxInitAllImageHandlers();
MyFrame* frame = new MyFrame();
frame->Show();
return true;
}
};
wxIMPLEMENT_APP(MyApp);
On windows, this monstrosity looks like this:
You can look at the source wxWidgets source for the other tab arts to see an example of how to make this prettier.
I followed the wxCrafter Hello World tutorial: https://wiki.codelite.org/pmwiki.php/Main/WxCrafterHelloWorld
Building process shows no errors, however no dialog shows up when I click "Build->Run" in CodeLite 13, for some reason nothing happens :/
main.cpp:
#include <wx/app.h>
#include <wx/event.h>
#include "MainDialog.h"
#include <wx/image.h>
// Define the MainApp
class MainApp : public wxApp
{
public:
MainApp() {}
virtual ~MainApp() {}
virtual bool OnInit() {
// Add the common image handlers
wxImage::AddHandler( new wxPNGHandler );
wxImage::AddHandler( new wxJPEGHandler );
MainDialog mainDialog(NULL);
mainDialog.ShowModal();
return false;
}
};
DECLARE_APP(MainApp)
IMPLEMENT_APP(MainApp)
MainDialog.h:
#ifndef MAINDIALOG_H
#define MAINDIALOG_H
#include "wxcrafter.h"
class MainDialog : public MainDialogBaseClass
{
public:
MainDialog(wxWindow* parent);
virtual ~MainDialog();
protected:
virtual void OnButtonokButtonClicked(wxCommandEvent& event);
};
#endif // MAINDIALOG_H
MainDialog.cpp:
#include "MainDialog.h"
#include <wx/msgdlg.h>
MainDialog::MainDialog(wxWindow* parent)
: MainDialogBaseClass(parent)
{
}
MainDialog::~MainDialog()
{
}
void MainDialog::OnButtonokButtonClicked(wxCommandEvent& event)
{
::wxMessageBox(_("Hello World"));
}
wxcrafter.h:
//////////////////////////////////////////////////////////////////////
// This file was auto-generated by codelite's wxCrafter Plugin
// wxCrafter project file: wxcrafter.wxcp
// Do not modify this file by hand!
//////////////////////////////////////////////////////////////////////
#ifndef _WORKSPACE_MEDCEN_PLUS_WXCRAFTER_BASE_CLASSES_H
#define _WORKSPACE_MEDCEN_PLUS_WXCRAFTER_BASE_CLASSES_H
#include <wx/artprov.h>
#include <wx/button.h>
#include <wx/dialog.h>
#include <wx/iconbndl.h>
#include <wx/settings.h>
#include <wx/sizer.h>
#include <wx/statline.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
#include <wx/xrc/xh_bmp.h>
#include <wx/xrc/xmlres.h>
#if wxVERSION_NUMBER >= 2900
#include <wx/persist.h>
#include <wx/persist/bookctrl.h>
#include <wx/persist/toplevel.h>
#include <wx/persist/treebook.h>
#endif
#ifdef WXC_FROM_DIP
#undef WXC_FROM_DIP
#endif
#if wxVERSION_NUMBER >= 3100
#define WXC_FROM_DIP(x) wxWindow::FromDIP(x, NULL)
#else
#define WXC_FROM_DIP(x) x
#endif
class MainDialogBaseClass : public wxDialog
{
protected:
wxStaticText* m_staticText21;
wxTextCtrl* m_textCtrl23;
wxStaticLine* m_staticLine15;
wxButton* m_buttonOK;
wxButton* m_buttonCancel;
protected:
virtual void OnButtonokButtonClicked(wxCommandEvent& event)
{
event.Skip();
}
public:
wxStaticText* GetStaticText21()
{
return m_staticText21;
}
wxTextCtrl* GetTextCtrl23()
{
return m_textCtrl23;
}
wxStaticLine* GetStaticLine15()
{
return m_staticLine15;
}
wxButton* GetButtonOK()
{
return m_buttonOK;
}
wxButton* GetButtonCancel()
{
return m_buttonCancel;
}
MainDialogBaseClass(wxWindow* parent,
wxWindowID id = wxID_ANY,
const wxString& title = _("My Dialog"),
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxSize(500, 300),
long style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
virtual ~MainDialogBaseClass();
};
#endif
wxcrafter.cpp:
//////////////////////////////////////////////////////////////////////
// This file was auto-generated by codelite's wxCrafter Plugin
// wxCrafter project file: wxcrafter.wxcp
// Do not modify this file by hand!
//////////////////////////////////////////////////////////////////////
#include "wxcrafter.h"
// Declare the bitmap loading function
extern void wxC9ED9InitBitmapResources();
static bool bBitmapLoaded = false;
MainDialogBaseClass::MainDialogBaseClass(wxWindow* parent,
wxWindowID id,
const wxString& title,
const wxPoint& pos,
const wxSize& size,
long style)
: wxDialog(parent, id, title, pos, size, style)
{
if(!bBitmapLoaded) {
// We need to initialise the default bitmap handler
wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
wxC9ED9InitBitmapResources();
bBitmapLoaded = true;
}
this->SetFocus();
wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
this->SetSizer(mainSizer);
wxBoxSizer* boxSizer19 = new wxBoxSizer(wxHORIZONTAL);
mainSizer->Add(boxSizer19, 1, wxALL | wxEXPAND, WXC_FROM_DIP(5));
m_staticText21 = new wxStaticText(
this, wxID_ANY, _("Static Text Label"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1, -1)), 0);
boxSizer19->Add(m_staticText21, 0, wxALL, WXC_FROM_DIP(5));
m_textCtrl23 = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1, -1)), 0);
#if wxVERSION_NUMBER >= 3000
m_textCtrl23->SetHint(wxT(""));
#endif
boxSizer19->Add(m_textCtrl23, 0, wxALL, WXC_FROM_DIP(5));
mainSizer->Add(0, 0, 1, wxALL | wxEXPAND, WXC_FROM_DIP(5));
m_staticLine15 =
new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1, -1)), wxLI_HORIZONTAL);
mainSizer->Add(m_staticLine15, 0, wxALL | wxEXPAND, WXC_FROM_DIP(5));
wxBoxSizer* boxSizer12 = new wxBoxSizer(wxHORIZONTAL);
mainSizer->Add(boxSizer12, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, WXC_FROM_DIP(5));
m_buttonOK = new wxButton(this, wxID_OK, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1, -1)), 0);
m_buttonOK->SetDefault();
boxSizer12->Add(m_buttonOK, 0, wxALL, WXC_FROM_DIP(5));
m_buttonCancel =
new wxButton(this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1, -1)), 0);
boxSizer12->Add(m_buttonCancel, 0, wxALL, WXC_FROM_DIP(5));
SetName(wxT("MainDialogBaseClass"));
SetSize(wxDLG_UNIT(this, wxSize(500, 300)));
if(GetSizer()) {
GetSizer()->Fit(this);
}
if(GetParent()) {
CentreOnParent(wxBOTH);
} else {
CentreOnScreen(wxBOTH);
}
#if wxVERSION_NUMBER >= 2900
if(!wxPersistenceManager::Get().Find(this)) {
wxPersistenceManager::Get().RegisterAndRestore(this);
} else {
wxPersistenceManager::Get().Restore(this);
}
#endif
// Connect events
m_buttonOK->Connect(
wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainDialogBaseClass::OnButtonokButtonClicked), NULL, this);
}
MainDialogBaseClass::~MainDialogBaseClass()
{
m_buttonOK->Disconnect(
wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainDialogBaseClass::OnButtonokButtonClicked), NULL, this);
}
Something is wrong with either the C::L installation or the wxCrafter plugin.
If you did follow the referenced tutorial, it should create a wxButton object as a member of the dialog and bind the event handler to it.
Can you compile and run the minimal sample from the wxWidgets install?
I have a simple frame which is containing some buttons. My aim is that, after clicking the GetMousePosition button, getting the first mouse click position. I try to capture mouse click, even if I click outside of the running application.
This is a desktop application running on Windows. I tried some mouse events that wxwidgets provides, but I couldn't handle the next click event. I tried to find a solution with following code, but if there is some different solution, I can throw that code in the trash.
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_BUTTON(BUTTON_GetPos, MyFrame::OnButtonClick)
EVT_MOUSE_EVENTS(MyFrame::OnMouseEvent)
EVT_MOUSE_CAPTURE_LOST(MyFrame::OnMouseCaptureLost)
END_EVENT_TABLE()
//some more code
void MyFrame::OnButtonClick(wxCommandEvent & WXUNUSED(event))
{
//Start Capturing for next mouse left-click
if (!HasCapture())
CaptureMouse();
}
void MyFrame::OnMouseEvent(wxMouseEvent &event)
{
if (event.LeftDown()) {
//GetMousePosition
if (HasCapture())
ReleaseMouse();
}
}
void MyFrame::OnMouseCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(event))
{
}
I expect to get the mouse position, in the first left click after the button is pressed.
The code you posted looks like it should work. If there's a problem, it might be in the code you omitted. Anyway, here's a small example application showing the behavior you want. The underlying logic of this example is the same as the code you posted, except this example uses dynamic binding instead of event tables.
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWidgets headers)
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
class MyFrame : public wxFrame
{
public:
MyFrame(wxWindow* parent);
protected:
void OnButtonClick(wxCommandEvent& event);
void OnMouseCapLost(wxMouseCaptureLostEvent& event);
void OnLeftDown(wxMouseEvent&);
void CleanUp();
private:
wxTextCtrl* m_textCtrl;
};
class MyApp : public wxApp
{
public:
virtual bool OnInit() wxOVERRIDE;
};
MyFrame::MyFrame(wxWindow* parent)
:wxFrame(parent, wxID_ANY, "Demo", wxDefaultPosition, wxDefaultSize,
wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL)
{
wxPanel* panel = new wxPanel(this, wxID_ANY );
wxButton* button = new wxButton(panel, wxID_ANY, "Click Me");
m_textCtrl = new wxTextCtrl(panel, wxID_ANY, wxEmptyString,
wxDefaultPosition, wxDefaultSize,
wxTE_DONTWRAP|wxTE_MULTILINE|wxTE_READONLY);
wxBoxSizer* bSizer = new wxBoxSizer(wxVERTICAL);
bSizer->Add(button, 0, wxALL, 5);
bSizer->Add(m_textCtrl, 1, wxALL|wxEXPAND, 5);
panel->SetSizer(bSizer);
Layout();
button->Bind(wxEVT_BUTTON,&MyFrame::OnButtonClick,this);
}
void MyFrame::OnButtonClick(wxCommandEvent& event)
{
if ( !HasCapture() )
{
CaptureMouse();
m_textCtrl->AppendText("Mouse captured.\n");
Bind(wxEVT_LEFT_DOWN, &MyFrame::OnLeftDown, this);
Bind(wxEVT_MOUSE_CAPTURE_LOST, &MyFrame::OnMouseCapLost, this);
}
}
void MyFrame::CleanUp()
{
if ( HasCapture() )
ReleaseMouse();
Unbind(wxEVT_LEFT_DOWN, &MyFrame::OnLeftDown, this);
Unbind(wxEVT_MOUSE_CAPTURE_LOST, &MyFrame::OnMouseCapLost, this);
}
void MyFrame::OnMouseCapLost(wxMouseCaptureLostEvent& event)
{
m_textCtrl->AppendText("Mouse cap lost.\n");
CleanUp();
}
void MyFrame::OnLeftDown(wxMouseEvent& event)
{
m_textCtrl->AppendText("Click recorded.\n");
CleanUp();
}
bool MyApp::OnInit()
{
MyFrame* frame = new MyFrame(NULL);
frame->Show();
return true;
}
wxIMPLEMENT_APP(MyApp);
I hope this helps.
edit: Here's a version using event tables as well:
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWidgets headers)
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#define BUTTON_ID 101
class MyFrame : public wxFrame
{
public:
MyFrame(wxWindow* parent);
protected:
void OnButtonClick(wxCommandEvent& event);
void OnMouseCapLost(wxMouseCaptureLostEvent& event);
void OnMouseEvent(wxMouseEvent&);
void CleanUp();
private:
wxTextCtrl* m_textCtrl;
wxDECLARE_EVENT_TABLE();
};
class MyApp : public wxApp
{
public:
virtual bool OnInit() wxOVERRIDE;
};
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_BUTTON(BUTTON_ID, MyFrame::OnButtonClick)
EVT_MOUSE_EVENTS(MyFrame::OnMouseEvent)
EVT_MOUSE_CAPTURE_LOST(MyFrame::OnMouseCapLost)
wxEND_EVENT_TABLE()
MyFrame::MyFrame(wxWindow* parent)
:wxFrame(parent, wxID_ANY, "Demo", wxDefaultPosition, wxDefaultSize,
wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL)
{
wxPanel* panel = new wxPanel(this, wxID_ANY );
wxButton* button = new wxButton(panel, BUTTON_ID, "Click Me");
m_textCtrl = new wxTextCtrl(panel, wxID_ANY, wxEmptyString,
wxDefaultPosition, wxDefaultSize,
wxTE_DONTWRAP|wxTE_MULTILINE|wxTE_READONLY);
wxBoxSizer* bSizer = new wxBoxSizer(wxVERTICAL);
bSizer->Add(button, 0, wxALL, 5);
bSizer->Add(m_textCtrl, 1, wxALL|wxEXPAND, 5);
panel->SetSizer(bSizer);
Layout();
}
void MyFrame::OnButtonClick(wxCommandEvent& event)
{
if ( !HasCapture() )
{
CaptureMouse();
m_textCtrl->AppendText("Mouse captured.\n");
}
}
void MyFrame::CleanUp()
{
if ( HasCapture() )
ReleaseMouse();
}
void MyFrame::OnMouseCapLost(wxMouseCaptureLostEvent& event)
{
m_textCtrl->AppendText("Mouse cap lost.\n");
CleanUp();
}
void MyFrame::OnMouseEvent(wxMouseEvent& event)
{
if( HasCapture() && event.LeftIsDown() )
{
m_textCtrl->AppendText("Click recorded.\n");
CleanUp();
}
}
bool MyApp::OnInit()
{
MyFrame* frame = new MyFrame(NULL);
frame->Show();
return true;
}
wxIMPLEMENT_APP(MyApp);
NOTE: I completely revised the question and turned it into an example project specifically for this question, so Nicks answer doesn't really make sense anymore. wxQuestionMain.h and wxQuestionMain.cpp are mildly modified wxWidget files, auto generated by Code::Blocks.
When I click the "Go" button I want the button event in "wxQuestionMain.cpp" to call "somefunction()" which is inside "otherFile.cpp". That works just fine. But I then want to change the text in the textbox "txtCtrl1" from inside "somefunction()" and that won't work because "somefunction()" is not part of the wxWidget class, and I don't want it to be. The wxwidget class is created in "wxQuestionMain.h".
wxQuestionMain.h -> Just creates the class
#ifndef WXQUESTIONMAIN_H
#define WXQUESTIONMAIN_H
#define BOOST_FILESYSTEM_VERSION 2
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include "wxQuestionApp.h"
#include <wx/button.h>
#include <wx/statline.h>
class wxQuestionDialog: public wxDialog
{
public:
wxQuestionDialog(wxDialog *dlg, const wxString& title);
~wxQuestionDialog();
protected:
enum
{
idBtnGo = 1000
};
wxStaticText* m_staticText1;
wxStaticLine* m_staticline1;
wxButton* BtnGo;
wxTextCtrl* textCtrl1;
private:
void OnClose(wxCloseEvent& event);
void OnGo(wxCommandEvent& event);
DECLARE_EVENT_TABLE()
};
void somefunction();
#endif // WXQUESTIONMAIN_H
wxQuestionMain.cpp -> Lots of yadda yadda and then at the very bottom the function that handles the buttonclick event.
#ifdef WX_PRECOMP
#include "wx_pch.h"
#endif
#ifdef __BORLANDC__
#pragma hdrstop
#endif //__BORLANDC__
#include "wxQuestionMain.h"
//helper functions
enum wxbuildinfoformat {
short_f, long_f };
wxString wxbuildinfo(wxbuildinfoformat format)
{
wxString wxbuild(wxVERSION_STRING);
if (format == long_f )
{
#if defined(__WXMSW__)
wxbuild << _T("-Windows");
#elif defined(__WXMAC__)
wxbuild << _T("-Mac");
#elif defined(__UNIX__)
wxbuild << _T("-Linux");
#endif
#if wxUSE_UNICODE
wxbuild << _T("-Unicode build");
#else
wxbuild << _T("-ANSI build");
#endif // wxUSE_UNICODE
}
return wxbuild;
}
BEGIN_EVENT_TABLE(wxQuestionDialog, wxDialog)
EVT_CLOSE(wxQuestionDialog::OnClose)
EVT_BUTTON(idBtnGo, wxQuestionDialog::OnGo)
END_EVENT_TABLE()
wxQuestionDialog::wxQuestionDialog(wxDialog *dlg, const wxString &title)
: wxDialog(dlg, -1, title)
{
this->SetSizeHints(wxDefaultSize, wxDefaultSize);
wxBoxSizer* bSizer1;
bSizer1 = new wxBoxSizer(wxHORIZONTAL);
m_staticText1 = new wxStaticText(this, wxID_ANY, wxT("Welcome To\nwxWidgets"), wxDefaultPosition, wxDefaultSize, 0);
m_staticText1->SetFont(wxFont(20, 74, 90, 90, false, wxT("Arial")));
bSizer1->Add(m_staticText1, 0, wxALL|wxEXPAND, 5);
wxBoxSizer* bSizer2;
bSizer2 = new wxBoxSizer(wxVERTICAL);
wxPoint textCtrl1Position(5,5); //Position
wxSize textCtrl1size(120,25); //Size
textCtrl1 = new wxTextCtrl(this, wxID_ANY, "hi", wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, "textCtrl1"); //Create textCtrl
bSizer2->Add(textCtrl1, 0, wxALL|wxEXPAND, 5); //Add to sizer
m_staticline1 = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
bSizer2->Add(m_staticline1, 0, wxALL|wxEXPAND, 5);
BtnGo = new wxButton(this, idBtnGo, wxT("&Go"), wxDefaultPosition, wxDefaultSize, 0);
bSizer2->Add(BtnGo, 0, wxALL, 5);
bSizer1->Add(bSizer2, 1, wxEXPAND, 5);
this->SetSizer(bSizer1);
this->Layout();
bSizer1->Fit(this);
}
wxQuestionDialog::~wxQuestionDialog()
{
}
void wxQuestionDialog::OnClose(wxCloseEvent &event)
{
Destroy();
}
void wxQuestionDialog::OnGo(wxCommandEvent &event)
{
somefunction();
}
otherFile.cpp:
#include "wxQuestionMain.h"
void somefunction()
{
//Try to change the text in textCtrl1
wxQuestionDialog::textCtrl1->AppendText("Red text\n");
}
Produces:
error: ‘wxTextCtrl* wxQuestionDialog::textCtrl1’ is protected
error: invalid use of non-static data member ‘wxQuestionDialog::textCtrl1’
So I moved 'wxTextCtrl* textCtrl1;' in 'wxQuestionMain.h' from 'protected' to 'public'
Produces:
error: invalid use of non-static data member ‘wxQuestionDialog::textCtrl1’
The class in wxQuestionMain.h seems to sais 'class wxQuestionDialog: public wxDialog'
I don't know what that "public" part means, I've never seen a class be created like that before, but I'm going to try to change 'otherFile.cpp' so it sais wxDialog instead of wxQuestionDialog.
#include "wxQuestionMain.h"
void somefunction()
{
//Try to change the text in textCtrl1
wxDialog::textCtrl1->AppendText("Red text\n");
}
Produces:
error: ‘textCtrl1’ is not a member of ‘wxDialog’
I'm at a loss here.. how can I update the text in "textCtrl1" without adding "somefunction()" to the wxWidget class?
CodeBlocks auto generated 2 other files, not sure if they are important, but here they are.
wxQuestionApp.cpp
#ifdef WX_PRECOMP
#include "wx_pch.h"
#endif
#ifdef __BORLANDC__
#pragma hdrstop
#endif //__BORLANDC__
#include "wxQuestionApp.h"
#include "wxQuestionMain.h"
IMPLEMENT_APP(wxQuestionApp);
bool wxQuestionApp::OnInit()
{
wxQuestionDialog* dlg = new wxQuestionDialog(0L, _("wxWidgets Application Template"));
dlg->Show();
return true;
}
wxQuestionApp.h
#ifndef WXQUESTIONAPP_H
#define WXQUESTIONAPP_H
#include <wx/app.h>
class wxQuestionApp : public wxApp
{
public:
virtual bool OnInit();
};
#endif // WXQUESTIONAPP_H
addtolistbox2 is a private member method of gfxDialog - even if you did have a properly constructed object, you wouldn't be able to call that method from outside a gfxDialog instance. At the very least you need to move addtolistbox2 to public: from private:, and then call it on a properly constructed instance (the constructor requires arguments but your code doesn't provide them):
gfxDialog testtime(0, "test");
testtime.addtolistbox2("somestring");
(The only valid constructor requires a parent dialog and a title string:
class gfxDialog: public wxDialog
{
public:
gfxDialog(wxDialog *dlg, const wxString& title);
if I remember my wxWidgets properly, the parent may be NULL, but of course you still have to provide the argument)