From 42d0df0030abbac4ca11a78b2f529133e3c9d986 Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Sat, 24 Sep 2005 23:56:34 +0000
Subject: [PATCH] wxLaunchDefaultBrowser() now supports wxBROWSER_NEW_WINDOW
 flag (and it actually works correctly, too)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@35669 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/changes.txt           |  4 +++
 docs/latex/wx/function.tex |  9 ++++--
 include/wx/utils.h         | 16 +++++++++-
 src/common/utilscmn.cpp    | 62 +++++++++++++++++++++++++++++++++++++-
 src/msw/utilsexc.cpp       | 12 ++++----
 5 files changed, 92 insertions(+), 11 deletions(-)

diff --git a/docs/changes.txt b/docs/changes.txt
index 60d674450b..97e038535f 100644
--- a/docs/changes.txt
+++ b/docs/changes.txt
@@ -5,6 +5,10 @@ wxWidgets Change Log - For more verbose changes, see the manual
 2.7.0
 -----
 
+All:
+
+- wxLaunchDefaultBrowser() now supports wxBROWSER_NEW_WINDOW flag
+
 wxMSW:
 
 - wxFileDialog respects absence of wxCHANGE_DIR flag under NT (Brad Anderson)
diff --git a/docs/latex/wx/function.tex b/docs/latex/wx/function.tex
index 7e4a4f8599..a6da0b19e4 100644
--- a/docs/latex/wx/function.tex
+++ b/docs/latex/wx/function.tex
@@ -3048,16 +3048,19 @@ frame or dialog containing it, or {\tt NULL}.
 
 \membersection{::wxLaunchDefaultBrowser}\label{wxlaunchdefaultbrowser}
 
-\func{bool}{wxLaunchDefaultBrowser}{\param{const wxString\& }{sUrl}}
+\func{bool}{wxLaunchDefaultBrowser}{\param{const wxString\& }{url}, \param{int }{flags = $0$}}
 
-Launches the user's default browser and tells it to open the location at {\tt sUrl}.
+Open the \arg{url} in user's default browser. If \arg{flags} parameter contains 
+\texttt{wxBROWSER\_NEW\_WINDOW} flag, a new window is opened for the URL
+(currently this is only supported under Windows).
 
-Returns true if the application was successfully launched.
+Returns \true if the application was successfully launched.
 
 \wxheading{Include files}
 
 <wx/utils.h>
 
+
 \membersection{::wxLoadUserResource}\label{wxloaduserresource}
 
 \func{wxString}{wxLoadUserResource}{\param{const wxString\& }{resourceName}, \param{const wxString\& }{resourceType=``TEXT"}}
diff --git a/include/wx/utils.h b/include/wx/utils.h
index e35fa38c40..f3e961d8fe 100644
--- a/include/wx/utils.h
+++ b/include/wx/utils.h
@@ -209,6 +209,13 @@ WXDLLIMPEXP_BASE long wxExecute(const wxString& command,
                                 wxArrayString& error,
                                 int flags = 0);
 
+#ifdef __WXMSW__
+// ask a DDE server to execute the DDE request with given parameters
+WXDLLIMPEXP_BASE bool wxExecuteDDE(const wxString& ddeServer,
+                                   const wxString& ddeTopic,
+                                   const wxString& ddeCommand);
+#endif // __WXMSW__
+
 enum wxSignal
 {
     wxSIGNONE = 0,  // verify if the process exists under Unix
@@ -319,8 +326,15 @@ WXDLLIMPEXP_BASE bool wxHandleFatalExceptions(bool doit = true);
 #endif // wxUSE_ON_FATAL_EXCEPTION
 
 #if wxABI_VERSION >= 20601
+
+// flags for wxLaunchDefaultBrowser
+enum
+{
+    wxBROWSER_NEW_WINDOW = 1
+};
+
 // Launch url in the user's default internet browser
-WXDLLIMPEXP_BASE bool wxLaunchDefaultBrowser(const wxString& url);
+WXDLLIMPEXP_BASE bool wxLaunchDefaultBrowser(const wxString& url, int flags = 0);
 #endif
 
 // ----------------------------------------------------------------------------
diff --git a/src/common/utilscmn.cpp b/src/common/utilscmn.cpp
index 24f2866ea4..9f77a8a6a8 100644
--- a/src/common/utilscmn.cpp
+++ b/src/common/utilscmn.cpp
@@ -520,14 +520,74 @@ long wxExecute(const wxString& command,
 // Launch default browser
 // ----------------------------------------------------------------------------
 
-bool wxLaunchDefaultBrowser(const wxString& urlOrig)
+bool wxLaunchDefaultBrowser(const wxString& urlOrig, int flags)
 {
+    wxUnusedVar(flags);
+
     // set the scheme of url to http if it does not have one
     wxString url(urlOrig);
     if ( !wxURI(url).HasScheme() )
         url.Prepend(wxT("http://"));
 
 #if defined(__WXMSW__)
+    if ( flags & wxBROWSER_NEW_WINDOW )
+    {
+        // ShellExecuteEx() opens the URL in an existing window by default so
+        // we can't use it if we need a new window
+        wxRegKey key(wxRegKey::HKCR, url.BeforeFirst(':') + _T("\\shell\\open"));
+        if ( key.Exists() )
+        {
+            wxRegKey keyDDE(key, wxT("DDEExec"));
+            if ( keyDDE.Exists() )
+            {
+                const wxString ddeTopic = wxRegKey(keyDDE, wxT("topic"));
+
+                // we only know the syntax of WWW_OpenURL DDE request for IE,
+                // optimistically assume that all other browsers are compatible
+                // with it
+                wxString ddeCmd;
+                bool ok = ddeTopic == wxT("WWW_OpenURL");
+                if ( ok )
+                {
+                    ddeCmd = keyDDE;
+                    ok = !ddeCmd.empty();
+                }
+
+                if ( ok )
+                {
+                    // for WWW_OpenURL, the index of the window to open the URL
+                    // in is -1 (meaning "current") by default, replace it with
+                    // 0 which means "new" (see KB article 160957)
+                    ok = ddeCmd.Replace(wxT("-1"), wxT("0"),
+                                        false /* only first occurence */) == 1;
+                }
+
+                if ( ok )
+                {
+                    // and also replace the parameters: the topic should
+                    // contain a placeholder for the URL
+                    ok = ddeCmd.Replace(wxT("%1"), url, false) == 1;
+                }
+
+                if ( ok )
+                {
+                    // try to send it the DDE request now but ignore the errors
+                    wxLogNull noLog;
+
+                    const wxString ddeServer = wxRegKey(keyDDE, wxT("application"));
+                    if ( wxExecuteDDE(ddeServer, ddeTopic, ddeCmd) )
+                        return true;
+
+                    // this is not necessarily an error: maybe browser is
+                    // simply not running, but no matter, in any case we're
+                    // going to launch it using ShellExecuteEx() below now and
+                    // we shouldn't try to open a new window if we open a new
+                    // browser anyhow
+                }
+            }
+        }
+    }
+
     WinStruct<SHELLEXECUTEINFO> sei;
     sei.lpFile = url.c_str();
     sei.lpVerb = _T("open");
diff --git a/src/msw/utilsexc.cpp b/src/msw/utilsexc.cpp
index 4eed50125a..c7fa039d3a 100644
--- a/src/msw/utilsexc.cpp
+++ b/src/msw/utilsexc.cpp
@@ -483,16 +483,16 @@ size_t wxPipeOutputStream::OnSysWrite(const void *buffer, size_t len)
 #if wxUSE_IPC
 
 // connect to the given server via DDE and ask it to execute the command
-static bool wxExecuteDDE(const wxString& ddeServer,
-                         const wxString& ddeTopic,
-                         const wxString& ddeCommand)
+bool
+wxExecuteDDE(const wxString& ddeServer,
+             const wxString& ddeTopic,
+             const wxString& ddeCommand)
 {
     bool ok wxDUMMY_INITIALIZE(false);
 
     wxDDEClient client;
-    wxConnectionBase *conn = client.MakeConnection(wxEmptyString,
-                                                   ddeServer,
-                                                   ddeTopic);
+    wxConnectionBase *
+        conn = client.MakeConnection(wxEmptyString, ddeServer, ddeTopic);
     if ( !conn )
     {
         ok = false;
-- 
2.50.0

