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