]> git.saurik.com Git - wxWidgets.git/blob - src/msw/helpchm.cpp
88dff23aab0bda1c4e7f2a596592199340925fce
[wxWidgets.git] / src / msw / helpchm.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: helpchm.cpp
3 // Purpose: Help system: MS HTML Help implementation
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 16/04/2000
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "helpchm.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #if wxUSE_HELP && wxUSE_MS_HTML_HELP && defined(__WIN95__)
24
25 #include "wx/filefn.h"
26 #include "wx/msw/helpchm.h"
27
28 #include "wx/dynlib.h"
29
30 #include "wx/msw/private.h"
31
32 // instead of including htmlhelp.h, duplicate the things from it we need here
33
34 enum
35 {
36 HH_DISPLAY_TOPIC,
37 HH_DISPLAY_TOC,
38 HH_DISPLAY_INDEX,
39 HH_DISPLAY_SEARCH,
40 HH_SET_WIN_TYPE,
41 HH_GET_WIN_TYPE,
42 HH_GET_WIN_HANDLE,
43 HH_ENUM_INFO_TYPE,
44 HH_SET_INFO_TYPE,
45 HH_SYNC,
46 HH_RESERVED1,
47 HH_RESERVED2,
48 HH_RESERVED3,
49 HH_KEYWORD_LOOKUP,
50 HH_DISPLAY_TEXT_POPUP,
51 HH_HELP_CONTEXT,
52 HH_TP_HELP_CONTEXTMENU,
53 HH_TP_HELP_WM_HELP,
54 HH_CLOSE_ALL,
55 HH_ALINK_LOOKUP,
56 HH_GET_LAST_ERROR,
57 HH_ENUM_CATEGORY,
58 HH_ENUM_CATEGORY_IT,
59 HH_RESET_IT_FILTER,
60 HH_SET_INCLUSIVE_FILTER,
61 HH_SET_EXCLUSIVE_FILTER
62 };
63
64 struct HH_POPUP
65 {
66 int cbStruct;
67 HINSTANCE hinst;
68 UINT idString;
69 LPCTSTR pszText;
70 POINT pt;
71 COLORREF clrForeground;
72 COLORREF clrBackground;
73 RECT rcMargins;
74 LPCTSTR pszFont;
75 };
76
77 struct HH_AKLINK
78 {
79 int cbStruct;
80 BOOL fReserved;
81 LPCTSTR pszKeywords;
82 LPCTSTR pszUrl;
83 LPCTSTR pszMsgText;
84 LPCTSTR pszMsgTitle;
85 LPCTSTR pszWindow;
86 BOOL fIndexOnFail;
87 };
88
89 // ----------------------------------------------------------------------------
90 // utility functions to manage the loading/unloading
91 // of hhctrl.ocx
92 // ----------------------------------------------------------------------------
93
94 #ifndef UNICODE
95 typedef HWND ( WINAPI * HTMLHELP )( HWND, LPCSTR, UINT, DWORD );
96 #define HTMLHELP_NAME "HtmlHelpA"
97 #else // ANSI
98 typedef HWND ( WINAPI * HTMLHELP )( HWND, LPCWSTR, UINT, DWORD );
99 #define HTMLHELP_NAME "HtmlHelpW"
100 #endif
101
102 // dll symbol handle
103 static HTMLHELP gs_htmlHelp = 0;
104 static wxPluginLibrary *gs_libHtmlHelp = NULL;
105
106 static bool LoadHtmlHelpLibrary()
107 {
108 gs_libHtmlHelp = wxPluginManager::LoadLibrary( _T("HHCTRL.OCX"), wxDL_DEFAULT | wxDL_VERBATIM );
109
110 if( !gs_libHtmlHelp )
111 {
112 wxLogError(_("MS HTML Help functions are unavailable because the MS HTML Help library is not installed on this machine. Please install it."));
113 return FALSE;
114 }
115 else
116 {
117 gs_htmlHelp = (HTMLHELP)gs_libHtmlHelp->GetSymbol( HTMLHELP_NAME );
118
119 if( !gs_htmlHelp )
120 {
121 wxLogError(_("Failed to initialize MS HTML Help."));
122
123 gs_libHtmlHelp->UnrefLib();
124 return FALSE ;
125 }
126 }
127
128 return TRUE;
129 }
130
131 static void UnloadHtmlHelpLibrary()
132 {
133 if( gs_htmlHelp )
134 {
135 wxPluginManager::UnloadLibrary( _T("HHCTRL.OCX") );
136 gs_libHtmlHelp->UnrefLib();
137
138 gs_htmlHelp = 0;
139 }
140 }
141
142 static HWND GetSuitableHWND()
143 {
144 if (wxTheApp->GetTopWindow())
145 return (HWND) wxTheApp->GetTopWindow()->GetHWND();
146 else
147 return GetDesktopWindow();
148 }
149
150 IMPLEMENT_DYNAMIC_CLASS(wxCHMHelpController, wxHelpControllerBase)
151
152 bool wxCHMHelpController::Initialize(const wxString& filename)
153 {
154 // warn on failure
155 if( !LoadHtmlHelpLibrary() )
156 return FALSE;
157
158 m_helpFile = filename;
159 return TRUE;
160 }
161
162 bool wxCHMHelpController::LoadFile(const wxString& file)
163 {
164 if (!file.IsEmpty())
165 m_helpFile = file;
166 return TRUE;
167 }
168
169 bool wxCHMHelpController::DisplayContents()
170 {
171 if (m_helpFile.IsEmpty()) return FALSE;
172
173 wxString str = GetValidFilename(m_helpFile);
174
175 gs_htmlHelp(GetSuitableHWND(), (const wxChar*) str, HH_DISPLAY_TOPIC, 0L);
176 return TRUE;
177 }
178
179 // Use topic or HTML filename
180 bool wxCHMHelpController::DisplaySection(const wxString& section)
181 {
182 if (m_helpFile.IsEmpty()) return FALSE;
183
184 wxString str = GetValidFilename(m_helpFile);
185
186 // Is this an HTML file or a keyword?
187 bool isFilename = (section.Find(wxT(".htm")) != -1);
188
189 if (isFilename)
190 gs_htmlHelp(GetSuitableHWND(), (const wxChar*) str, HH_DISPLAY_TOPIC, (DWORD) (const wxChar*) section);
191 else
192 KeywordSearch(section);
193 return TRUE;
194 }
195
196 // Use context number
197 bool wxCHMHelpController::DisplaySection(int section)
198 {
199 if (m_helpFile.IsEmpty()) return FALSE;
200
201 wxString str = GetValidFilename(m_helpFile);
202
203 gs_htmlHelp(GetSuitableHWND(), (const wxChar*) str, HH_HELP_CONTEXT, (DWORD)section);
204 return TRUE;
205 }
206
207 bool wxCHMHelpController::DisplayContextPopup(int contextId)
208 {
209 if (m_helpFile.IsEmpty()) return FALSE;
210
211 wxString str = GetValidFilename(m_helpFile);
212
213 // We also have to specify the popups file (default is cshelp.txt).
214 // str += wxT("::/cshelp.txt");
215
216 HH_POPUP popup;
217 popup.cbStruct = sizeof(popup);
218 popup.hinst = (HINSTANCE) wxGetInstance();
219 popup.idString = contextId ;
220
221 GetCursorPos(& popup.pt);
222 popup.clrForeground = (COLORREF)-1;
223 popup.clrBackground = (COLORREF)-1;
224 popup.rcMargins.top = popup.rcMargins.left = popup.rcMargins.right = popup.rcMargins.bottom = -1;
225 popup.pszFont = NULL;
226 popup.pszText = NULL;
227
228 gs_htmlHelp(GetSuitableHWND(), (const wxChar*) str, HH_DISPLAY_TEXT_POPUP, (DWORD) & popup);
229 return TRUE;
230 }
231
232 bool wxCHMHelpController::DisplayTextPopup(const wxString& text, const wxPoint& pos)
233 {
234 HH_POPUP popup;
235 popup.cbStruct = sizeof(popup);
236 popup.hinst = (HINSTANCE) wxGetInstance();
237 popup.idString = 0 ;
238 popup.pt.x = pos.x; popup.pt.y = pos.y;
239 popup.clrForeground = (COLORREF)-1;
240 popup.clrBackground = (COLORREF)-1;
241 popup.rcMargins.top = popup.rcMargins.left = popup.rcMargins.right = popup.rcMargins.bottom = -1;
242 popup.pszFont = NULL;
243 popup.pszText = (const wxChar*) text;
244
245 gs_htmlHelp(GetSuitableHWND(), NULL, HH_DISPLAY_TEXT_POPUP, (DWORD) & popup);
246 return TRUE;
247 }
248
249 bool wxCHMHelpController::DisplayBlock(long block)
250 {
251 return DisplaySection(block);
252 }
253
254 bool wxCHMHelpController::KeywordSearch(const wxString& k)
255 {
256 if (m_helpFile.IsEmpty()) return FALSE;
257
258 wxString str = GetValidFilename(m_helpFile);
259
260 HH_AKLINK link;
261 link.cbStruct = sizeof(HH_AKLINK) ;
262 link.fReserved = FALSE ;
263 link.pszKeywords = k.c_str() ;
264 link.pszUrl = NULL ;
265 link.pszMsgText = NULL ;
266 link.pszMsgTitle = NULL ;
267 link.pszWindow = NULL ;
268 link.fIndexOnFail = TRUE ;
269
270 gs_htmlHelp(GetSuitableHWND(), (const wxChar*) str, HH_KEYWORD_LOOKUP, (DWORD)& link);
271 return TRUE;
272 }
273
274 bool wxCHMHelpController::Quit()
275 {
276 gs_htmlHelp(GetSuitableHWND(), 0, HH_CLOSE_ALL, 0L);
277
278 return TRUE;
279 }
280
281 // Append extension if necessary.
282 wxString wxCHMHelpController::GetValidFilename(const wxString& file) const
283 {
284 wxString path, name, ext;
285 wxSplitPath(file, & path, & name, & ext);
286
287 wxString fullName;
288 if (path.IsEmpty())
289 fullName = name + wxT(".chm");
290 else if (path.Last() == wxT('\\'))
291 fullName = path + name + wxT(".chm");
292 else
293 fullName = path + wxT("\\") + name + wxT(".chm");
294 return fullName;
295 }
296
297 wxCHMHelpController::~wxCHMHelpController()
298 {
299 UnloadHtmlHelpLibrary();
300 }
301
302 #endif // wxUSE_HELP
303