rewrote sample to have a more conventional structure (in preparation for further changes...)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@34859 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2005-07-15 21:05:48 +00:00
parent b3eb133b51
commit 874c5c9521

View File

@@ -14,15 +14,16 @@
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#include "wx/app.h" #include "wx/app.h"
#include "wx/log.h" #include "wx/frame.h"
#include "wx/menu.h"
#include "wx/msgdlg.h"
#include "wx/button.h"
#include "wx/datetime.h" #include "wx/datetime.h"
#include "wx/ffile.h" #include "wx/ffile.h"
#include "wx/filename.h" #include "wx/filename.h"
#include "wx/dynlib.h"
#include "wx/debugrpt.h" #include "wx/debugrpt.h"
#include "wx/msgdlg.h"
#if !wxUSE_DEBUGREPORT #if !wxUSE_DEBUGREPORT
#error "This sample can't be built without wxUSE_DEBUGREPORT" #error "This sample can't be built without wxUSE_DEBUGREPORT"
#endif // wxUSE_DEBUGREPORT #endif // wxUSE_DEBUGREPORT
@@ -31,6 +32,10 @@
#error "This sample can't be built without wxUSE_ON_FATAL_EXCEPTION" #error "This sample can't be built without wxUSE_ON_FATAL_EXCEPTION"
#endif // wxUSE_ON_FATAL_EXCEPTION #endif // wxUSE_ON_FATAL_EXCEPTION
#if !defined(__WXMSW__) && !defined(__WXPM__)
#include "../sample.xpm"
#endif
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// custom debug reporting class // custom debug reporting class
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -128,6 +133,35 @@ void foo(int n)
bar(wxT("even")); bar(wxT("even"));
} }
// ----------------------------------------------------------------------------
// main window
// ----------------------------------------------------------------------------
enum
{
DebugRpt_Quit = wxID_EXIT,
DebugRpt_Crash = 100,
DebugRpt_Current,
DebugRpt_Upload,
DebugRpt_About = wxID_ABOUT
};
class MyFrame : public wxFrame
{
public:
MyFrame();
private:
void OnQuit(wxCommandEvent& event);
void OnReportForCrash(wxCommandEvent& event);
void OnReportForCurrent(wxCommandEvent& event);
void OnReportUpload(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
DECLARE_NO_COPY_CLASS(MyFrame)
DECLARE_EVENT_TABLE()
};
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// application class // application class
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -139,63 +173,154 @@ void foo(int n)
class MyApp : public wxApp class MyApp : public wxApp
{ {
public: public:
virtual bool OnInit() // call wxHandleFatalExceptions here
{ MyApp();
wxHandleFatalExceptions();
if ( !wxApp::OnInit() ) // create our main window here
return false; virtual bool OnInit();
return true; // called when a crash occurs in this application
} virtual void OnFatalException();
virtual int OnRun() // this is where we really generate the debug report
{ void GenerateReport(wxDebugReport::Context ctx);
// a real program would be presumably be a bit harder to crash than
// just pressing "yes" in a dialog... but this is just an example // if this function is called, we'll use MyDebugReport which would try to
switch ( wxMessageBox // upload the (next) generated debug report to its URL, otherwise we just
( // generate the debug report and leave it in a local file
_T("Generate report for crash (or just current context)?"), void UploadReport(bool doIt) { m_uploadReport = doIt; }
_T("wxDebugReport Test"),
wxYES_NO | wxCANCEL private:
) ) bool m_uploadReport;
{
case wxYES: DECLARE_NO_COPY_CLASS(MyApp)
};
IMPLEMENT_APP(MyApp)
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// MyFrame
// ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(DebugRpt_Quit, MyFrame::OnQuit)
EVT_MENU(DebugRpt_Crash, MyFrame::OnReportForCrash)
EVT_MENU(DebugRpt_Current, MyFrame::OnReportForCurrent)
EVT_MENU(DebugRpt_Upload, MyFrame::OnReportUpload)
EVT_MENU(DebugRpt_About, MyFrame::OnAbout)
END_EVENT_TABLE()
MyFrame::MyFrame()
: wxFrame(NULL, wxID_ANY, _T("wxWidgets Debug Report Sample"))
{
SetIcon(wxICON(sample));
wxMenu *menuFile = new wxMenu;
menuFile->Append(DebugRpt_Quit, _T("E&xit\tAlt-X"));
wxMenu *menuReport = new wxMenu;
menuReport->Append(DebugRpt_Crash, _T("Report for &crash\tCtrl-C"),
_T("Provoke a crash inside the program and create report for it"));
menuReport->Append(DebugRpt_Current, _T("Report for c&urrent context\tCtrl-U"),
_T("Create report for the current program context"));
menuReport->AppendSeparator();
menuReport->AppendCheckItem(DebugRpt_Upload, _T("Up&load debug report"),
_T("You need to configure a web server accepting debug report uploads to use this function"));
wxMenu *menuHelp = new wxMenu;
menuHelp->Append(DebugRpt_About, _T("&About...\tF1"));
wxMenuBar *mbar = new wxMenuBar();
mbar->Append(menuFile, _T("&File"));
mbar->Append(menuReport, _T("&Report"));
mbar->Append(menuHelp, _T("&Help"));
SetMenuBar(mbar);
CreateStatusBar();
Show();
}
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close(true);
}
void MyFrame::OnReportForCrash(wxCommandEvent& WXUNUSED(event))
{
// this call is going to crash // this call is going to crash
foo(32); foo(32);
foo(17); foo(17);
break; }
case wxNO: void MyFrame::OnReportForCurrent(wxCommandEvent& WXUNUSED(event))
{
// example of manually generated report, this could be also // example of manually generated report, this could be also
// used in wxApp::OnAssert() // used in wxApp::OnAssert()
GenerateReport(wxDebugReport::Context_Current); wxGetApp().GenerateReport(wxDebugReport::Context_Current);
break; }
case wxCANCEL: void MyFrame::OnReportUpload(wxCommandEvent& event)
break; {
} wxGetApp().UploadReport(event.IsChecked());
}
return 0; void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
} {
wxMessageBox
(
_T("wxDebugReport sample\n(c) 2005 Vadim Zeitlin <vadim@wxwindows.org>"),
_T("wxWidgets Debug Report Sample"),
wxOK | wxICON_INFORMATION,
this
);
}
virtual void OnFatalException() // ----------------------------------------------------------------------------
{ // MyApp
// ----------------------------------------------------------------------------
MyApp::MyApp()
{
// user needs to explicitely enable this
m_uploadReport = false;
// call this to tell the library to call our OnFatalException()
wxHandleFatalExceptions();
}
bool MyApp::OnInit()
{
if ( !wxApp::OnInit() )
return false;
new MyFrame;
return true;
}
void MyApp::OnFatalException()
{
GenerateReport(wxDebugReport::Context_Exception); GenerateReport(wxDebugReport::Context_Exception);
} }
void GenerateReport(wxDebugReport::Context ctx) void MyApp::GenerateReport(wxDebugReport::Context ctx)
{ {
MyDebugReport report; wxDebugReportCompress *report = m_uploadReport ? new MyDebugReport
: new wxDebugReportCompress;
// add all standard files: currently this means just a minidump and an // add all standard files: currently this means just a minidump and an
// XML file with system info and stack trace // XML file with system info and stack trace
report.AddAll(ctx); report->AddAll(ctx);
// you can also call report.AddFile(...) with your own log files, files // you can also call report->AddFile(...) with your own log files, files
// created using wxRegKey::Export() and so on, here we just add a test // created using wxRegKey::Export() and so on, here we just add a test
// file containing the date of the crash // file containing the date of the crash
wxFileName fn(report.GetDirectory(), _T("timestamp.my")); wxFileName fn(report->GetDirectory(), _T("timestamp.my"));
wxFFile file(fn.GetFullPath(), _T("w")); wxFFile file(fn.GetFullPath(), _T("w"));
if ( file.IsOpened() ) if ( file.IsOpened() )
{ {
@@ -204,27 +329,35 @@ public:
file.Close(); file.Close();
} }
report.AddFile(fn.GetFullName(), _T("timestamp of this report")); report->AddFile(fn.GetFullName(), _T("timestamp of this report"));
// can also add an existing file directly, it will be copied // can also add an existing file directly, it will be copied
// automatically // automatically
#ifdef __WXMSW__ #ifdef __WXMSW__
report.AddFile(_T("c:\\autoexec.bat"), _T("DOS startup file")); report->AddFile(_T("c:\\autoexec.bat"), _T("DOS startup file"));
#else #else
report.AddFile(_T("/etc/motd"), _T("Message of the day")); report->AddFile(_T("/etc/motd"), _T("Message of the day"));
#endif #endif
// calling Show() is not mandatory, but is more polite // calling Show() is not mandatory, but is more polite
if ( wxDebugReportPreviewStd().Show(report) ) if ( wxDebugReportPreviewStd().Show(*report) )
{ {
if ( report.Process() ) if ( report->Process() )
{ {
// report successfully uploaded if ( m_uploadReport )
{
wxLogMessage(_T("Report successfully uploaded."));
}
else
{
wxLogMessage(_T("Report generated in \"%s\"."),
report->GetCompressedFileName().c_str());
report->Reset();
}
} }
} }
//else: user cancelled the report //else: user cancelled the report
}
};
IMPLEMENT_APP(MyApp) delete report;
}