Fire an event Topic is solved

Are you writing your own components and need help with how to set them up or have questions about the components you are deriving from ? Ask them here.
Post Reply
kea_
Experienced Solver
Experienced Solver
Posts: 59
Joined: Wed Oct 17, 2007 7:32 am

Fire an event

Post by kea_ » Wed Dec 17, 2008 10:31 am

Hello together,

not quit sure if it's a widget or a linking problem.
I like to create my own button if I compile it width release (static libs) mode it works but it doesn't work width debug (shared libs) mode.

I get this error:
-------------- Build: Debug in MyCustomEvent ---------------

Linking executable: bin\Debug\MyCustomEvent.exe
obj\Debug\MyFrame.o: In function `Z41__static_initialization_and_destruction_0ii':
D:/my_projects/cpp/MyCustomEvent/MyFrame.cpp:6: undefined reference to `_imp__CP_BUTTON_CLICKED'
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 0 seconds)
1 errors, 0 warnings


This is a part of my source code:
cpMyButton.h

Code: Select all

#ifndef CP_MYBUTTON_H
#define CP_MYBUTTON_H

#include <wx/scrolwin.h>
#include <wx/colour.h>
#include <wx/dcbuffer.h>
#include <wx/settings.h>
#include <wx/event.h>


DEFINE_EVENT_TYPE(CP_BUTTON_CLICKED)
DECLARE_EVENT_TYPE(CP_BUTTON_CLICKED, -1)

class cpMyButton : public wxScrolledWindow
{
    DECLARE_EVENT_TABLE();

	public:
		// FUNCTIONS
		cpMyButton(wxWindow *wParent, wxWindowID iWindowId, wxString sLabel = "");
		~cpMyButton();
		void cpMyButton::SetFont(wxFont font);

		// PARAMETERS

	protected:
		// FUNCTION
		// PARAMETER

	private:
		// FUNCTIONS
		void FireButtonClickedEvent();

		// PARAMETERS
		int m_iMouseEvent;

		// EVENTS
        void OnPaint(wxPaintEvent& WXUNUSED(event));
        void OnEraseBackground(wxEraseEvent& event);
        void OnEnter(wxMouseEvent & event);
        void OnLeave(wxMouseEvent & event);
        void OnLeftUp(wxMouseEvent & event);

	enum{
		ID_DUMMY_VALUE_
	};
};



#endif // CP_MYBUTTON_H
cpMyButton.cpp

Code: Select all

#include "cpMyButton.h"


BEGIN_EVENT_TABLE(cpMyButton, wxScrolledWindow)
    EVT_ERASE_BACKGROUND(cpMyButton::OnEraseBackground)
    EVT_PAINT(cpMyButton::OnPaint)
    EVT_ENTER_WINDOW(cpMyButton::OnEnter)
    EVT_LEAVE_WINDOW(cpMyButton::OnLeave)
    EVT_LEFT_UP(cpMyButton::OnLeftUp)
END_EVENT_TABLE()


cpMyButton::cpMyButton(wxWindow *wParent, wxWindowID iWindowId, wxString sLabel)
          : wxScrolledWindow(wParent, iWindowId, wxDefaultPosition, wxDefaultSize, wxHSCROLL | wxVSCROLL | wxNO_BORDER | wxFULL_REPAINT_ON_RESIZE){
    SetLabel("Button_1");

    int iWidth, iHeight;
    GetTextExtent(GetLabel(), &iWidth, &iHeight);
    iHeight += 2;
    iWidth += 4;
    SetSize(iWidth, iHeight);

    m_iMouseEvent = 1;
}


cpMyButton::~cpMyButton(){}


// fire event: click
void cpMyButton::FireButtonClickedEvent(){
    wxCommandEvent evt(CP_BUTTON_CLICKED, GetId());
    evt.SetEventObject(this);
    GetEventHandler()->ProcessEvent(evt);
}


// *** E V E N T S ***********
void cpMyButton::OnEraseBackground(wxEraseEvent& event){}


void cpMyButton::OnPaint(wxPaintEvent& WXUNUSED(event)){
    wxBufferedPaintDC dc(this);
    PrepareDC(dc);
    dc.Clear();
    dc.SetFont(GetParent()->GetFont());

    if(m_iMouseEvent == 0){
        dc.SetTextForeground(wxColour("#2d37c4"));
    }else if(m_iMouseEvent == 1){
        dc.SetTextForeground(wxColour("#000000"));
    }

    dc.DrawText(GetLabel(), 2, 0);
}

void cpMyButton::OnEnter(wxMouseEvent &event){
    m_iMouseEvent = 0;
    Refresh();
}


void cpMyButton::OnLeave(wxMouseEvent &event){
    m_iMouseEvent = 1;
    Refresh();
}


void cpMyButton::OnLeftUp(wxMouseEvent &event){
    FireButtonClickedEvent();
}
MyFrame.h

Code: Select all

#ifndef MY_FRAME_H
#define MY_FRAME_H

#include "cpMyButton.h"
#include "dgMyDialog.h"
#include <wx/frame.h>
#include <wx/panel.h>
#include <wx/stattext.h>


class MyFrame : public wxFrame
{
    DECLARE_EVENT_TABLE();

	public:
		// FUNCTION
		MyFrame(wxWindow *wParent);
		~MyFrame();

		// PARAMETER

	protected:
		// FUNCTION
		// PARAMETER

	private:
		// FUNCTION
		cpMyButton *m_button;
		wxStaticText *m_text;

		// PARAMETER
		// EVENTS
		void OnButton(wxCommandEvent &event);

		enum{
            ID_BUTTON = 1,
			ID_DUMMY_VALUE_
		};
};



#endif // MY_FRAME_H
MyFrame.cpp

Code: Select all

#include "MyFrame.h"


BEGIN_EVENT_TABLE(MyFrame, wxFrame)
    EVT_COMMAND(ID_BUTTON, CP_BUTTON_CLICKED, MyFrame::OnButton)
END_EVENT_TABLE()


MyFrame::MyFrame(wxWindow *wParent)
       : wxFrame(wParent, ID_DUMMY_VALUE_, "MyFrame", wxDefaultPosition, wxDefaultSize, wxCAPTION | wxRESIZE_BORDER | wxSYSTEM_MENU | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxCLOSE_BOX | wxNO_FULL_REPAINT_ON_RESIZE){

    wxPanel *p = new wxPanel(this, ID_DUMMY_VALUE_);
    m_button = new cpMyButton(p, ID_BUTTON);
    m_text = new wxStaticText(p, ID_DUMMY_VALUE_, "--", wxPoint(1, 20));
}


MyFrame::~MyFrame(){
    delete m_button;
    delete m_text;
}


// **  E V E N T S  ***
void MyFrame::OnButton(wxCommandEvent &event){
    dgMyDialog *mdg = new dgMyDialog(this);
    mdg->ShowModal();
    delete mdg;
    m_text->SetLabel("OK");
}
Has any body an idea?

Thank you for your help.
kea_

tan
Moderator
Moderator
Posts: 1471
Joined: Tue Nov 14, 2006 7:58 am
Location: Saint-Petersburg, Russia

Post by tan » Wed Dec 17, 2008 2:20 pm

Hi,
try replace

Code: Select all

DEFINE_EVENT_TYPE(CP_BUTTON_CLICKED)
DECLARE_EVENT_TYPE(CP_BUTTON_CLICKED, -1)
to

Code: Select all

DEFINE_LOCAL_EVENT_TYPE(CP_BUTTON_CLICKED)
DECLARE_LOCAL_EVENT_TYPE(CP_BUTTON_CLICKED, -1)
in the cpMyButton.h
OS: Windows XP Pro
Compiler: MSVC++ 7.1
wxWidgets: 2.8.10

kea_
Experienced Solver
Experienced Solver
Posts: 59
Joined: Wed Oct 17, 2007 7:32 am

Post by kea_ » Wed Dec 17, 2008 2:31 pm

Thank you for the answer,

but unfortunately it does the same.
For me it's strange that it works on the release width static libs and it doesn't work width the dll libs.

It must be something there.

Tanks for the answer
kea_

tan
Moderator
Moderator
Posts: 1471
Joined: Tue Nov 14, 2006 7:58 am
Location: Saint-Petersburg, Russia

Post by tan » Wed Dec 17, 2008 4:15 pm

First, you have to define in the cpMyButton.cpp, not in the cpMyButton.h
Second, as i mentioned earlier you have to declare it as LOCAL event type to work with dynamic linking:

cpMyButton.h

Code: Select all

...
DECLARE_LOCAL_EVENT_TYPE(CP_BUTTON_CLICKED, -1)
...
cpMyButton.cpp

Code: Select all

...
DEFINE_LOCAL_EVENT_TYPE(CP_BUTTON_CLICKED)
...
Rebuild the project, it should work.
OS: Windows XP Pro
Compiler: MSVC++ 7.1
wxWidgets: 2.8.10

kea_
Experienced Solver
Experienced Solver
Posts: 59
Joined: Wed Oct 17, 2007 7:32 am

Post by kea_ » Thu Dec 18, 2008 5:30 am

Hi tan,

thank you for your great help.
Now it works. It's strange that it worked width static libs.

Thank you very much.

kea_

tan
Moderator
Moderator
Posts: 1471
Joined: Tue Nov 14, 2006 7:58 am
Location: Saint-Petersburg, Russia

Post by tan » Thu Dec 18, 2008 6:45 am

kea_ wrote:Hi tan,

thank you for your great help.
Now it works.
Glad to hear it :)
kea_ wrote: It's strange that it worked width static libs.
It isn't strange. With shared libs DECLARE_EVENT_TYPE() is expanded to DECLARE_EXPORTED_EVENT_TYPE() then it generates in turn __declspec(dllexport/dllimport) attribute for event type. But you actually doesn't import the event type, because it is placed in the same module. So you have to explicitly declare it as local event type. With static libs compiler interprets all declarations as local (without dllimport/dllexport attribute).

BTW, i believe you wished to accept my answer :), i unaccepted the thread for that.
OS: Windows XP Pro
Compiler: MSVC++ 7.1
wxWidgets: 2.8.10

Post Reply