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
This commit is contained in:
Vadim Zeitlin 2006-06-14 17:46:51 +00:00
parent 7cf41a5d66
commit 392c5133ff
3 changed files with 110 additions and 79 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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 )
if ( !s_htmlHelp )
{
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
{
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)
bool
wxCHMHelpController::DisplayTextPopup(const wxString& text, const wxPoint& pos)
{
return ShowContextHelpPopup(text, pos, GetParentWindow());
}
/* 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