Use of DECLARE_APP Macro Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Blinkinhek
Experienced Solver
Experienced Solver
Posts: 91
Joined: Tue Aug 16, 2005 10:54 am

Use of DECLARE_APP Macro

Post by Blinkinhek » Wed Nov 26, 2008 1:51 pm

I have the IMPLEMENT_APP(MyApp) macro in my main program module. I am trying to use DECLARE_APP(MyApp) in other modeles in order to use the function wxGetApp(). The problem is that the compiler kicks this out with an error:
"expected initializer before '&' token"

Looking at the definition of the macro in the wxWidgets app.h include file, DECLARE_APP equates to:

#define DECLARE_APP(appname) extern appname& wxGetApp();

So my compiler does not like the appname& part - so needs MyApp declaring also - but I am not sure how to do this (as the definitions/declarations of appname are all macroed up as well (am I making sense?)

The wxWidgets help file does not really give me any clues here on its usage ... any thoughts as to what I am doing wrong?

TIA

catalin
Moderator
Moderator
Posts: 1596
Joined: Wed Nov 12, 2008 7:23 am
Location: Romania

Post by catalin » Wed Nov 26, 2008 2:10 pm

http://docs.wxwidgets.org/stable/wx_app ... l#wxgetapp
Are you using DECLARE_APP in other "modeles"? or "modules" (which you shouldn't..) ? :)

Blinkinhek
Experienced Solver
Experienced Solver
Posts: 91
Joined: Tue Aug 16, 2005 10:54 am

Post by Blinkinhek » Wed Nov 26, 2008 2:21 pm

catalin wrote:http://docs.wxwidgets.org/stable/wx_app ... l#wxgetapp
Are you using DECLARE_APP in other "modeles"? or "modules" (which you shouldn't..) ? :)
yes I am using it in other modules - but that is my interpretation of the information provided. From the help file "Thus, before using it <ie wxGetApp> anywhere but in the same module where this macro is used, you must make it available using DECLARE_APP." ie to use exGetApp in another module, use DECLARE_APP.

I have just found another thread on this topic, but the resolution on that does not seem to be working for me.

User avatar
doublemax
Moderator
Moderator
Posts: 15512
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Post by doublemax » Wed Nov 26, 2008 2:24 pm

before using DECLARE_APP(appname) in a .cpp file you need to include the header file where your appname class gets declared.

Code: Select all

#include "myapp.h"
DECLARE_APP(myapp)
Use the source, Luke!

catalin
Moderator
Moderator
Posts: 1596
Joined: Wed Nov 12, 2008 7:23 am
Location: Romania

Post by catalin » Wed Nov 26, 2008 2:28 pm

Right, actually I have it myapp.h , just after the class declaration..

Blinkinhek
Experienced Solver
Experienced Solver
Posts: 91
Joined: Tue Aug 16, 2005 10:54 am

Post by Blinkinhek » Wed Nov 26, 2008 2:58 pm

doublemax wrote:before using DECLARE_APP(appname) in a .cpp file you need to include the header file where your appname class gets declared.

Code: Select all

#include "myapp.h"
DECLARE_APP(myapp)
oh dear, "it always gets darker before the dawn"!
I always start out trying to cleanly structure the program such that ModuleA + HeaderA are distinct and are stand-alone compared with ModuleB and HeaderB.

I can include these files as needed elsewhere without the pollution of cross-referencing.

Anyway, I put together a Main header, to declare MyApp. BUT because I need wxGetApp in other modules, I now have to include the main header in these other modules in order to use DECLARE_APP. BUT Because my declarations in MyApp also includes objects of other classes, in other modules, my main header has now to include all the other headers. So now I am cross-referencing all over the place. Probably not clear from my rambling without drawing up some class diagrams. The bottom line is that yes, your solution does work, so many thanks for that, I am just a little depressed about my program structure! (maybe I need lessons in structuring programs!!)

User avatar
doublemax
Moderator
Moderator
Posts: 15512
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Post by doublemax » Wed Nov 26, 2008 3:16 pm

well it is kinda ugly. Basically you're just dealing with a global variable "wxTheApp" here. The DECLARE_APP just casts it to your derived class so you can use its methods.

If you only need to call methods from the base class, you can use wxTheApp->method() directly without the dependency trouble.
Use the source, Luke!

Blinkinhek
Experienced Solver
Experienced Solver
Posts: 91
Joined: Tue Aug 16, 2005 10:54 am

Post by Blinkinhek » Wed Nov 26, 2008 10:56 pm

mmmhh sorry about this, but I still have a problem.

I extracted the class MyApp definitions into a myapp.h header - and this let the compiler pass the use of DECLARE_APP in other modules, however now, in my main.cpp module where I have my MyApp.OnInit() method, the IMPLEMENT_APP(MyApp) is now failing compile with the error message:
error: no matching function for call to `MyApp::MyApp()'
note: candidates are: MyApp::MyApp(const MyApp&)

basically my myapp.hpp has:
class AppFrame: public wxFrame
{
<stuff>
};
class MyApp : public wxApp
{
public:
virtual bool OnInit();
<other methods>
private:
<app variables and other stuff>
};

and my main.cpp has:

#include "myapp.hpp"
<stuff (defines, Event declarations etc>
IMPLEMENT_APP(MyApp);
bool MyApp::OnInit()
{
<create Frame>
<other initialisation>
return true;
}
<other MyApp methods>

...sigh ... a rocky road :)

User avatar
doublemax
Moderator
Moderator
Posts: 15512
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Post by doublemax » Wed Nov 26, 2008 11:51 pm

please use code tags, makes it easier to read the code.

I don't see anything wrong right now. Check the header file for small typos, forgotten semicolons or so.

Compare your code to one of the samples that use the IMPLEMENT/DECLARE macros.

If you still don't find anything, please post the complete codes, sometimes the error is where you don't expect it ;)
Use the source, Luke!

S.Volkenandt
Knows some wx things
Knows some wx things
Posts: 26
Joined: Tue Nov 14, 2006 1:51 pm
Location: Duesseldorf, Germany

Post by S.Volkenandt » Thu Nov 27, 2008 7:12 am

Blinkinhek wrote:error: no matching function for call to `MyApp::MyApp()'
note: candidates are: MyApp::MyApp(const MyApp&)
I guess anywhere within that <stuff>, <other methods> and <other stuff> is a constructor (with more than 0 arguments) that prevents the default constructor from being autogenerated.

Blinkinhek
Experienced Solver
Experienced Solver
Posts: 91
Joined: Tue Aug 16, 2005 10:54 am

Post by Blinkinhek » Thu Nov 27, 2008 9:27 pm

doublemax wrote:please use code tags, makes it easier to read the code.

I don't see anything wrong right now. Check the header file for small typos, forgotten semicolons or so.

Compare your code to one of the samples that use the IMPLEMENT/DECLARE macros.

If you still don't find anything, please post the complete codes, sometimes the error is where you don't expect it ;)
ok - will try and post the code tomorrow (I am away on business at the moment). As some additional info, when I directly selected and cut the class declaration from the include file and pasted, without modification, into the main.cpp file then the IMPLEMENT_APP macro worked ok. Reversing that process brought about the error message. I tried putting the IMPLEMENT_APP macro in the include file (protected by #ifdef statements to ensure it was only included once) and the error message ("...no matching function...") was displayed

Blinkinhek
Experienced Solver
Experienced Solver
Posts: 91
Joined: Tue Aug 16, 2005 10:54 am

Post by Blinkinhek » Fri Nov 28, 2008 3:42 pm

doublemax wrote:please use code tags, makes it easier to read the code.

I don't see anything wrong right now. Check the header file for small typos, forgotten semicolons or so.

Compare your code to one of the samples that use the IMPLEMENT/DECLARE macros.

If you still don't find anything, please post the complete codes, sometimes the error is where you don't expect it ;)

Code: Select all

// app part of main.cpp
#include <wx/wxprec.h>
#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#ifndef WX_PRECOMP
    #include <wx/wx.h>
#endif

#include "myapp.hpp"

#define VERSION 0.1
#define TITLE "Training App"

#define ID_MENU_QUIT 5000
#define ID_MENU_ABOUT 6000
#define ID_USERENTRY 7000
#define ID_OUTPUTFULL 8000
#define ID_OUTPUT     8500
#define ID_OUTPUTWRITE 9000

#define LOGFILENAME "c:\\Log.txt"     // just force this to root directory

BEGIN_DECLARE_EVENT_TYPES()
    DECLARE_EVENT_TYPE(wxEVT_POSTED_COMMAND, 7777)
END_DECLARE_EVENT_TYPES()
DEFINE_EVENT_TYPE(wxEVT_POSTED_COMMAND)

#define EVT_POSTED_COMMAND(id, fn) \
    DECLARE_EVENT_TABLE_ENTRY( \
        wxEVT_POSTED_COMMAND, id, wxID_ANY, \
        (wxObjectEventFunction)(wxEventFunction) wxStaticCastEvent( wxCommandEventFunction, &fn ), \
        (wxObject *) NULL \
    ),

//------------------------------------------------------------------------------

IMPLEMENT_APP(ThisApp);

bool ThisApp::OnInit()
{
    // get path of application
    wxStandardPaths AppPaths;
    m_currentworkingdirectory = AppPaths.GetDataDir();

	m_frame = new AppFrame(0L, TITLE);

	m_frame->Show();

    m_logfile.Create(LOGFILENAME, true, wxS_DEFAULT);
    m_logfile.Close();

	return true;
}

AppFrame& ThisApp::Frame(void)
{
    return *m_frame;
}

wxString& ThisApp::Input(void)
{
    return m_input;
}

wxString& ThisApp::CurrentWorkingDirectory(void)
{
    return m_currentworkingdirectory;
}

wxFile& ThisApp::LogFile()
{
    return m_logfile;
}

// include file myapp.hpp

#ifndef MYAPP_HPP
    #define MYAPP_HPP

    #ifndef WX_PRECOMP
        #include <wx/wx.h>
    #endif

#include <stdio.h>
#include <stdlib.h>
#include <wx/string.h>
#include <wx/listimpl.cpp>
#include <wx/tokenzr.h>
#include <time.h>
#include <wx/file.h>
#include <wx/list.h>
#include <wx/event.h>
#include <wx/memory.h>
#include <wx/app.h>
#include <wx/mstream.h>
#include "wx/msw/private.h"
#include <wx/dragimag.h>
#include <wx/toplevel.h>
#include <wx/timer.h>
#include <wx/stdpaths.h>
#include <wx/dir.h>
#include <wx/filename.h>

#include <wx/dynarray.h>
#include <wx/arrimpl.cpp>
#include <wx/app.h>

#include "common.hpp"
#include "net.hpp"

class AppFrame: public wxFrame
{
	public:
		AppFrame(wxFrame *frame, const wxString& title);
		~AppFrame();
	private:

		void OnQuit(wxCommandEvent& event);
		void OnAbout(wxCommandEvent& event);
		void OnRun(wxCommandEvent& event);
		void OnDefine(wxCommandEvent& event);
        void OnSize(wxSizeEvent &event);
        void OnUserEntry(wxCommandEvent &event);
        void OnIdle(wxIdleEvent &event);
        void OnFull(wxCommandEvent &event);
        void OnPostedEvent(wxCommandEvent& event);

        wxTextCtrl *Output;
        wxTextCtrl *UserEntry;

		DECLARE_EVENT_TABLE();
};

class ThisApp : public wxApp
{
	public:
        // these arrays contain the Card ID = cCard RftGCards[CardID]
		virtual bool OnInit();
		AppFrame& Frame(void);
        wxString& Input(void);
        wxString& CurrentWorkingDirectory(void);
        wxFile& LogFile();

    private:
        AppFrame* m_frame;

        wxAppTraits * AppTraits;
        wxString AppPath;
        wxString m_input;
        wxString m_currentworkingdirectory;
        wxFile m_logfile;
};

#endif

User avatar
doublemax
Moderator
Moderator
Posts: 15512
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Post by doublemax » Fri Nov 28, 2008 4:04 pm

after removing the references to parts that i don't have ("common.hpp", "net.hpp" and usage of AppFrame), the code compiled fine here...
Use the source, Luke!

Blinkinhek
Experienced Solver
Experienced Solver
Posts: 91
Joined: Tue Aug 16, 2005 10:54 am

Post by Blinkinhek » Fri Nov 28, 2008 10:23 pm

doublemax wrote:after removing the references to parts that i don't have ("common.hpp", "net.hpp" and usage of AppFrame), the code compiled fine here...
mmmh, thanks for that. I think that with this result, and the evidence of the other problems I am having with global variables, that the common factor is the minGw? (or maybe some of the default build options / defines that the IDE Codeblocks sets)

I think I will try dumping the rest of my code and see if the extract compiles, and if it doesn't work from there...

Many thanks for all your efforts to help!!

Post Reply