appbase.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 848 行 · 第 1/2 页
CPP
848 行
#if 0 // can't use wxLogTrace, not up and running yet
printf("checking build options object '%s' (ptr %p) in '%s'\n",
optionsSignature, optionsSignature, componentName);
#endif
if ( strcmp(optionsSignature, WX_BUILD_OPTIONS_SIGNATURE) != 0 )
{
wxString lib = wxString::FromAscii(WX_BUILD_OPTIONS_SIGNATURE);
wxString prog = wxString::FromAscii(optionsSignature);
wxString progName = wxString::FromAscii(componentName);
wxString msg;
msg.Printf(_T("Mismatch between the program and library build versions detected.\nThe library used %s,\nand %s used %s."),
lib.c_str(), progName.c_str(), prog.c_str());
wxLogFatalError(msg.c_str());
// normally wxLogFatalError doesn't return
return false;
}
#undef wxCMP
return true;
}
#ifdef __WXDEBUG__
void wxAppConsole::OnAssert(const wxChar *file,
int line,
const wxChar *cond,
const wxChar *msg)
{
ShowAssertDialog(file, line, cond, msg, GetTraits());
}
#endif // __WXDEBUG__
#if WXWIN_COMPATIBILITY_2_4
bool wxAppConsole::CheckBuildOptions(const wxBuildOptions& buildOptions)
{
return CheckBuildOptions(buildOptions.m_signature, "your program");
}
#endif
// ============================================================================
// other classes implementations
// ============================================================================
// ----------------------------------------------------------------------------
// wxConsoleAppTraitsBase
// ----------------------------------------------------------------------------
#if wxUSE_LOG
wxLog *wxConsoleAppTraitsBase::CreateLogTarget()
{
return new wxLogStderr;
}
#endif // wxUSE_LOG
wxMessageOutput *wxConsoleAppTraitsBase::CreateMessageOutput()
{
return new wxMessageOutputStderr;
}
#if wxUSE_FONTMAP
wxFontMapper *wxConsoleAppTraitsBase::CreateFontMapper()
{
return (wxFontMapper *)new wxFontMapperBase;
}
#endif // wxUSE_FONTMAP
wxRendererNative *wxConsoleAppTraitsBase::CreateRenderer()
{
// console applications don't use renderers
return NULL;
}
#ifdef __WXDEBUG__
bool wxConsoleAppTraitsBase::ShowAssertDialog(const wxString& msg)
{
return wxAppTraitsBase::ShowAssertDialog(msg);
}
#endif
bool wxConsoleAppTraitsBase::HasStderr()
{
// console applications always have stderr, even under Mac/Windows
return true;
}
void wxConsoleAppTraitsBase::ScheduleForDestroy(wxObject *object)
{
delete object;
}
void wxConsoleAppTraitsBase::RemoveFromPendingDelete(wxObject * WXUNUSED(object))
{
// nothing to do
}
#if wxUSE_SOCKETS
GSocketGUIFunctionsTable* wxConsoleAppTraitsBase::GetSocketGUIFunctionsTable()
{
return NULL;
}
#endif
// ----------------------------------------------------------------------------
// wxAppTraits
// ----------------------------------------------------------------------------
#ifdef __WXDEBUG__
bool wxAppTraitsBase::ShowAssertDialog(const wxString& msg)
{
return DoShowAssertDialog(msg);
}
#endif // __WXDEBUG__
// ============================================================================
// global functions implementation
// ============================================================================
void wxExit()
{
if ( wxTheApp )
{
wxTheApp->Exit();
}
else
{
// what else can we do?
exit(-1);
}
}
void wxWakeUpIdle()
{
if ( wxTheApp )
{
wxTheApp->WakeUpIdle();
}
//else: do nothing, what can we do?
}
#ifdef __WXDEBUG__
// wxASSERT() helper
bool wxAssertIsEqual(int x, int y)
{
return x == y;
}
// break into the debugger
void wxTrap()
{
#if defined(__WXMSW__) && !defined(__WXMICROWIN__)
DebugBreak();
#elif defined(__WXMAC__) && !defined(__DARWIN__)
#if __powerc
Debugger();
#else
SysBreak();
#endif
#elif defined(_MSL_USING_MW_C_HEADERS) && _MSL_USING_MW_C_HEADERS
Debugger();
#elif defined(__UNIX__)
raise(SIGTRAP);
#else
// TODO
#endif // Win/Unix
}
void wxAssert(int cond,
const wxChar *szFile,
int nLine,
const wxChar *szCond,
const wxChar *szMsg)
{
if ( !cond )
wxOnAssert(szFile, nLine, szCond, szMsg);
}
// this function is called when an assert fails
void wxOnAssert(const wxChar *szFile,
int nLine,
const wxChar *szCond,
const wxChar *szMsg)
{
// FIXME MT-unsafe
static bool s_bInAssert = false;
if ( s_bInAssert )
{
// He-e-e-e-elp!! we're trapped in endless loop
wxTrap();
s_bInAssert = false;
return;
}
s_bInAssert = true;
if ( !wxTheApp )
{
// by default, show the assert dialog box -- we can't customize this
// behaviour
ShowAssertDialog(szFile, nLine, szCond, szMsg);
}
else
{
// let the app process it as it wants
wxTheApp->OnAssert(szFile, nLine, szCond, szMsg);
}
s_bInAssert = false;
}
#endif // __WXDEBUG__
// ============================================================================
// private functions implementation
// ============================================================================
#ifdef __WXDEBUG__
static void LINKAGEMODE SetTraceMasks()
{
#if wxUSE_LOG
wxString mask;
if ( wxGetEnv(wxT("WXTRACE"), &mask) )
{
wxStringTokenizer tkn(mask, wxT(",;:"));
while ( tkn.HasMoreTokens() )
wxLog::AddTraceMask(tkn.GetNextToken());
}
#endif // wxUSE_LOG
}
bool DoShowAssertDialog(const wxString& msg)
{
// under MSW we can show the dialog even in the console mode
#if defined(__WXMSW__) && !defined(__WXMICROWIN__)
wxString msgDlg(msg);
// this message is intentionally not translated -- it is for
// developpers only
msgDlg += wxT("\nDo you want to stop the program?\n")
wxT("You can also choose [Cancel] to suppress ")
wxT("further warnings.");
switch ( ::MessageBox(NULL, msgDlg, _T("wxWidgets Debug Alert"),
MB_YESNOCANCEL | MB_ICONSTOP ) )
{
case IDYES:
wxTrap();
break;
case IDCANCEL:
// stop the asserts
return true;
//case IDNO: nothing to do
}
#else // !__WXMSW__
wxFprintf(stderr, wxT("%s\n"), msg.c_str());
fflush(stderr);
// TODO: ask the user to enter "Y" or "N" on the console?
wxTrap();
#endif // __WXMSW__/!__WXMSW__
// continue with the asserts
return false;
}
#if wxUSE_STACKWALKER
static wxString GetAssertStackTrace()
{
wxString stackTrace;
class StackDump : public wxStackWalker
{
public:
StackDump() { }
const wxString& GetStackTrace() const { return m_stackTrace; }
protected:
virtual void OnStackFrame(const wxStackFrame& frame)
{
m_stackTrace << wxString::Format(_T("[%02d] "), frame.GetLevel());
wxString name = frame.GetName();
if ( !name.empty() )
{
m_stackTrace << wxString::Format(_T("%-40s"), name.c_str());
}
else
{
m_stackTrace << wxString::Format
(
_T("0x%08lx"),
(unsigned long)frame.GetAddress()
);
}
if ( frame.HasSourceLocation() )
{
m_stackTrace << _T('\t')
<< frame.GetFileName()
<< _T(':')
<< frame.GetLine();
}
m_stackTrace << _T('\n');
}
private:
wxString m_stackTrace;
};
StackDump dump;
dump.Walk(5); // don't show OnAssert() call itself
stackTrace = dump.GetStackTrace();
// don't show more than maxLines or we could get a dialog too tall to be
// shown on screen: 20 should be ok everywhere as even with 15 pixel high
// characters it is still only 300 pixels...
static const int maxLines = 20;
const int count = stackTrace.Freq(wxT('\n'));
for ( int i = 0; i < count - maxLines; i++ )
stackTrace = stackTrace.BeforeLast(wxT('\n'));
return stackTrace;
}
#endif // wxUSE_STACKWALKER
// show the assert modal dialog
static
void ShowAssertDialog(const wxChar *szFile,
int nLine,
const wxChar *szCond,
const wxChar *szMsg,
wxAppTraits *traits)
{
// this variable can be set to true to suppress "assert failure" messages
static bool s_bNoAsserts = false;
wxString msg;
msg.reserve(2048);
// make life easier for people using VC++ IDE by using this format: like
// this, clicking on the message will take us immediately to the place of
// the failed assert
msg.Printf(wxT("%s(%d): assert \"%s\" failed"), szFile, nLine, szCond);
if ( szMsg )
{
msg << _T(": ") << szMsg;
}
else // no message given
{
msg << _T('.');
}
#if wxUSE_STACKWALKER
const wxString stackTrace = GetAssertStackTrace();
if ( !stackTrace.empty() )
{
msg << _T("\n\nCall stack:\n") << stackTrace;
}
#endif // wxUSE_STACKWALKER
#if wxUSE_THREADS
// if we are not in the main thread, output the assert directly and trap
// since dialogs cannot be displayed
if ( !wxThread::IsMain() )
{
msg += wxT(" [in child thread]");
#if defined(__WXMSW__) && !defined(__WXMICROWIN__)
msg << wxT("\r\n");
OutputDebugString(msg );
#else
// send to stderr
wxFprintf(stderr, wxT("%s\n"), msg.c_str());
fflush(stderr);
#endif
// He-e-e-e-elp!! we're asserting in a child thread
wxTrap();
}
else
#endif // wxUSE_THREADS
if ( !s_bNoAsserts )
{
// send it to the normal log destination
wxLogDebug(_T("%s"), msg.c_str());
if ( traits )
{
// delegate showing assert dialog (if possible) to that class
s_bNoAsserts = traits->ShowAssertDialog(msg);
}
else // no traits object
{
// fall back to the function of last resort
s_bNoAsserts = DoShowAssertDialog(msg);
}
}
}
#endif // __WXDEBUG__
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?