+#if wxUSE_IPC
+ 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.QueryDefaultValue();
+ 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
+ }
+ }
+ }
+ }
+#endif // wxUSE_IPC
+
+ WinStruct<SHELLEXECUTEINFO> sei;
+ sei.lpFile = url.c_str();
+ sei.lpVerb = _T("open");
+ sei.nShow = SW_SHOWNORMAL;
+
+ ::ShellExecuteEx(&sei);
+
+ const int nResult = (int) sei.hInstApp;
+
+ // Firefox returns file not found for some reason, so make an exception
+ // for it
+ if ( nResult > 32 || nResult == SE_ERR_FNF )
+ {
+#ifdef __WXDEBUG__
+ // Log something if SE_ERR_FNF happens
+ if ( nResult == SE_ERR_FNF )
+ wxLogDebug(wxT("SE_ERR_FNF from ShellExecute -- maybe FireFox?"));
+#endif // __WXDEBUG__
+ return true;
+ }
+#elif defined(__WXMAC__)
+ OSStatus err;
+ ICInstance inst;
+ SInt32 startSel;
+ SInt32 endSel;
+
+ err = ICStart(&inst, 'STKA'); // put your app creator code here
+ if (err == noErr)
+ {
+#if !TARGET_CARBON
+ err = ICFindConfigFile(inst, 0, NULL);
+#endif
+ if (err == noErr)
+ {
+ ConstStr255Param hint = 0;
+ startSel = 0;
+ endSel = url.length();
+ err = ICLaunchURL(inst, hint, url.fn_str(), endSel, &startSel, &endSel);
+ if (err != noErr)
+ wxLogDebug(wxT("ICLaunchURL error %d"), (int) err);
+ }
+ ICStop(inst);
+ return true;
+ }
+ else
+ {
+ wxLogDebug(wxT("ICStart error %d"), (int) err);
+ return false;
+ }
+#elif wxUSE_MIMETYPE
+ // Non-windows way
+ bool ok = false;
+ wxString cmd;
+
+ wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(_T("html"));
+ if ( ft )
+ {
+ wxString mt;
+ ft->GetMimeType(&mt);
+
+ ok = ft->GetOpenCommand(&cmd, wxFileType::MessageParameters(url));
+ delete ft;
+ }
+
+ if ( !ok || cmd.empty() )
+ {
+ // fallback to checking for the BROWSER environment variable
+ cmd = wxGetenv(wxT("BROWSER"));
+ if ( !cmd.empty() )
+ cmd << _T(' ') << url;
+ }
+
+ ok = ( !cmd.empty() && wxExecute(cmd) );
+ if (ok)
+ return ok;
+
+ // no file type for HTML extension
+ wxLogError(_T("No default application configured for HTML files."));
+
+#endif // !wxUSE_MIMETYPE && !__WXMSW__
+
+ wxLogSysError(_T("Failed to open URL \"%s\" in default browser."),
+ url.c_str());
+
+ return false;
+}
+
+// ----------------------------------------------------------------------------
+// wxApp::Yield() wrappers for backwards compatibility
+// ----------------------------------------------------------------------------
+
+bool wxYield()
+{
+ return wxTheApp && wxTheApp->Yield();
+}
+
+bool wxYieldIfNeeded()
+{
+ return wxTheApp && wxTheApp->Yield(true);
+}
+
+#endif // wxUSE_BASE
+
+// ============================================================================
+// GUI-only functions from now on
+// ============================================================================
+
+#if wxUSE_GUI
+
+// Id generation
+static long wxCurrentId = 100;
+
+long wxNewId()
+{
+ // skip the part of IDs space that contains hard-coded values:
+ if (wxCurrentId == wxID_LOWEST)
+ wxCurrentId = wxID_HIGHEST + 1;
+
+ return wxCurrentId++;
+}
+
+long
+wxGetCurrentId(void) { return wxCurrentId; }
+
+void
+wxRegisterId (long id)
+{
+ if (id >= wxCurrentId)
+ wxCurrentId = id + 1;
+}
+
+// ----------------------------------------------------------------------------
+// Menu accelerators related functions
+// ----------------------------------------------------------------------------
+
+wxChar *wxStripMenuCodes(const wxChar *in, wxChar *out)
+{
+#if wxUSE_MENUS
+ wxString s = wxMenuItem::GetLabelFromText(in);
+#else
+ wxString str(in);
+ wxString s = wxStripMenuCodes(str);
+#endif // wxUSE_MENUS
+ if ( out )
+ {
+ // go smash their buffer if it's not big enough - I love char * params
+ memcpy(out, s.c_str(), s.length() * sizeof(wxChar));
+ }
+ else
+ {
+ // MYcopystring - for easier search...
+ out = new wxChar[s.length() + 1];
+ wxStrcpy(out, s.c_str());
+ }
+
+ return out;
+}
+
+wxString wxStripMenuCodes(const wxString& in, int flags)
+{
+ wxASSERT_MSG( flags, _T("this is useless to call without any flags") );
+
+ wxString out;
+
+ size_t len = in.length();
+ out.reserve(len);
+
+ for ( size_t n = 0; n < len; n++ )
+ {
+ wxChar ch = in[n];
+ if ( (flags & wxStrip_Mnemonics) && ch == _T('&') )
+ {
+ // skip it, it is used to introduce the accel char (or to quote
+ // itself in which case it should still be skipped): note that it
+ // can't be the last character of the string
+ if ( ++n == len )
+ {
+ wxLogDebug(_T("Invalid menu string '%s'"), in.c_str());
+ }
+ else
+ {
+ // use the next char instead
+ ch = in[n];
+ }
+ }
+ else if ( (flags & wxStrip_Accel) && ch == _T('\t') )
+ {
+ // everything after TAB is accel string, exit the loop
+ break;
+ }
+
+ out += ch;
+ }
+
+ return out;
+}
+
+// ----------------------------------------------------------------------------
+// Window search functions
+// ----------------------------------------------------------------------------
+
+/*
+ * If parent is non-NULL, look through children for a label or title
+ * matching the specified string. If NULL, look through all top-level windows.
+ *
+ */
+
+wxWindow *
+wxFindWindowByLabel (const wxString& title, wxWindow * parent)
+{
+ return wxWindow::FindWindowByLabel( title, parent );
+}
+
+
+/*
+ * If parent is non-NULL, look through children for a name
+ * matching the specified string. If NULL, look through all top-level windows.
+ *
+ */
+
+wxWindow *
+wxFindWindowByName (const wxString& name, wxWindow * parent)
+{
+ return wxWindow::FindWindowByName( name, parent );
+}
+
+// Returns menu item id or wxNOT_FOUND if none.
+int
+wxFindMenuItemId (wxFrame * frame, const wxString& menuString, const wxString& itemString)
+{
+#if wxUSE_MENUS
+ wxMenuBar *menuBar = frame->GetMenuBar ();
+ if ( menuBar )
+ return menuBar->FindMenuItem (menuString, itemString);
+#endif // wxUSE_MENUS
+
+ return wxNOT_FOUND;
+}
+
+// Try to find the deepest child that contains 'pt'.
+// We go backwards, to try to allow for controls that are spacially
+// within other controls, but are still siblings (e.g. buttons within
+// static boxes). Static boxes are likely to be created _before_ controls
+// that sit inside them.
+wxWindow* wxFindWindowAtPoint(wxWindow* win, const wxPoint& pt)
+{
+ if (!win->IsShown())
+ return NULL;
+
+ // Hack for wxNotebook case: at least in wxGTK, all pages
+ // claim to be shown, so we must only deal with the selected one.
+#if wxUSE_NOTEBOOK
+ if (win->IsKindOf(CLASSINFO(wxNotebook)))
+ {
+ wxNotebook* nb = (wxNotebook*) win;
+ int sel = nb->GetSelection();
+ if (sel >= 0)
+ {
+ wxWindow* child = nb->GetPage(sel);
+ wxWindow* foundWin = wxFindWindowAtPoint(child, pt);
+ if (foundWin)
+ return foundWin;
+ }
+ }
+#endif
+
+ wxWindowList::compatibility_iterator node = win->GetChildren().GetLast();
+ while (node)
+ {
+ wxWindow* child = node->GetData();
+ wxWindow* foundWin = wxFindWindowAtPoint(child, pt);
+ if (foundWin)
+ return foundWin;
+ node = node->GetPrevious();
+ }
+
+ wxPoint pos = win->GetPosition();
+ wxSize sz = win->GetSize();
+ if ( !win->IsTopLevel() && win->GetParent() )
+ {
+ pos = win->GetParent()->ClientToScreen(pos);
+ }
+
+ wxRect rect(pos, sz);
+ if (rect.Inside(pt))
+ return win;
+
+ return NULL;
+}
+
+wxWindow* wxGenericFindWindowAtPoint(const wxPoint& pt)
+{
+ // Go backwards through the list since windows
+ // on top are likely to have been appended most
+ // recently.
+ wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetLast();
+ while (node)
+ {
+ wxWindow* win = node->GetData();
+ wxWindow* found = wxFindWindowAtPoint(win, pt);
+ if (found)
+ return found;
+ node = node->GetPrevious();
+ }
+ return NULL;
+}
+
+// ----------------------------------------------------------------------------
+// GUI helpers
+// ----------------------------------------------------------------------------
+
+/*
+ * N.B. these convenience functions must be separate from msgdlgg.cpp, textdlgg.cpp
+ * since otherwise the generic code may be pulled in unnecessarily.
+ */
+
+#if wxUSE_MSGDLG
+
+int wxMessageBox(const wxString& message, const wxString& caption, long style,
+ wxWindow *parent, int WXUNUSED(x), int WXUNUSED(y) )
+{
+ long decorated_style = style;
+
+ if ( ( style & ( wxICON_EXCLAMATION | wxICON_HAND | wxICON_INFORMATION | wxICON_QUESTION ) ) == 0 )
+ {
+ decorated_style |= ( style & wxYES ) ? wxICON_QUESTION : wxICON_INFORMATION ;
+ }
+
+ wxMessageDialog dialog(parent, message, caption, decorated_style);
+
+ int ans = dialog.ShowModal();
+ switch ( ans )
+ {
+ case wxID_OK:
+ return wxOK;
+ case wxID_YES:
+ return wxYES;
+ case wxID_NO:
+ return wxNO;
+ case wxID_CANCEL:
+ return wxCANCEL;
+ }
+
+ wxFAIL_MSG( _T("unexpected return code from wxMessageDialog") );
+
+ return wxCANCEL;
+}
+
+#endif // wxUSE_MSGDLG
+
+#if wxUSE_TEXTDLG
+
+wxString wxGetTextFromUser(const wxString& message, const wxString& caption,
+ const wxString& defaultValue, wxWindow *parent,
+ wxCoord x, wxCoord y, bool centre )
+{
+ wxString str;
+ long style = wxTextEntryDialogStyle;
+
+ if (centre)
+ style |= wxCENTRE;
+ else
+ style &= ~wxCENTRE;
+
+ wxTextEntryDialog dialog(parent, message, caption, defaultValue, style, wxPoint(x, y));
+
+ if (dialog.ShowModal() == wxID_OK)
+ {
+ str = dialog.GetValue();
+ }
+
+ return str;
+}
+
+wxString wxGetPasswordFromUser(const wxString& message,
+ const wxString& caption,
+ const wxString& defaultValue,
+ wxWindow *parent,
+ wxCoord x, wxCoord y, bool centre )
+{
+ wxString str;
+ long style = wxTextEntryDialogStyle;
+
+ if (centre)
+ style |= wxCENTRE;
+ else
+ style &= ~wxCENTRE;
+
+ wxPasswordEntryDialog dialog(parent, message, caption, defaultValue,
+ style, wxPoint(x, y));
+ if ( dialog.ShowModal() == wxID_OK )
+ {
+ str = dialog.GetValue();
+ }
+
+ return str;
+}
+
+#endif // wxUSE_TEXTDLG
+
+#if wxUSE_COLOURDLG
+
+wxColour wxGetColourFromUser(wxWindow *parent, const wxColour& colInit, const wxString& caption)
+{
+ wxColourData data;
+ data.SetChooseFull(true);
+ if ( colInit.Ok() )
+ {
+ data.SetColour((wxColour &)colInit); // const_cast
+ }
+
+ wxColour colRet;
+ wxColourDialog dialog(parent, &data);
+ if (!caption.empty())
+ dialog.SetTitle(caption);
+ if ( dialog.ShowModal() == wxID_OK )
+ {
+ colRet = dialog.GetColourData().GetColour();
+ }
+ //else: leave it invalid
+
+ return colRet;
+}
+
+#endif // wxUSE_COLOURDLG
+
+#if wxUSE_FONTDLG
+
+wxFont wxGetFontFromUser(wxWindow *parent, const wxFont& fontInit, const wxString& caption)
+{
+ wxFontData data;
+ if ( fontInit.Ok() )
+ {
+ data.SetInitialFont(fontInit);
+ }
+
+ wxFont fontRet;
+ wxFontDialog dialog(parent, data);
+ if (!caption.empty())
+ dialog.SetTitle(caption);
+ if ( dialog.ShowModal() == wxID_OK )
+ {
+ fontRet = dialog.GetFontData().GetChosenFont();
+ }
+ //else: leave it invalid
+
+ return fontRet;
+}
+
+#endif // wxUSE_FONTDLG
+
+// ----------------------------------------------------------------------------
+// wxSafeYield and supporting functions
+// ----------------------------------------------------------------------------
+
+void wxEnableTopLevelWindows(bool enable)
+{
+ wxWindowList::compatibility_iterator node;
+ for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
+ node->GetData()->Enable(enable);
+}
+
+wxWindowDisabler::wxWindowDisabler(wxWindow *winToSkip)
+{
+ // remember the top level windows which were already disabled, so that we
+ // don't reenable them later
+ m_winDisabled = NULL;
+
+ wxWindowList::compatibility_iterator node;
+ for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
+ {
+ wxWindow *winTop = node->GetData();
+ if ( winTop == winToSkip )
+ continue;
+
+ // we don't need to disable the hidden or already disabled windows
+ if ( winTop->IsEnabled() && winTop->IsShown() )
+ {
+ winTop->Disable();
+ }
+ else
+ {
+ if ( !m_winDisabled )
+ {
+ m_winDisabled = new wxWindowList;
+ }
+
+ m_winDisabled->Append(winTop);
+ }
+ }
+}
+
+wxWindowDisabler::~wxWindowDisabler()
+{
+ wxWindowList::compatibility_iterator node;
+ for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
+ {
+ wxWindow *winTop = node->GetData();
+ if ( !m_winDisabled || !m_winDisabled->Find(winTop) )
+ {
+ winTop->Enable();
+ }
+ //else: had been already disabled, don't reenable
+ }
+
+ delete m_winDisabled;
+}
+
+// Yield to other apps/messages and disable user input to all windows except
+// the given one
+bool wxSafeYield(wxWindow *win, bool onlyIfNeeded)
+{
+ wxWindowDisabler wd(win);
+
+ bool rc;
+ if (onlyIfNeeded)
+ rc = wxYieldIfNeeded();
+ else
+ rc = wxYield();
+
+ return rc;
+}
+
+// Don't synthesize KeyUp events holding down a key and producing KeyDown
+// events with autorepeat. On by default and always on in wxMSW. wxGTK version
+// in utilsgtk.cpp.
+#ifndef __WXGTK__
+bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag) )
+{
+ return true; // detectable auto-repeat is the only mode MSW supports
+}
+#endif // !wxGTK
+
+#endif // wxUSE_GUI