From d76a558d4d5216b0590907b92d3182f82057c1ae Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Fri, 25 May 2007 00:52:00 +0000
Subject: [PATCH] added wxMSW-specific wxEntryStart() overload taking
 WinMain-like parameters

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@46203 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/latex/wx/function.tex |  9 ++++
 include/wx/msw/app.h       |  8 ++++
 src/msw/main.cpp           | 88 +++++++++++++++++++++++++++-----------
 3 files changed, 80 insertions(+), 25 deletions(-)

diff --git a/docs/latex/wx/function.tex b/docs/latex/wx/function.tex
index fca7636a23..c1056d214f 100644
--- a/docs/latex/wx/function.tex
+++ b/docs/latex/wx/function.tex
@@ -435,6 +435,15 @@ least the GUI part of) the library can't be used at all.
 Notice that parameters \arg{argc} and \arg{argv} may be modified by this
 function.
 
+An additional overload of wxEntryStart() is provided under MSW only: it is
+meant to be called with the parameters passed to \texttt{WinMain()}.
+
+\func{bool}{wxEntryStart}{\param{HINSTANCE }{hInstance}, \param{HINSTANCE }{hPrevInstance = \NULL}, \param{char *}{pCmdLine = \NULL}, \param{int }{nCmdShow = \texttt{SW\_SHOWNORMAL}}}
+
+(notice that under Windows CE platform, and only there, the type of 
+\arg{pCmdLine} is \texttt{wchar\_t *}, otherwise it is \texttt{char *}, even in
+Unicode build).
+
 \wxheading{Include files}
 
 <wx/init.h>
diff --git a/include/wx/msw/app.h b/include/wx/msw/app.h
index d43d6a20cb..754dc8f39b 100644
--- a/include/wx/msw/app.h
+++ b/include/wx/msw/app.h
@@ -96,6 +96,14 @@ protected:
     typedef char *wxCmdLineArgType;
 #endif
 
+// wxMSW-only overloads of wxEntry() and wxEntryStart() which take the
+// parameters passed to WinMain() instead of those passed to main()
+extern bool WXDLLEXPORT
+wxEntryStart(HINSTANCE hInstance,
+             HINSTANCE hPrevInstance = NULL,
+             wxCmdLineArgType pCmdLine = NULL,
+             int nCmdShow = SW_SHOWNORMAL);
+
 extern int WXDLLEXPORT
 wxEntry(HINSTANCE hInstance,
         HINSTANCE hPrevInstance = NULL,
diff --git a/src/msw/main.cpp b/src/msw/main.cpp
index ef89ba1061..80c14d917a 100644
--- a/src/msw/main.cpp
+++ b/src/msw/main.cpp
@@ -61,6 +61,7 @@
 
 // defined in common/init.cpp
 extern int wxEntryReal(int& argc, wxChar **argv);
+extern int wxEntryCleanupReal(int& argc, wxChar **argv);
 
 // ============================================================================
 // implementation: various entry points
@@ -319,31 +320,56 @@ static bool wxIsUnicodeAvailable()
 // Windows-specific wxEntry
 // ----------------------------------------------------------------------------
 
-// helper function used to clean up in wxEntry() just below
-//
-// notice that argv elements are supposed to be allocated using malloc() while
-// argv array itself is allocated with new
-static void wxFreeArgs(int argc, wxChar **argv)
+struct wxMSWCommandLineArguments
 {
-    for ( int i = 0; i < argc; i++ )
+    wxMSWCommandLineArguments() { argc = 0; argv = NULL; }
+
+    void Init(const wxArrayString& args)
     {
-        free(argv[i]);
+        argc = args.size();
+
+        // +1 here for the terminating NULL
+        argv = new wxChar *[argc + 1];
+        for ( int i = 0; i < argc; i++ )
+        {
+            argv[i] = wxStrdup(args[i]);
+        }
+
+        // argv[] must be NULL-terminated
+        argv[argc] = NULL;
     }
 
-    delete [] argv;
-}
+    void Free()
+    {
+        if ( !argc )
+            return;
 
-WXDLLEXPORT int wxEntry(HINSTANCE hInstance,
-                        HINSTANCE WXUNUSED(hPrevInstance),
-                        wxCmdLineArgType WXUNUSED(pCmdLine),
-                        int nCmdShow)
+        for ( int i = 0; i < argc; i++ )
+        {
+            free(argv[i]);
+        }
+
+        delete [] argv;
+        argv = NULL;
+        argc = 0;
+    }
+
+    int argc;
+    wxChar **argv;
+};
+
+static wxMSWCommandLineArguments wxArgs;
+
+// common part of wxMSW-specific wxEntryStart() and wxEntry() overloads
+static bool
+wxMSWEntryCommon(HINSTANCE hInstance, int nCmdShow)
 {
     // the first thing to do is to check if we're trying to run an Unicode
     // program under Win9x w/o MSLU emulation layer - if so, abort right now
     // as it has no chance to work and has all chances to crash
 #ifdef NEED_UNICODE_CHECK
     if ( !wxIsUnicodeAvailable() )
-        return -1;
+        return false;
 #endif // NEED_UNICODE_CHECK
 
 
@@ -369,21 +395,33 @@ WXDLLEXPORT int wxEntry(HINSTANCE hInstance,
     args.Insert(wxGetFullModuleName(), 0);
 #endif
 
-    int argc = args.GetCount();
+    wxArgs.Init(args);
 
-    // +1 here for the terminating NULL
-    wxChar **argv = new wxChar *[argc + 1];
-    for ( int i = 0; i < argc; i++ )
-    {
-        argv[i] = wxStrdup(args[i]);
-    }
+    return true;
+}
+
+WXDLLEXPORT bool wxEntryStart(HINSTANCE hInstance,
+                              HINSTANCE WXUNUSED(hPrevInstance),
+                              wxCmdLineArgType WXUNUSED(pCmdLine),
+                              int nCmdShow)
+{
+    if ( !wxMSWEntryCommon(hInstance, nCmdShow) )
+       return false;
 
-    // argv[] must be NULL-terminated
-    argv[argc] = NULL;
+    return wxEntryStart(wxArgs.argc, wxArgs.argv);
+}
+
+WXDLLEXPORT int wxEntry(HINSTANCE hInstance,
+                        HINSTANCE WXUNUSED(hPrevInstance),
+                        wxCmdLineArgType WXUNUSED(pCmdLine),
+                        int nCmdShow)
+{
+    if ( !wxMSWEntryCommon(hInstance, nCmdShow) )
+        return -1;
 
-    wxON_BLOCK_EXIT2(wxFreeArgs, argc, argv);
+    wxON_BLOCK_EXIT_OBJ0(wxArgs, wxMSWCommandLineArguments::Free);
 
-    return wxEntry(argc, argv);
+    return wxEntry(wxArgs.argc, wxArgs.argv);
 }
 
 #endif // wxUSE_GUI && __WXMSW__
-- 
2.50.0

