Page 4 of 5

Posted: Thu Sep 30, 2010 1:16 pm
by jfouche
Do not use DECLARE_EVENT_TYPE and DEFINE_EVENT_TYPE with plugins. You must explicit the ID. I personnaly use enum in a
common header.

Posted: Thu Sep 30, 2010 1:52 pm
by evstevemd
jfouche wrote:Do not use DECLARE_EVENT_TYPE and DEFINE_EVENT_TYPE with plugins. You must explicit the ID. I personnaly use enum in a
common header.
Ah, I don't use them but I wanted to know how I can generate Unique IDs so that No two plugins will have same Id? Should I use wxWindow::GetId() in Connecting events or what? :roll:

Could you provide example how you do with two plugins (Only ID section) Because AFAIK two diferent Enum can have same numerical value.

Posted: Thu Sep 30, 2010 2:26 pm
by jfouche
Excuse me, I didn't read carefuly...
Can you provide a small example (by text), because I don't see the problem.

Posted: Thu Sep 30, 2010 2:37 pm
by xaviou
Hi
evstevemd wrote:Now that I can load Menus from DLL to App, I have question:
We know events are generated by App Menu and are connected to Specific wxID. So How do I ensure there is no ID conflict within plugins and that I have Unique ID?
You should use the wxNewId() and wxNewEventType() functions, so, you'll be sure that your IDs will be unique ones.
evstevemd wrote:Should I use wxWindow::GetId() in Connecting events or what?
That's (I think) the good way to do it.

Regards

Xav'

Posted: Thu Sep 30, 2010 2:52 pm
by jfouche
xaviou wrote:You should use the wxNewId() and wxNewEventType() functions, so, you'll be sure that your IDs will be unique ones.
I don't think so. In the application you'll have an instance of the static var which auto generate the IDs. In the plugin, you'll have another one. So you can have multiple IDs with the same values, even if you use wxNewId(). (I experienced it recently).

That's why I was talking about a unique common header file describe explicitly the available ID for events.
For the controls, I don't think there is problems, but I'm waiting for somebody to tell me I'm wrong :wink:

Posted: Thu Sep 30, 2010 3:46 pm
by xaviou
Hi
jfouche wrote:
xaviou wrote:You should use the wxNewId() and wxNewEventType() functions, so, you'll be sure that your IDs will be unique ones.
I don't think so. In the application you'll have an instance of the static var which auto generate the IDs. In the plugin, you'll have another one. So you can have multiple IDs with the same values, even if you use wxNewId(). (I experienced it recently).
I've just tested it, and Ids are uniques :

I have a host app, and a dll plugin.
The host app has a wxNoteBook : the first page is generated by the exe itself, and the other pages (only one, in the test), are generated by the plugins.
On both pages, I've put a button with the following code :

Code: Select all

void MainFrame::OnTest(wxCommandEvent &event)
{
    int id=wxNewId();
    wxString sMsg;
    sMsg.Printf(_T("New Id generated = %0d"), id);
    wxMessageBox(sMsg);
}

[code]void PluginPanel::OnButtonClicked(wxCommandEvent &event)
{
	static int i=0;
	i++;
	m_stBox->SetLabel(wxString::Format(_T("Click #%0d"),i));
	int id=wxNewId();
    wxString sMsg;
    sMsg.Printf(_T("New Id generated = %0d"), id);
    wxMessageBox(sMsg);
}

[/code]

If I press 2 times the "frame" button, I get the IDs "100" then "101"
Then, I press the "Plugin" button, and I get the ID "102"
If I come back to the frame button, I get "103", and so on.

As both the plugins and the host application use the dynamic version of the libs (if not, it won't work), the static var used is the same.


But I've just read something in the 2.9.1's doc : wxNewId and wxNewEventType will be deprecated, because they can conflict with IDs defined by the user code.
wxID_ANY is strongly recommended.

Regards

Xav'

Posted: Fri Oct 01, 2010 6:20 am
by evstevemd
Thanks guys,
I think I will go for wxID_ANY and wxWindow::GetId(). If I will need cleaner code I will go for Jeremie's dedicated header with enum.
Thanks again guys :)

Posted: Mon Oct 11, 2010 9:50 pm
by evstevemd
Hi Friends, I have faced the code I cannot understand.

Code: Select all

wxClassInfo::sm_classTable->BeginFind();

I checked the Manual and Couldn't find anything. Is it hidden somewhere?

Posted: Tue Oct 12, 2010 5:56 am
by xaviou
Hi.

This is part of the undocumented wxWidgets stuff :wink:

As I understood, the library has a static list of all dynamically registered classes (the ones whitch use the DECLARE_DYNAMIC_CLASS and IMPLEMENT_DYNAMIC_CLASS macros) : the name of this list is sm_classTable.

The code you pointed allow an interation into this list.

With wxWidgets-2.9.1, this code won't work, as the sm_classTable becomes private.

Regards

Xav'

Posted: Tue Oct 12, 2010 4:07 pm
by evstevemd
xaviou wrote:Hi.

This is part of the undocumented wxWidgets stuff :wink:

As I understood, the library has a static list of all dynamically registered classes (the ones whitch use the DECLARE_DYNAMIC_CLASS and IMPLEMENT_DYNAMIC_CLASS macros) : the name of this list is sm_classTable.

The code you pointed allow an interation into this list.

With wxWidgets-2.9.1, this code won't work, as the sm_classTable becomes private.

Regards

Xav'
i appreciate your ready help, sir. So then in future this technique will be having a problem! What methods can you and anyone propose? What about making extern C methods for exporting the class...just to hear your thought guys and girls on this.

Again, thanks

Posted: Tue Oct 12, 2010 4:41 pm
by xaviou
Hi

I've already tested, for the wxWidgets-2.9.1 migration of my app.

The sm_classTable becomes private, but new members are created (in <wx/object.h> of the wx-2.9.1 includes) :
  • static const_iterator begin_classinfo();
  • static const_iterator end_classinfo()
So, the (simplified) code

Code: Select all

wxHashTable_Node* node;
wxClassInfo::sm_classTable->BeginFind();
while((node = wxClassInfo::sm_classTable->Next()))
{
    wxClassInfo *classInfo = (wxClassInfo *)node->GetData();
    wxString classname = classInfo->GetClassName();
    if(classname.StartsWith(_T("wxTdlPlugin_")))
    {
        PluginBase *object = (PluginBase*)classInfo->CreateObject();
        m_plugins.Add(object);
    }
}
will become :

Code: Select all

wxClassInfo::const_iterator iter;
for (iter=wxClassInfo::begin_classinfo(); iter!=wxClassInfo::end_classinfo(); iter++)
{
    const wxClassInfo *classInfo = *iter;
    wxString classname = classInfo->GetClassName();
    if(classname.StartsWith(_T("wxTdlPlugin_")))
    {
        PluginBase *object = (PluginBase*)classInfo->CreateObject();
        m_plugins.Add(object);
    }
}
Regards
Xav'

Posted: Wed Oct 13, 2010 12:13 pm
by evstevemd
xaviou wrote:Hi

I've already tested, for the wxWidgets-2.9.1 migration of my app.

The sm_classTable becomes private, but new members are created (in <wx/object.h> of the wx-2.9.1 includes) :
  • static const_iterator begin_classinfo();
  • static const_iterator end_classinfo()
So, the (simplified) code

Code: Select all

wxHashTable_Node* node;
wxClassInfo::sm_classTable->BeginFind();
while((node = wxClassInfo::sm_classTable->Next()))
{
    wxClassInfo *classInfo = (wxClassInfo *)node->GetData();
    wxString classname = classInfo->GetClassName();
    if(classname.StartsWith(_T("wxTdlPlugin_")))
    {
        PluginBase *object = (PluginBase*)classInfo->CreateObject();
        m_plugins.Add(object);
    }
}
will become :

Code: Select all

wxClassInfo::const_iterator iter;
for (iter=wxClassInfo::begin_classinfo(); iter!=wxClassInfo::end_classinfo(); iter++)
{
    const wxClassInfo *classInfo = *iter;
    wxString classname = classInfo->GetClassName();
    if(classname.StartsWith(_T("wxTdlPlugin_")))
    {
        PluginBase *object = (PluginBase*)classInfo->CreateObject();
        m_plugins.Add(object);
    }
}
Regards
Xav'
ahsante sana (thanks a lot)

Posted: Tue Dec 28, 2010 7:47 pm
by evstevemd
I appreciate your help Xav and Jeremie I have come to the final part of my app (I halted for a time as I do this not as dedicated work, and time you knoq ;)). i have written Plugin interface and I'm about to write test plguin and then Manager. But I have question. In windows we need dllspec__ thing and I hope none in linux and I don't know in Mac. Is there a wx way to export plugins class from dll/so? How do you make a dll/so without doing changes to code?

I have searched forum and I have not found goog answe (may be i use bad leyword)

again, thanks alot for invaluable contributions

Posted: Wed Dec 29, 2010 10:23 am
by jfouche
Hello

There are 2 great wx macros : WXEXPORT and WXIMPORT.
Have a look to this wiki. This works for Windows, MAC and Linux.

But, for a simple function export, I do the following :

Code: Select all

#ifdef _WIN32
	#define EXPORT  __declspec(dllexport)
#else
	#define EXPORT
#endif


extern "C" EXPORT IPlugin* GetPlugin(IManager* manager)
{
   ...
}

Posted: Wed Dec 29, 2010 3:50 pm
by evstevemd
that is great! Thank you!