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