There are several functions which aren't directly visible in the GUI of an application and therefore often get forgotten.
Since some OpenSource seems to crash (IMO happens too often) it's necessary to report the crash stack trace with as much as possible information. This can be achieved under GTK with wxCrashPrint, of course only if the debug symbols are available. Under Windows it's possible through the use of the BlackBox.dll (see here).
#if defined(__linux__) #include "wx/crashprint.h" // CrashPrint backtrace #endif ... #if defined(__linux__) //! crashprint wxCrashPrint g_crashprint; #endif ... class App: public wxApp { public: //! the main function called durning application start virtual bool OnInit (); #if defined(__linux__) //! fatal exeption handling void OnFatalException(); #endif ... } bool App::OnInit () { #if defined(__linux__) // fatal exceptions handling wxHandleFatalExceptions (true); #endif ... } #if defined(__linux__) void App::OnFatalException () { g_crashprint.Report(); } #endif
Don't forget to add the crashprint sources to your project, they aren't currently part of wxWidgets but from wxCode.
#include <wx/dynlib.h> // dynamic library support ... class App: public wxApp { public: //! the main function called durning application start virtual bool OnInit (); //! application exit function virtual int OnExit (); ... private: #if defined(__WINDOWS__) //! BlackBox dll (crash handling) wxDynamicLibrary m_blackboxDll; #endif ... } bool App::OnInit () { #if defined(__WINDOWS__) // BlackBox dll (crash handling) m_blackboxDll.Load (_T("BlackBox.dll")); #endif ... } int App::OnExit () { #if defined(__WINDOWS__) // unload BlackBox dll if (m_blackboxDll.IsLoaded()) m_blackboxDll.Unload (); #endif ... }
The command line is usually associated with non-GUI application but that isn't true. When a system allows starting an app with parameters these are sent to the application as a command line. Therefore any app should handle command lines. The following sample shows how to handle filenames sent through the command line.
#include <wx/cmdline.h> // command line support class App: public wxApp { friend class AppFrame; ... //! command line wxArrayString *m_fnames; bool ProcessCmdLine (wxChar** argv, int argc = 0); }; bool App::OnInit () { ... // get and process command line m_fnames = new wxArrayString(); ProcessCmdLine (argv, argc); ... } int App::OnExit () { ... // delete command line fnames if (m_fnames) delete m_fnames; ... } bool App::ProcessCmdLine (wxChar** argv, int argc) { // get and process command line static const wxCmdLineEntryDesc cmdLineDesc[] = { {wxCMD_LINE_PARAM, NULL, NULL, _T("input files"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE}, {wxCMD_LINE_NONE} }; wxCmdLineParser parser (cmdLineDesc, argc, argv); // get filenames from the command line m_fnames->Clear(); if (parser.Parse() == 0) { for (size_t paramNr=0; paramNr < parser.GetParamCount(); paramNr++) { m_fnames->Add (parser.GetParam (paramNr)); } } return true; }
Usually an application which opens files should also allow dropping files onto it. Be carefully where (onto which window) files can be dropped.
static wxString g_appname; class AppFrame: public wxFrame { friend class DropFiles; ... }; class DropFiles: public wxFileDropTarget { public: //! constructor DropFiles (AppFrame *frame) {m_frame = frame;} virtual bool OnDropFiles (wxCoord x, wxCoord y, const wxArrayString& filenames); private: AppFrame *m_frame; }; AppFrame::AppFrame (... ... // initialize drop files SetDropTarget (new DropFiles (this)); ... }; bool DropFiles::OnDropFiles (wxCoord x, wxCoord y, const wxArrayString& filenames) { for (size_t n = 0; n < filenames.Count(); n++) { if (wxFileName(filenames[n]).IsDir()) { wxMessageBox (_("It is currently not allowed to drop \n" "directories onto the editor!"), _("Error"), wxOK | wxICON_EXCLAMATION); return FALSE; } } m_frame->FileOpen (filenames); m_frame->m_book->SetFocus(); wxString title = g_appname + " " + m_frame->m_edit->GetFilename(); m_frame->SetTitle (title); return TRUE; }