From 392c5133ff8aba785fece7aef8f63f99843e8aa1 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 14 Jun 2006 17:46:51 +0000 Subject: [PATCH] show native-looking (with 3D shadow) help tooltips for context help, if possible, using wxCHMHelpController git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@39725 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/msw/helpchm.h | 6 +- src/common/cshelp.cpp | 54 +++++++++++----- src/msw/helpchm.cpp | 129 ++++++++++++++++++++------------------- 3 files changed, 110 insertions(+), 79 deletions(-) diff --git a/include/wx/msw/helpchm.h b/include/wx/msw/helpchm.h index 72afc643dc..859290f94c 100644 --- a/include/wx/msw/helpchm.h +++ b/include/wx/msw/helpchm.h @@ -20,7 +20,6 @@ class WXDLLEXPORT wxCHMHelpController : public wxHelpControllerBase { public: wxCHMHelpController(wxWindow* parentWindow = NULL): wxHelpControllerBase(parentWindow) { } - virtual ~wxCHMHelpController(); // Must call this to set the filename virtual bool Initialize(const wxString& file); @@ -40,6 +39,11 @@ public: wxString GetHelpFile() const { return m_helpFile; } + // helper of DisplayTextPopup(), also used in wxSimpleHelpProvider::ShowHelp + static bool ShowContextHelpPopup(const wxString& text, + const wxPoint& pos, + wxWindow *window); + protected: // Append extension if necessary. wxString GetValidFilename(const wxString& file) const; diff --git a/src/common/cshelp.cpp b/src/common/cshelp.cpp index 2a16628047..ec7ec40de0 100644 --- a/src/common/cshelp.cpp +++ b/src/common/cshelp.cpp @@ -34,6 +34,11 @@ #include "wx/module.h" #include "wx/cshelp.h" +#if wxUSE_MS_HTML_HELP + #include "wx/msw/helpchm.h" // for ShowContextHelpPopup + #include "wx/utils.h" // for wxGetMousePosition() +#endif + // ---------------------------------------------------------------------------- // wxContextHelpEvtHandler private class // ---------------------------------------------------------------------------- @@ -378,29 +383,46 @@ void wxSimpleHelpProvider::RemoveHelp(wxWindowBase* window) bool wxSimpleHelpProvider::ShowHelp(wxWindowBase *window) { -#if wxUSE_TIPWINDOW - static wxTipWindow* s_tipWindow = NULL; - - if (s_tipWindow) - { - // Prevent s_tipWindow being nulled in OnIdle, - // thereby removing the chance for the window to be closed by ShowHelp - s_tipWindow->SetTipWindowPtr(NULL); - s_tipWindow->Close(); - } - s_tipWindow = NULL; - +#if wxUSE_MS_HTML_HELP || wxUSE_TIPWINDOW const wxString text = GetHelpTextMaybeAtPoint(window); + if ( !text.empty() ) { - s_tipWindow = new wxTipWindow((wxWindow *)window, text, - 100, &s_tipWindow); + // use the native help popup style if it's available +#if wxUSE_MS_HTML_HELP + if ( !wxCHMHelpController::ShowContextHelpPopup + ( + text, + wxGetMousePosition(), + (wxWindow *)window + ) ) +#endif // wxUSE_MS_HTML_HELP + { +#if wxUSE_TIPWINDOW + static wxTipWindow* s_tipWindow = NULL; + + if ( s_tipWindow ) + { + // Prevent s_tipWindow being nulled in OnIdle, thereby removing + // the chance for the window to be closed by ShowHelp + s_tipWindow->SetTipWindowPtr(NULL); + s_tipWindow->Close(); + } + + s_tipWindow = new wxTipWindow((wxWindow *)window, text, + 100, &s_tipWindow); +#else // !wxUSE_TIPWINDOW + // we tried wxCHMHelpController but it failed and we don't have + // wxTipWindow to fall back on, so + return false; +#endif // wxUSE_TIPWINDOW + } return true; } -#else +#else // !wxUSE_MS_HTML_HELP && !wxUSE_TIPWINDOW wxUnusedVar(window); -#endif // wxUSE_TIPWINDOW +#endif // wxUSE_MS_HTML_HELP || wxUSE_TIPWINDOW return false; } diff --git a/src/msw/helpchm.cpp b/src/msw/helpchm.cpp index 2d964b0011..411d495980 100644 --- a/src/msw/helpchm.cpp +++ b/src/msw/helpchm.cpp @@ -44,59 +44,58 @@ #define HTMLHELP_NAME wxT("HtmlHelpW") #endif -// dll symbol handle -static HTMLHELP gs_htmlHelp = 0; - -static bool LoadHtmlHelpLibrary() +HTMLHELP GetHtmlHelpFunction() { - wxPluginLibrary *lib = wxPluginManager::LoadLibrary( _T("HHCTRL.OCX"), wxDL_DEFAULT | wxDL_VERBATIM ); + static HTMLHELP s_htmlHelp = NULL; - if( !lib ) - { - wxLogError(_("MS HTML Help functions are unavailable because the MS HTML Help library is not installed on this machine. Please install it.")); - return false; - } - else + if ( !s_htmlHelp ) { - gs_htmlHelp = (HTMLHELP)lib->GetSymbol( HTMLHELP_NAME ); + static wxDynamicLibrary s_dllHtmlHelp(_T("HHCTRL.OCX"), wxDL_VERBATIM); - if( !gs_htmlHelp ) + if ( !s_dllHtmlHelp.IsLoaded() ) { - wxLogError(_("Failed to initialize MS HTML Help.")); - - lib->UnrefLib(); - return false ; + wxLogError(_("MS HTML Help functions are unavailable because the MS HTML Help library is not installed on this machine. Please install it.")); + } + else + { + s_htmlHelp = (HTMLHELP)s_dllHtmlHelp.GetSymbol(HTMLHELP_NAME); + if ( !s_htmlHelp ) + { + wxLogError(_("Failed to initialize MS HTML Help.")); + } } } - return true; + return s_htmlHelp; } -static void UnloadHtmlHelpLibrary() +// find the window to use in HtmlHelp() call: use the given one by default but +// fall back to the top level app window and then the desktop if it's NULL +static HWND GetSuitableHWND(wxWindow *win) { - if ( gs_htmlHelp ) - { - if (wxPluginManager::UnloadLibrary( _T("HHCTRL.OCX") )) - gs_htmlHelp = 0; - } + if ( !win && wxTheApp ) + win = wxTheApp->GetTopWindow(); + + return win ? GetHwndOf(win) : ::GetDesktopWindow(); } -static HWND GetSuitableHWND(wxCHMHelpController* controller) +// wrap the real HtmlHelp() but just return false (and not crash) if it +// couldn't be loaded +// +// it also takes a wxWindow instead of HWND +static bool +CallHtmlHelpFunction(wxWindow *win, const wxChar *str, UINT uint, DWORD dword) { - if (controller->GetParentWindow()) - return (HWND) controller->GetParentWindow()->GetHWND(); - else if (wxTheApp->GetTopWindow()) - return (HWND) wxTheApp->GetTopWindow()->GetHWND(); - else - return GetDesktopWindow(); + HTMLHELP htmlHelp = GetHtmlHelpFunction(); + + return htmlHelp && htmlHelp(GetSuitableHWND(win), str, uint, dword); } IMPLEMENT_DYNAMIC_CLASS(wxCHMHelpController, wxHelpControllerBase) bool wxCHMHelpController::Initialize(const wxString& filename) { - // warn on failure - if( !LoadHtmlHelpLibrary() ) + if ( !GetHtmlHelpFunction() ) return false; m_helpFile = filename; @@ -112,40 +111,43 @@ bool wxCHMHelpController::LoadFile(const wxString& file) bool wxCHMHelpController::DisplayContents() { - if (m_helpFile.IsEmpty()) return false; + if (m_helpFile.IsEmpty()) + return false; wxString str = GetValidFilename(m_helpFile); - gs_htmlHelp(GetSuitableHWND(this), (const wxChar*) str, HH_DISPLAY_TOPIC, 0L); - return true; + return CallHtmlHelpFunction(GetParentWindow(), str, HH_DISPLAY_TOPIC, 0L); } // Use topic or HTML filename bool wxCHMHelpController::DisplaySection(const wxString& section) { - if (m_helpFile.IsEmpty()) return false; + if (m_helpFile.IsEmpty()) + return false; wxString str = GetValidFilename(m_helpFile); // Is this an HTML file or a keyword? - bool isFilename = (section.Find(wxT(".htm")) != wxNOT_FOUND); + if ( section.Find(wxT(".htm")) != wxNOT_FOUND ) + { + // interpret as a file name + return CallHtmlHelpFunction(GetParentWindow(), str, HH_DISPLAY_TOPIC, + wxPtrToUInt(section.c_str())); + } - if (isFilename) - gs_htmlHelp(GetSuitableHWND(this), (const wxChar*) str, HH_DISPLAY_TOPIC, (DWORD) (const wxChar*) section); - else - KeywordSearch(section); - return true; + return KeywordSearch(section); } // Use context number bool wxCHMHelpController::DisplaySection(int section) { - if (m_helpFile.IsEmpty()) return false; + if (m_helpFile.IsEmpty()) + return false; wxString str = GetValidFilename(m_helpFile); - gs_htmlHelp(GetSuitableHWND(this), (const wxChar*) str, HH_HELP_CONTEXT, (DWORD)section); - return true; + return CallHtmlHelpFunction(GetParentWindow(), str, HH_HELP_CONTEXT, + (DWORD)section); } bool wxCHMHelpController::DisplayContextPopup(int contextId) @@ -169,11 +171,20 @@ bool wxCHMHelpController::DisplayContextPopup(int contextId) popup.pszFont = NULL; popup.pszText = NULL; - gs_htmlHelp(GetSuitableHWND(this), (const wxChar*) str, HH_DISPLAY_TEXT_POPUP, (DWORD) & popup); - return true; + return CallHtmlHelpFunction(GetParentWindow(), str, HH_DISPLAY_TEXT_POPUP, + wxPtrToUInt(&popup)); +} + +bool +wxCHMHelpController::DisplayTextPopup(const wxString& text, const wxPoint& pos) +{ + return ShowContextHelpPopup(text, pos, GetParentWindow()); } -bool wxCHMHelpController::DisplayTextPopup(const wxString& text, const wxPoint& pos) +/* static */ +bool wxCHMHelpController::ShowContextHelpPopup(const wxString& text, + const wxPoint& pos, + wxWindow *window) { HH_POPUP popup; popup.cbStruct = sizeof(popup); @@ -186,8 +197,8 @@ bool wxCHMHelpController::DisplayTextPopup(const wxString& text, const wxPoint& popup.pszFont = NULL; popup.pszText = (const wxChar*) text; - gs_htmlHelp(GetSuitableHWND(this), NULL, HH_DISPLAY_TEXT_POPUP, (DWORD) & popup); - return true; + return CallHtmlHelpFunction(window, NULL, HH_DISPLAY_TEXT_POPUP, + wxPtrToUInt(&popup)); } bool wxCHMHelpController::DisplayBlock(long block) @@ -198,7 +209,8 @@ bool wxCHMHelpController::DisplayBlock(long block) bool wxCHMHelpController::KeywordSearch(const wxString& k, wxHelpSearchMode WXUNUSED(mode)) { - if (m_helpFile.IsEmpty()) return false; + if (m_helpFile.IsEmpty()) + return false; wxString str = GetValidFilename(m_helpFile); @@ -212,15 +224,13 @@ bool wxCHMHelpController::KeywordSearch(const wxString& k, link.pszWindow = NULL ; link.fIndexOnFail = TRUE ; - gs_htmlHelp(GetSuitableHWND(this), (const wxChar*) str, HH_KEYWORD_LOOKUP, (DWORD)& link); - return true; + return CallHtmlHelpFunction(GetParentWindow(), str, HH_KEYWORD_LOOKUP, + wxPtrToUInt(&link)); } bool wxCHMHelpController::Quit() { - gs_htmlHelp(GetSuitableHWND(this), 0, HH_CLOSE_ALL, 0L); - - return true; + return CallHtmlHelpFunction(GetParentWindow(), NULL, HH_CLOSE_ALL, 0L); } // Append extension if necessary. @@ -239,9 +249,4 @@ wxString wxCHMHelpController::GetValidFilename(const wxString& file) const return fullName; } -wxCHMHelpController::~wxCHMHelpController() -{ - UnloadHtmlHelpLibrary(); -} - #endif // wxUSE_HELP -- 2.45.2