ConvertToStandardCommandArgs() was ugly, buggy and leaked memory (not bad
for 10 lines of code). Now it's only ugly... git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@757 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
146
src/msw/app.cpp
146
src/msw/app.cpp
@@ -44,19 +44,22 @@
|
||||
#include "wx/resource.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if defined(__WIN95__) && !defined(__GNUWIN32__)
|
||||
#include <commctrl.h>
|
||||
#endif
|
||||
|
||||
// use debug CRT functions for memory leak detections in VC++
|
||||
/* Doesn't work when using the makefiles, for some reason.
|
||||
#if defined(__WXDEBUG__) && defined(_MSC_VER)
|
||||
// VC++ uses this macro as debug/release mode indicator
|
||||
#ifndef _DEBUG
|
||||
#define _DEBUG
|
||||
#endif
|
||||
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
*/
|
||||
|
||||
extern char *wxBuffer;
|
||||
extern char *wxOsVersion;
|
||||
@@ -69,6 +72,7 @@ HINSTANCE wxhInstance = 0;
|
||||
static MSG s_currentMsg;
|
||||
wxApp *wxTheApp = NULL;
|
||||
|
||||
// @@ why not const? and not static?
|
||||
char wxFrameClassName[] = "wxFrameClass";
|
||||
char wxMDIFrameClassName[] = "wxMDIFrameClass";
|
||||
char wxMDIChildFrameClassName[] = "wxMDIChildFrameClass";
|
||||
@@ -89,6 +93,7 @@ LRESULT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM);
|
||||
|
||||
#if !USE_SHARED_LIBRARY
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
|
||||
|
||||
BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
|
||||
EVT_IDLE(wxApp::OnIdle)
|
||||
END_EVENT_TABLE()
|
||||
@@ -106,25 +111,22 @@ bool wxApp::Initialize()
|
||||
{
|
||||
wxBuffer = new char[1500];
|
||||
|
||||
/* Doesn't work when using the makefiles, for some reason.
|
||||
#if defined(__WXDEBUG__) && defined(_MSC_VER)
|
||||
// do check for memory leaks on program exit
|
||||
// (another useful flag is _CRTDBG_DELAY_FREE_MEM_DF which doesn't free
|
||||
// deallocated memory which may be used to simulate low-memory condition)
|
||||
_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
|
||||
#endif // debug build under MS VC++
|
||||
*/
|
||||
|
||||
#if (WXDEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT
|
||||
|
||||
#if !defined(_WINDLL)
|
||||
streambuf* sBuf = new wxDebugStreamBuf;
|
||||
#else
|
||||
#if defined(_WINDLL)
|
||||
streambuf* sBuf = NULL;
|
||||
#endif
|
||||
#else // EXE
|
||||
streambuf* sBuf = new wxDebugStreamBuf;
|
||||
#endif // DLL
|
||||
|
||||
ostream* oStr = new ostream(sBuf) ;
|
||||
wxDebugContext::SetStream(oStr, sBuf);
|
||||
|
||||
#endif // USE_MEMORY_TRACING
|
||||
|
||||
wxClassInfo::InitializeClasses();
|
||||
@@ -207,6 +209,7 @@ bool wxApp::Initialize()
|
||||
extern char wxDummyChar;
|
||||
if (wxDummyChar) wxDummyChar++;
|
||||
#endif
|
||||
|
||||
wxSetKeyboardHook(TRUE);
|
||||
|
||||
wxModule::RegisterModules();
|
||||
@@ -343,17 +346,15 @@ bool wxApp::RegisterWindowClasses()
|
||||
|
||||
//// Convert Windows to argc, argv style
|
||||
|
||||
// FIXME this code should be rewritten (use wxArrayString instead...)
|
||||
void wxApp::ConvertToStandardCommandArgs(char* lpCmdLine)
|
||||
{
|
||||
// Split command line into tokens, as in usual main(argc, argv)
|
||||
char **command = new char*[50];
|
||||
char **command = new char*[50]; // VZ: sure? why not 25 or 73 and a half??
|
||||
|
||||
int count = 0;
|
||||
char *buf = new char[strlen(lpCmdLine) + 1];
|
||||
|
||||
// Hangs around until end of app. in case
|
||||
// user carries pointers to the tokens
|
||||
|
||||
/* Model independent strcpy */
|
||||
int i;
|
||||
for (i = 0; (buf[i] = lpCmdLine[i]) != 0; i++)
|
||||
@@ -362,8 +363,8 @@ void wxApp::ConvertToStandardCommandArgs(char* lpCmdLine)
|
||||
}
|
||||
|
||||
// Get application name
|
||||
char name[200];
|
||||
::GetModuleFileName(wxhInstance, name, 199);
|
||||
char name[260]; // 260 is MAX_PATH value from windef.h
|
||||
::GetModuleFileName(wxhInstance, name, WXSIZEOF(name));
|
||||
|
||||
// Is it only 16-bit Borland that already copies the program name
|
||||
// to the first argv index?
|
||||
@@ -382,29 +383,44 @@ void wxApp::ConvertToStandardCommandArgs(char* lpCmdLine)
|
||||
char* str = buf;
|
||||
while (*str)
|
||||
{
|
||||
while (*str && *str <= ' ') str++; // skip whitespace
|
||||
if ( count == WXSIZEOF(command) )
|
||||
{
|
||||
wxFAIL_MSG("too many command line args.");
|
||||
break;
|
||||
}
|
||||
|
||||
while ( *str && isspace(*str) ) // skip whitespace
|
||||
str++;
|
||||
|
||||
if (*str == '"')
|
||||
{
|
||||
str++;
|
||||
command[count++] = str;
|
||||
while (*str && *str != '"') str++;
|
||||
while (*str && *str != '"')
|
||||
str++;
|
||||
}
|
||||
else if (*str)
|
||||
{
|
||||
command[count++] = str;
|
||||
while (*str && *str > ' ') str++;
|
||||
while (*str && !isspace(*str))
|
||||
str++;
|
||||
}
|
||||
if (*str) *str++ = '\0';
|
||||
if (*str)
|
||||
*str++ = '\0';
|
||||
}
|
||||
|
||||
wxTheApp->argv = new char*[argc+1];
|
||||
wxTheApp->argv = new char*[count + 1];
|
||||
wxTheApp->argv[count] = NULL; /* argv[] is NULL terminated list! */
|
||||
wxTheApp->argc = count;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
wxTheApp->argv[i] = copystring(command[i]);
|
||||
|
||||
delete [] command[i];
|
||||
}
|
||||
|
||||
delete [] command;
|
||||
delete [] buf;
|
||||
}
|
||||
|
||||
@@ -498,34 +514,36 @@ void wxApp::CleanUp()
|
||||
#if !defined(_WINDLL) || (defined(_WINDLL) && defined(WXMAKINGDLL))
|
||||
|
||||
//// Main wxWindows entry point
|
||||
|
||||
int wxEntry(WXHINSTANCE hInstance, WXHINSTANCE WXUNUSED(hPrevInstance), char *lpCmdLine,
|
||||
int nCmdShow, bool enterLoop)
|
||||
int wxEntry(WXHINSTANCE hInstance,
|
||||
WXHINSTANCE WXUNUSED(hPrevInstance),
|
||||
char *lpCmdLine,
|
||||
int nCmdShow,
|
||||
bool enterLoop)
|
||||
{
|
||||
#ifndef __WXDEBUG__ // take everything into a try-except block in release build
|
||||
__try {
|
||||
#endif
|
||||
|
||||
wxhInstance = (HINSTANCE) hInstance;
|
||||
|
||||
if (!wxApp::Initialize())
|
||||
return 0;
|
||||
|
||||
// The app may have declared a global application object, but we recommend
|
||||
// the IMPLEMENT_APP macro is used instead, which sets an initializer function
|
||||
// for delayed, dynamic app object construction.
|
||||
// create the application object or ensure that one already exists
|
||||
if (!wxTheApp)
|
||||
{
|
||||
if (!wxApp::GetInitializerFunction())
|
||||
{
|
||||
MessageBox(NULL, "No initializer - use IMPLEMENT_APP macro.", "wxWindows Error", MB_APPLMODAL | MB_ICONSTOP | MB_OK);
|
||||
return 0;
|
||||
}
|
||||
// The app may have declared a global application object, but we recommend
|
||||
// the IMPLEMENT_APP macro is used instead, which sets an initializer
|
||||
// function for delayed, dynamic app object construction.
|
||||
wxCHECK_MSG( wxApp::GetInitializerFunction(), 0,
|
||||
"No initializer - use IMPLEMENT_APP macro." );
|
||||
|
||||
wxTheApp = (*wxApp::GetInitializerFunction()) ();
|
||||
}
|
||||
|
||||
if (!wxTheApp) {
|
||||
MessageBox(NULL, "You have to define an instance of wxApp!", "wxWindows Error", MB_APPLMODAL | MB_ICONSTOP | MB_OK);
|
||||
return 0;
|
||||
}
|
||||
wxCHECK_MSG( wxTheApp, 0, "You have to define an instance of wxApp!" );
|
||||
|
||||
// save the WinMain() parameters
|
||||
wxTheApp->ConvertToStandardCommandArgs(lpCmdLine);
|
||||
wxTheApp->m_nCmdShow = nCmdShow;
|
||||
|
||||
@@ -533,44 +551,30 @@ int wxEntry(WXHINSTANCE hInstance, WXHINSTANCE WXUNUSED(hPrevInstance), char *lp
|
||||
// but this call is provided for compatibility across platforms.
|
||||
wxTheApp->OnInitGui() ;
|
||||
|
||||
if (!wxTheApp->OnInit())
|
||||
int retValue = 0;
|
||||
|
||||
if ( wxTheApp->OnInit() )
|
||||
{
|
||||
if ( enterLoop )
|
||||
{
|
||||
wxTheApp->DeletePendingObjects();
|
||||
wxTheApp->OnExit();
|
||||
wxApp::CleanUp();
|
||||
|
||||
delete wxTheApp;
|
||||
wxTheApp = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!enterLoop)
|
||||
return 0;
|
||||
|
||||
int retValue = 1;
|
||||
|
||||
/* New behaviour - leave it to the app to show the top window
|
||||
if (wxTheApp->GetTopWindow()) {
|
||||
// show the toplevel frame, only if we are not iconized (from MS-Windows)
|
||||
if(wxTheApp->GetShowFrameOnInit() && (nCmdShow!=SW_HIDE)) wxTheApp->GetTopWindow()->Show(TRUE);
|
||||
}
|
||||
*/
|
||||
|
||||
retValue = wxTheApp->OnRun();
|
||||
}
|
||||
}
|
||||
//else: app initialization failed, so we skipped OnRun()
|
||||
|
||||
if (wxTheApp->GetTopWindow())
|
||||
wxWindow *topWindow = wxTheApp->GetTopWindow();
|
||||
if ( topWindow )
|
||||
{
|
||||
// Forcibly delete the window.
|
||||
if (wxTheApp->GetTopWindow()->IsKindOf(CLASSINFO(wxFrame)) ||
|
||||
wxTheApp->GetTopWindow()->IsKindOf(CLASSINFO(wxDialog)))
|
||||
if ( topWindow->IsKindOf(CLASSINFO(wxFrame)) ||
|
||||
topWindow->IsKindOf(CLASSINFO(wxDialog)) )
|
||||
{
|
||||
wxTheApp->GetTopWindow()->Close(TRUE);
|
||||
topWindow->Close(TRUE);
|
||||
wxTheApp->DeletePendingObjects();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete wxTheApp->GetTopWindow();
|
||||
delete topWindow;
|
||||
wxTheApp->SetTopWindow(NULL);
|
||||
}
|
||||
}
|
||||
@@ -596,6 +600,17 @@ int wxEntry(WXHINSTANCE hInstance, WXHINSTANCE WXUNUSED(hPrevInstance), char *lp
|
||||
#endif
|
||||
|
||||
return retValue;
|
||||
#ifndef __WXDEBUG__ // catch exceptions only in release build
|
||||
}
|
||||
__except ( EXCEPTION_EXECUTE_HANDLER ) {
|
||||
/*
|
||||
if ( wxTheApp )
|
||||
wxTheApp->OnFatalException();
|
||||
*/
|
||||
|
||||
::ExitProcess(3); // the same exit code as abort()
|
||||
}
|
||||
#endif //debug
|
||||
}
|
||||
|
||||
#else /* _WINDLL */
|
||||
@@ -975,4 +990,3 @@ HINSTANCE wxGetInstance()
|
||||
#if (defined(_MSC_VER) && !defined(__WIN32__)) || defined(__GNUWIN32__)
|
||||
#include "main.cpp"
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user