///////////////////////////////////////////////////////////////////////////// // Name: helpchm.cpp // Purpose: Help system: MS HTML Help implementation // Author: Julian Smart // Modified by: // Created: 16/04/2000 // RCS-ID: $Id$ // Copyright: (c) Julian Smart // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ #pragma implementation "helpchm.h" #endif // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #if wxUSE_HELP && wxUSE_MS_HTML_HELP && defined(__WIN95__) #include "wx/filefn.h" #include "wx/msw/helpchm.h" #include "wx/dynlib.h" #include "wx/msw/private.h" // instead of including htmlhelp.h, duplicate the things from it we need here enum { HH_DISPLAY_TOPIC, HH_DISPLAY_TOC, HH_DISPLAY_INDEX, HH_DISPLAY_SEARCH, HH_SET_WIN_TYPE, HH_GET_WIN_TYPE, HH_GET_WIN_HANDLE, HH_ENUM_INFO_TYPE, HH_SET_INFO_TYPE, HH_SYNC, HH_RESERVED1, HH_RESERVED2, HH_RESERVED3, HH_KEYWORD_LOOKUP, HH_DISPLAY_TEXT_POPUP, HH_HELP_CONTEXT, HH_TP_HELP_CONTEXTMENU, HH_TP_HELP_WM_HELP, HH_CLOSE_ALL, HH_ALINK_LOOKUP, HH_GET_LAST_ERROR, HH_ENUM_CATEGORY, HH_ENUM_CATEGORY_IT, HH_RESET_IT_FILTER, HH_SET_INCLUSIVE_FILTER, HH_SET_EXCLUSIVE_FILTER }; struct HH_POPUP { int cbStruct; HINSTANCE hinst; UINT idString; LPCTSTR pszText; POINT pt; COLORREF clrForeground; COLORREF clrBackground; RECT rcMargins; LPCTSTR pszFont; }; struct HH_AKLINK { int cbStruct; BOOL fReserved; LPCTSTR pszKeywords; LPCTSTR pszUrl; LPCTSTR pszMsgText; LPCTSTR pszMsgTitle; LPCTSTR pszWindow; BOOL fIndexOnFail; }; // ---------------------------------------------------------------------------- // utility functions to manage the loading/unloading // of hhctrl.ocx // ---------------------------------------------------------------------------- #ifndef UNICODE typedef HWND ( WINAPI * HTMLHELP )( HWND, LPCSTR, UINT, DWORD ); #define HTMLHELP_NAME "HtmlHelpA" #else // ANSI typedef HWND ( WINAPI * HTMLHELP )( HWND, LPCWSTR, UINT, DWORD ); #define HTMLHELP_NAME "HtmlHelpW" #endif // dll symbol handle static HTMLHELP gs_htmlHelp = 0; static bool LoadHtmlHelpLibrary() { wxPluginLibrary *lib = wxPluginManager::LoadLibrary( _T("HHCTRL.OCX"), wxDL_DEFAULT | wxDL_VERBATIM ); 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 { gs_htmlHelp = (HTMLHELP)lib->GetSymbol( HTMLHELP_NAME ); if( !gs_htmlHelp ) { wxLogError(_("Failed to initialize MS HTML Help.")); lib->UnrefLib(); return FALSE ; } } return TRUE; } static void UnloadHtmlHelpLibrary() { if ( gs_htmlHelp ) { wxPluginManager::UnloadLibrary( _T("HHCTRL.OCX") ); gs_htmlHelp = 0; } } static HWND GetSuitableHWND() { if (wxTheApp->GetTopWindow()) return (HWND) wxTheApp->GetTopWindow()->GetHWND(); else return GetDesktopWindow(); } IMPLEMENT_DYNAMIC_CLASS(wxCHMHelpController, wxHelpControllerBase) bool wxCHMHelpController::Initialize(const wxString& filename) { // warn on failure if( !LoadHtmlHelpLibrary() ) return FALSE; m_helpFile = filename; return TRUE; } bool wxCHMHelpController::LoadFile(const wxString& file) { if (!file.IsEmpty()) m_helpFile = file; return TRUE; } bool wxCHMHelpController::DisplayContents() { if (m_helpFile.IsEmpty()) return FALSE; wxString str = GetValidFilename(m_helpFile); gs_htmlHelp(GetSuitableHWND(), (const wxChar*) str, HH_DISPLAY_TOPIC, 0L); return TRUE; } // Use topic or HTML filename bool wxCHMHelpController::DisplaySection(const wxString& section) { 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")) != -1); if (isFilename) gs_htmlHelp(GetSuitableHWND(), (const wxChar*) str, HH_DISPLAY_TOPIC, (DWORD) (const wxChar*) section); else KeywordSearch(section); return TRUE; } // Use context number bool wxCHMHelpController::DisplaySection(int section) { if (m_helpFile.IsEmpty()) return FALSE; wxString str = GetValidFilename(m_helpFile); gs_htmlHelp(GetSuitableHWND(), (const wxChar*) str, HH_HELP_CONTEXT, (DWORD)section); return TRUE; } bool wxCHMHelpController::DisplayContextPopup(int contextId) { if (m_helpFile.IsEmpty()) return FALSE; wxString str = GetValidFilename(m_helpFile); // We also have to specify the popups file (default is cshelp.txt). // str += wxT("::/cshelp.txt"); HH_POPUP popup; popup.cbStruct = sizeof(popup); popup.hinst = (HINSTANCE) wxGetInstance(); popup.idString = contextId ; GetCursorPos(& popup.pt); popup.clrForeground = (COLORREF)-1; popup.clrBackground = (COLORREF)-1; popup.rcMargins.top = popup.rcMargins.left = popup.rcMargins.right = popup.rcMargins.bottom = -1; popup.pszFont = NULL; popup.pszText = NULL; gs_htmlHelp(GetSuitableHWND(), (const wxChar*) str, HH_DISPLAY_TEXT_POPUP, (DWORD) & popup); return TRUE; } bool wxCHMHelpController::DisplayTextPopup(const wxString& text, const wxPoint& pos) { HH_POPUP popup; popup.cbStruct = sizeof(popup); popup.hinst = (HINSTANCE) wxGetInstance(); popup.idString = 0 ; popup.pt.x = pos.x; popup.pt.y = pos.y; popup.clrForeground = (COLORREF)-1; popup.clrBackground = (COLORREF)-1; popup.rcMargins.top = popup.rcMargins.left = popup.rcMargins.right = popup.rcMargins.bottom = -1; popup.pszFont = NULL; popup.pszText = (const wxChar*) text; gs_htmlHelp(GetSuitableHWND(), NULL, HH_DISPLAY_TEXT_POPUP, (DWORD) & popup); return TRUE; } bool wxCHMHelpController::DisplayBlock(long block) { return DisplaySection(block); } bool wxCHMHelpController::KeywordSearch(const wxString& k) { if (m_helpFile.IsEmpty()) return FALSE; wxString str = GetValidFilename(m_helpFile); HH_AKLINK link; link.cbStruct = sizeof(HH_AKLINK) ; link.fReserved = FALSE ; link.pszKeywords = k.c_str() ; link.pszUrl = NULL ; link.pszMsgText = NULL ; link.pszMsgTitle = NULL ; link.pszWindow = NULL ; link.fIndexOnFail = TRUE ; gs_htmlHelp(GetSuitableHWND(), (const wxChar*) str, HH_KEYWORD_LOOKUP, (DWORD)& link); return TRUE; } bool wxCHMHelpController::Quit() { gs_htmlHelp(GetSuitableHWND(), 0, HH_CLOSE_ALL, 0L); return TRUE; } // Append extension if necessary. wxString wxCHMHelpController::GetValidFilename(const wxString& file) const { wxString path, name, ext; wxSplitPath(file, & path, & name, & ext); wxString fullName; if (path.IsEmpty()) fullName = name + wxT(".chm"); else if (path.Last() == wxT('\\')) fullName = path + name + wxT(".chm"); else fullName = path + wxT("\\") + name + wxT(".chm"); return fullName; } wxCHMHelpController::~wxCHMHelpController() { UnloadHtmlHelpLibrary(); } #endif // wxUSE_HELP