Page 1 of 1

Fire an event

Posted: Wed Dec 17, 2008 10:31 am
by kea_
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_

Posted: Wed Dec 17, 2008 2:20 pm
by tan
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

Posted: Wed Dec 17, 2008 2:31 pm
by kea_
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_

Posted: Wed Dec 17, 2008 4:15 pm
by tan
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.

Posted: Thu Dec 18, 2008 5:30 am
by kea_
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_

Posted: Thu Dec 18, 2008 6:45 am
by tan
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.