From 498a1eeb8d044ef64815352ecabe4c223adf8c6a Mon Sep 17 00:00:00 2001 From: Ryan Norton Date: Thu, 21 Apr 2005 20:13:44 +0000 Subject: [PATCH] Add wxLaunchDefaultBrowser, note wxGetKeyState change git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@33802 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 2 + docs/latex/wx/function.tex | 13 ++++ include/wx/utils.h | 3 + src/common/utilscmn.cpp | 140 +++++++++++++++++++++++++++++++++++++ 4 files changed, 158 insertions(+) diff --git a/docs/changes.txt b/docs/changes.txt index aeaf72176f..b9332dfc0b 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -5,9 +5,11 @@ wxWidgets Change Log - For more verbose changes, see the manual 2.6.1 ----- All: +- Added wxLaunchDefaultBrowser. wxMac: - Added support for launching 'APPL' bundles with wxExecute (usually they have a .app extension and are the ones that reside in the Applications folder). +- Fixed a bug in wxGetKeyState where shift and some other keys were returning an incorrect state. 2.6.0 ----- diff --git a/docs/latex/wx/function.tex b/docs/latex/wx/function.tex index 1a1bb44e51..58e5964499 100644 --- a/docs/latex/wx/function.tex +++ b/docs/latex/wx/function.tex @@ -164,6 +164,7 @@ the corresponding topic. \helpref{wxIsNaN}{wxisnan}\\ \helpref{wxIsWild}{wxiswild}\\ \helpref{wxKill}{wxkill}\\ +\helpref{wxLaunchDefaultBrowser}{wxlaunchdefaultbrowser}\\ \helpref{wxLEAVE\_CRIT\_SECT}{wxleavecritsect}\\ \helpref{wxLoadUserResource}{wxloaduserresource}\\ \helpref{wxLogDebug}{wxlogdebug}\\ @@ -2978,6 +2979,18 @@ frame or dialog containing it, or {\tt NULL}. +\membersection{::wxLaunchDefaultBrowser}\label{wxlaunchdefaultbrowser} + +\func{bool}{wxLaunchDefaultBrowser}{\param{const wxString\& }{sUrl}} + +Launches the user's default browser and tells it to open the location at {\tt sUrl}. + +Returns true if the application was successfully launched. + +\wxheading{Include files} + + + \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 30b4b59816..9c73ab4214 100644 --- a/include/wx/utils.h +++ b/include/wx/utils.h @@ -324,6 +324,9 @@ WXDLLIMPEXP_BASE bool wxHandleFatalExceptions(bool doit = true); #endif // wxUSE_ON_FATAL_EXCEPTION +// Launch url in the user's default internet browser +WXDLLIMPEXP_BASE bool wxLaunchDefaultBrowser(const wxString& url); + // ---------------------------------------------------------------------------- // Environment variables // ---------------------------------------------------------------------------- diff --git a/src/common/utilscmn.cpp b/src/common/utilscmn.cpp index 09369b63f3..bd2714f1eb 100644 --- a/src/common/utilscmn.cpp +++ b/src/common/utilscmn.cpp @@ -60,6 +60,9 @@ #include "wx/process.h" #include "wx/txtstrm.h" +#include "wx/uri.h" +#include "wx/mimetype.h" +#include "wx/config.h" #if defined(__WXWINCE__) && wxUSE_DATETIME #include "wx/datetime.h" @@ -524,6 +527,143 @@ long wxExecute(const wxString& command, return wxDoExecuteWithCapture(command, output, &error, flags); } +// ---------------------------------------------------------------------------- +// Launch default browser +// ---------------------------------------------------------------------------- + +bool wxLaunchDefaultBrowser(const wxString& url) +{ + wxString finalurl = url; + + //if it isn't a full url, try appending http:// to it + if(wxURI(url).IsReference()) + finalurl = wxString(wxT("http://")) + url; + +#ifdef __WINDOWS__ + wxString command; + + // ShellExecute() always opens in the same window, + // so do it manually for new window (from Mahogany) + wxRegKey key(wxRegKey::HKCR, url.BeforeFirst(':') + wxT("\\shell\\open")); + if ( key.Exists() ) + { + wxRegKey keyDDE(key, wxT("DDEExec")); + if ( keyDDE.Exists() ) + { + wxString ddeTopic = wxRegKey(keyDDE, wxT("topic")); + + // we only know the syntax of WWW_OpenURL DDE request + if ( ddeTopic == wxT("WWW_OpenURL") ) + { + wxString ddeCmd = keyDDE; + + // this is a bit naive but should work as -1 can't appear + // elsewhere in the DDE topic, normally + if ( ddeCmd.Replace(wxT("-1"), wxT("0"), + FALSE /* only first occurence */) == 1 ) + { + // and also replace the parameters + if ( ddeCmd.Replace(wxT("%1"), url, FALSE) == 1 ) + { + // magic incantation understood by wxMSW + command << wxT("WX_DDE#") + << wxRegKey(key, wxT("command")).QueryDefaultValue() << wxT('#') + << wxRegKey(keyDDE, wxT("application")).QueryDefaultValue() + << wxT('#') << ddeTopic << wxT('#') + << ddeCmd; + } + } + } + } + } + + //Try wxExecute - if it doesn't work or the regkey stuff + //above failed, fallback to opening the file in the same + //browser window + if ( command.empty() || wxExecute(command) == -1) + { + // CYGWIN and MINGW may have problems - so load ShellExecute + // dynamically + typedef HINSTANCE (*LPShellExecute)(HWND hwnd, const wxChar* lpOperation, + const wxChar* lpFile, + const wxChar* lpParameters, + const wxChar* lpDirectory, + INT nShowCmd); + + HINSTANCE hShellDll = ::LoadLibrary(wxT("shell32.dll")); + if(hShellDll == NULL) + return false; + + LPShellExecute lpShellExecute = + (LPShellExecute) ::GetProcAddress(hShellDll, + wxString::Format(wxT("ShellExecute%s"), +#ifdef __WXUNICODE__ + wxT("W") +#else + wxT("A") +#endif + ) + ); + if(lpShellExecute == NULL) + return false; + + // Windows sometimes doesn't open the browser correctly when using mime + // types, so do ShellExecute - i.e. start (from James Carroll) + unsigned int nResult = (int) (*lpShellExecute)(NULL, NULL, finalurl.c_str(), + NULL, wxT(""), SW_SHOWNORMAL); + + // Unload Shell32.dll + ::FreeLibrary(hShellDll); + + // Hack for Firefox (returns file not found for some reason) + // from Angelo Mandato's wxHyperlinksCtrl + // HINSTANCE_ERROR == 32 + if (nResult <= HINSTANCE_ERROR && nResult != SE_ERR_FNF) + return false; + + # ifdef __WXDEBUG__ + // Log something if SE_ERR_FNF happens + if(nResult == SE_ERR_FNF) + wxLogDebug(wxT("Got SE_ERR_FNF from ShellExecute - maybe FireFox")); + # endif + } + +#else + // Non-windows way + wxFileType *ft = + wxTheMimeTypesManager->GetFileTypeFromExtension (_T("html")); + if (!ft) + { + wxLogError(_T("No default application can open .html extension")); + return false; + } + + wxString mt; + ft->GetMimeType(&mt); + + wxString cmd; + bool ok = + ft->GetOpenCommand (&cmd, + wxFileType::MessageParameters (finalurl.c_str(), + _T(""))); + delete ft; + + if (ok) + { + if( wxExecute (cmd, wxEXEC_ASYNC) == -1 ) + { + wxLogError(_T("Failed to launch application for wxLaunchDefaultBrowser")); + return false; + } + } + else + return false; +#endif + + //success - hopefully + return true; +} + // ---------------------------------------------------------------------------- // wxApp::Yield() wrappers for backwards compatibility // ---------------------------------------------------------------------------- -- 2.47.2