// Name: htmlhelp.cpp // Purpose: Help controller // Author: Vaclav Slavik // Copyright: (c) 1999 Vaclav Slavik // Licence: wxWindows Licence ///////////////////////////////////////////////////////////////////////////// #error This file should not be compiled! Update your build system! \ (configure users, rerun configure to get a new Makefile) \ Instead of htmlhelp[_io], use helpdata, helpfrm and helpctrl. This \ file is only left to point out the problem and will be removed r.s.n. #ifdef __GNUG__ #pragma implementation "htmlhelp.h" #endif #include "wx/wxprec.h" #if wxUSE_HTML #ifdef __BORDLANDC__ #pragma hdrstop #endif #ifndef WXPRECOMP #endif #include #include #include #include #include #include #include #include #if !((wxVERSION_NUMBER < 2100) || ((wxVERSION_NUMBER == 2100) && (wxBETA_NUMBER < 7))) #include #endif // Bitmaps: #ifndef __WXMSW__ // XPM hack: make the arrays const #define static static const #include "bitmaps/panel.xpm" #include "bitmaps/back.xpm" #include "bitmaps/forward.xpm" #include "bitmaps/book.xpm" #include "bitmaps/folder.xpm" #include "bitmaps/page.xpm" #undef static #endif #include "search.h" #include WX_DEFINE_OBJARRAY(HtmlBookRecArray) //----------------------------------------------------------------------------- // wxHtmlHelpController //----------------------------------------------------------------------------- IMPLEMENT_DYNAMIC_CLASS(wxHtmlHelpController, wxEvtHandler) wxHtmlHelpController::wxHtmlHelpController() : wxEvtHandler() { m_Frame = NULL; m_Config = NULL; m_ConfigRoot = wxEmptyString; m_TitleFormat = _("Help : %s"); m_TempPath = wxEmptyString; m_Cfg.x = m_Cfg.y = 0; m_Cfg.w = 700; m_Cfg.h = 480; m_Cfg.sashpos = 240; m_Cfg.navig_on = TRUE; m_ContentsImageList = new wxImageList(12, 12); m_ContentsImageList -> Add(wxICON(book)); m_ContentsImageList -> Add(wxICON(folder)); m_ContentsImageList -> Add(wxICON(page)); m_Contents = NULL; m_ContentsCnt = 0; m_Index = NULL; m_IndexCnt = 0; m_IndexBox = NULL; m_ContentsBox = NULL; m_SearchList = NULL; m_SearchText = NULL; m_SearchButton = NULL; m_HtmlWin = NULL; m_Splitter = NULL; m_NavigPan = NULL; } wxHtmlHelpController::~wxHtmlHelpController() { int i; m_BookRecords.Empty(); delete m_ContentsImageList; if (m_Contents) { for (i = 0; i < m_ContentsCnt; i++) { delete[] m_Contents[i].m_Page; delete[] m_Contents[i].m_Name; } free(m_Contents); } if (m_Index) { for (i = 0; i < m_IndexCnt; i++) { delete[] m_Index[i].m_Page; delete[] m_Index[i].m_Name; } free(m_Index); } } void wxHtmlHelpController::SetTempDir(const wxString& path) { if (path == wxEmptyString) m_TempPath = path; else { if (wxIsAbsolutePath(path)) m_TempPath = path; else m_TempPath = wxGetCwd() + "/" + path; if (m_TempPath[m_TempPath.Length() - 1] != '/') m_TempPath << "/"; } } // Reads one line, stores it into buf and returns pointer to new line or NULL. static char* ReadLine(char *line, char *buf) { char *writeptr = buf, *readptr = line; while (*readptr != 0 && *readptr != '\r' && *readptr != '\n') *(writeptr++) = *(readptr++); *writeptr = 0; while (*readptr == '\r' || *readptr == '\n') readptr++; if (*readptr == 0) return NULL; else return readptr; } static wxString SafeFileName(const wxString& s) { wxString res = s; res.Replace(_T(":"), _T("_"), TRUE); res.Replace(_T(" "), _T("_"), TRUE); res.Replace(_T("/"), _T("_"), TRUE); res.Replace(_T("\\"), _T("_"), TRUE); res.Replace(_T("#"), _T("_"), TRUE); res.Replace(_T("."), _T("_"), TRUE); return res; } static int IndexCompareFunc(const void *a, const void *b) { return strcmp(((HtmlContentsItem*)a) -> m_Name, ((HtmlContentsItem*)b) -> m_Name); } bool wxHtmlHelpController::AddBook(const wxString& book, bool show_wait_msg) { wxFSFile *fi; wxFileSystem fsys; wxInputStream *s; HtmlBookRecord *bookr; wxString bookFull; int sz; char *buff, *lineptr; char linebuf[300]; wxString title = _("noname"), safetitle, start = wxEmptyString, contents = wxEmptyString, index = wxEmptyString; if (wxIsAbsolutePath(book)) bookFull = book; else bookFull = wxGetCwd() + "/" + book; fi = fsys.OpenFile(bookFull); if (fi == NULL) return FALSE; fsys.ChangePathTo(bookFull); s = fi -> GetStream(); sz = s -> GetSize(); buff = new char[sz+1]; buff[sz] = 0; s -> Read(buff, sz); lineptr = buff; delete fi; while ((lineptr = ReadLine(lineptr, linebuf)) != NULL) { if (strstr(linebuf, "Title=") == linebuf) title = linebuf + strlen("Title="); if (strstr(linebuf, "Default topic=") == linebuf) start = linebuf + strlen("Default topic="); if (strstr(linebuf, "Index file=") == linebuf) index = linebuf + strlen("Index file="); if (strstr(linebuf, "Contents file=") == linebuf) contents = linebuf + strlen("Contents file="); } delete[] buff; bookr = new HtmlBookRecord(fsys.GetPath(), title, start); if (m_ContentsCnt % HTML_REALLOC_STEP == 0) m_Contents = (HtmlContentsItem*) realloc(m_Contents, (m_ContentsCnt + HTML_REALLOC_STEP) * sizeof(HtmlContentsItem)); m_Contents[m_ContentsCnt].m_Level = 0; m_Contents[m_ContentsCnt].m_ID = 0; m_Contents[m_ContentsCnt].m_Page = new char[start.Length() + 1]; strcpy(m_Contents[m_ContentsCnt].m_Page, start.c_str()); m_Contents[m_ContentsCnt].m_Name = new char [title.Length() + 1]; strcpy(m_Contents[m_ContentsCnt].m_Name, title.c_str()); m_Contents[m_ContentsCnt].m_Book = bookr; m_ContentsCnt++; // Try to find cached binary versions: safetitle = SafeFileName(title); fi = fsys.OpenFile(safetitle + ".cached"); if (fi == NULL) fi = fsys.OpenFile(m_TempPath + safetitle + ".cached"); if ((fi == NULL) || (m_TempPath == wxEmptyString)) { LoadMSProject(bookr, fsys, index, contents, show_wait_msg); if (m_TempPath != wxEmptyString) { wxFileOutputStream *outs = new wxFileOutputStream(m_TempPath + safetitle + ".cached"); SaveCachedBook(bookr, outs); delete outs; } } else { LoadCachedBook(bookr, fi -> GetStream()); delete fi; } m_BookRecords.Add(bookr); if (m_IndexCnt > 0) qsort(m_Index, m_IndexCnt, sizeof(HtmlContentsItem), IndexCompareFunc); return TRUE; } void wxHtmlHelpController::Display(const wxString& x) { int cnt; int i; wxFileSystem fsys; wxFSFile *f; CreateHelpWindow(); /* 1. try to open given file: */ cnt = m_BookRecords.GetCount(); for (i = 0; i < cnt; i++) { f = fsys.OpenFile(m_BookRecords[i].GetBasePath() + x); if (f) { m_HtmlWin -> LoadPage(m_BookRecords[i].GetBasePath() + x); delete f; return; } } /* 2. try to find a book: */ for (i = 0; i < cnt; i++) { if (m_BookRecords[i].GetTitle() == x) { m_HtmlWin -> LoadPage(m_BookRecords[i].GetBasePath() + m_BookRecords[i].GetStart()); return; } } /* 3. try to find in contents: */ cnt = m_ContentsCnt; for (i = 0; i < cnt; i++) { if (strcmp(m_Contents[i].m_Name, x) == 0) { m_HtmlWin -> LoadPage(m_Contents[i].m_Book -> GetBasePath() + m_Contents[i].m_Page); return; } } /* 4. try to find in index: */ cnt = m_IndexCnt; for (i = 0; i < cnt; i++) { if (strcmp(m_Index[i].m_Name, x) == 0) { m_HtmlWin -> LoadPage(m_Index[i].m_Book -> GetBasePath() + m_Index[i].m_Page); return; } } /* 5. if everything failed, search the documents: */ KeywordSearch(x); } void wxHtmlHelpController::Display(const int id) { CreateHelpWindow(); for (int i = 0; i < m_ContentsCnt; i++) { if (m_Contents[i].m_ID == id) { m_HtmlWin -> LoadPage(m_Contents[i].m_Book -> GetBasePath() + m_Contents[i].m_Page); return; } } } void wxHtmlHelpController::DisplayContents() { CreateHelpWindow(); m_Frame -> Raise(); if (!m_Splitter -> IsSplit()) { m_NavigPan -> Show(TRUE); m_HtmlWin -> Show(TRUE); m_Splitter -> SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos); } m_NavigPan -> SetSelection(0); } void wxHtmlHelpController::DisplayIndex() { CreateHelpWindow(); m_Frame -> Raise(); if (!m_Splitter -> IsSplit()) { m_NavigPan -> Show(TRUE); m_HtmlWin -> Show(TRUE); m_Splitter -> SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos); } m_NavigPan -> SetSelection(1); } #if (wxVERSION_NUMBER < 2100) || ((wxVERSION_NUMBER == 2100) && (wxBETA_NUMBER < 7)) class MyProgressDlg : public wxDialog { public: bool m_Canceled; MyProgressDlg(wxWindow *parent) : wxDialog(parent, -1, _("Searching..."), wxPoint(0, 0), #ifdef __WXGTK__ wxSize(300, 110) #else wxSize(300, 130) #endif ) {m_Canceled = FALSE;} void OnCancel(wxCommandEvent& event) {m_Canceled = TRUE;} DECLARE_EVENT_TABLE() }; BEGIN_EVENT_TABLE(MyProgressDlg, wxDialog) EVT_BUTTON(wxID_CANCEL, MyProgressDlg::OnCancel) END_EVENT_TABLE() #endif bool wxHtmlHelpController::KeywordSearch(const wxString& keyword) { int foundcnt = 0; CreateHelpWindow(); // if these are not set, we can't continue if (! (m_SearchList && m_HtmlWin)) return FALSE; m_Frame -> Raise(); if (m_Splitter && m_NavigPan && m_SearchButton) { if (!m_Splitter -> IsSplit()) { m_NavigPan -> Show(TRUE); m_HtmlWin -> Show(TRUE); m_Splitter -> SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos); } m_NavigPan -> SetSelection(2); m_SearchList -> Clear(); m_SearchText -> SetValue(keyword); m_SearchButton -> Enable(FALSE); } { int cnt = m_ContentsCnt; wxSearchEngine engine; wxFileSystem fsys; wxFSFile *file; wxString lastpage = wxEmptyString; wxString foundstr; #if (wxVERSION_NUMBER < 2100) || ((wxVERSION_NUMBER == 2100) && (wxBETA_NUMBER < 7)) MyProgressDlg progress(m_Frame); wxStaticText *prompt = new wxStaticText(&progress, -1, "", wxPoint(20, 50), wxSize(260, 25), wxALIGN_CENTER); wxGauge *gauge = new wxGauge(&progress, -1, cnt, wxPoint(20, 20), wxSize(260, 25)); wxButton *btn = new wxButton(&progress, wxID_CANCEL, _("Cancel"), wxPoint(110, 70), wxSize(80, 25)); btn = btn; /* fool compiler :-) */ prompt -> SetLabel(_("No matching page found yet")); progress.Centre(wxBOTH); progress.Show(TRUE); #else wxProgressDialog progress(_("Searching..."), _("No matching page found yet"), cnt, m_Frame, wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_AUTO_HIDE); #endif engine.LookFor(keyword); for (int i = 0; i < cnt; i++) { #if (wxVERSION_NUMBER < 2100) || ((wxVERSION_NUMBER == 2100) && (wxBETA_NUMBER < 7)) gauge -> SetValue(i); if (progress.m_Canceled) break; #else if (progress.Update(i) == FALSE) break; #endif wxYield(); file = fsys.OpenFile(m_Contents[i].m_Book -> GetBasePath() + m_Contents[i].m_Page); if (file) { if (lastpage != file -> GetLocation()) { lastpage = file -> GetLocation(); if (engine.Scan(file -> GetStream())) { foundstr.Printf(_("Found %i matches"), ++foundcnt); #if (wxVERSION_NUMBER < 2100) || ((wxVERSION_NUMBER == 2100) && (wxBETA_NUMBER < 7)) prompt -> SetLabel(foundstr); #else progress.Update(i, foundstr); #endif wxYield(); m_SearchList -> Append(m_Contents[i].m_Name, (char*)(m_Contents + i)); } } delete file; } } #if (wxVERSION_NUMBER < 2100) || ((wxVERSION_NUMBER == 2100) && (wxBETA_NUMBER < 7)) progress.Close(TRUE); #endif } if (m_SearchButton) m_SearchButton -> Enable(TRUE); if (m_SearchText) { m_SearchText -> SetSelection(0, keyword.Length()); m_SearchText -> SetFocus(); } if (foundcnt) { HtmlContentsItem *it = (HtmlContentsItem*) m_SearchList -> GetClientData(0); if (it) m_HtmlWin -> LoadPage(it -> m_Book -> GetBasePath() + it -> m_Page); } return (foundcnt > 0); } void wxHtmlHelpController::CreateHelpWindow() { wxBusyCursor cur; wxString oldpath; wxStatusBar *sbar; if (m_Frame) { m_Frame -> Raise(); m_Frame -> Show(TRUE); return; } #if wxUSE_BUSYINFO wxBusyInfo busyinfo(_("Preparing help window...")); #endif if (m_Config) ReadCustomization(m_Config, m_ConfigRoot); m_Frame = new wxFrame(NULL, -1, "", wxPoint(m_Cfg.x, m_Cfg.y), wxSize(m_Cfg.w, m_Cfg.h)); m_Frame -> PushEventHandler(this); sbar = m_Frame -> CreateStatusBar(); { wxToolBar *toolBar; toolBar = m_Frame -> CreateToolBar(wxNO_BORDER | wxTB_HORIZONTAL | wxTB_FLAT | wxTB_DOCKABLE); toolBar -> SetMargins(2, 2); wxBitmap* toolBarBitmaps[3]; #ifdef __WXMSW__ toolBarBitmaps[0] = new wxBitmap("panel"); toolBarBitmaps[1] = new wxBitmap("back"); toolBarBitmaps[2] = new wxBitmap("forward"); int width = 24; #else toolBarBitmaps[0] = new wxBitmap(panel_xpm); toolBarBitmaps[1] = new wxBitmap(back_xpm); toolBarBitmaps[2] = new wxBitmap(forward_xpm); int width = 16; #endif int currentX = 5; toolBar -> AddTool(wxID_HTML_PANEL, *(toolBarBitmaps[0]), wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, _("Show/hide navigation panel")); currentX += width + 5; toolBar -> AddSeparator(); toolBar -> AddTool(wxID_HTML_BACK, *(toolBarBitmaps[1]), wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, _("Go back to the previous HTML page")); currentX += width + 5; toolBar -> AddTool(wxID_HTML_FORWARD, *(toolBarBitmaps[2]), wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, _("Go forward to the next HTML page")); currentX += width + 5; toolBar -> Realize(); // Can delete the bitmaps since they're reference counted for (int i = 0; i < 3; i++) delete toolBarBitmaps[i]; } { m_Splitter = new wxSplitterWindow(m_Frame); m_HtmlWin = new wxHtmlWindow(m_Splitter); m_HtmlWin -> SetRelatedFrame(m_Frame, m_TitleFormat); m_HtmlWin -> SetRelatedStatusBar(0); if (m_Config) m_HtmlWin -> ReadCustomization(m_Config, m_ConfigRoot); m_NavigPan = new wxNotebook(m_Splitter, wxID_HTML_NOTEBOOK, wxDefaultPosition, wxDefaultSize); { m_ContentsBox = new wxTreeCtrl(m_NavigPan, wxID_HTML_TREECTRL, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS | wxSUNKEN_BORDER); m_ContentsBox -> SetImageList(m_ContentsImageList); m_NavigPan -> AddPage(m_ContentsBox, _("Contents")); } { wxWindow *dummy = new wxPanel(m_NavigPan, wxID_HTML_INDEXPAGE); wxLayoutConstraints *b1 = new wxLayoutConstraints; b1 -> top.SameAs (dummy, wxTop, 0); b1 -> left.SameAs (dummy, wxLeft, 0); b1 -> width.PercentOf (dummy, wxWidth, 100); b1 -> bottom.SameAs (dummy, wxBottom, 0); m_IndexBox = new wxListBox(dummy, wxID_HTML_INDEXLIST, wxDefaultPosition, wxDefaultSize, 0); m_IndexBox -> SetConstraints(b1); dummy -> SetAutoLayout(TRUE); m_NavigPan -> AddPage(dummy, _("Index")); } { wxWindow *dummy = new wxPanel(m_NavigPan, wxID_HTML_SEARCHPAGE); wxLayoutConstraints *b1 = new wxLayoutConstraints; m_SearchText = new wxTextCtrl(dummy, wxID_HTML_SEARCHTEXT); b1 -> top.SameAs (dummy, wxTop, 0); b1 -> left.SameAs (dummy, wxLeft, 0); b1 -> right.SameAs (dummy, wxRight, 0); b1 -> height.AsIs(); m_SearchText -> SetConstraints(b1); wxLayoutConstraints *b2 = new wxLayoutConstraints; m_SearchButton = new wxButton(dummy, wxID_HTML_SEARCHBUTTON, _("Search!")); b2 -> top.Below (m_SearchText, 10); b2 -> right.SameAs (dummy, wxRight, 10); b2 -> width.AsIs(); b2 -> height.AsIs(); m_SearchButton -> SetConstraints(b2); wxLayoutConstraints *b3 = new wxLayoutConstraints; m_SearchList = new wxListBox(dummy, wxID_HTML_SEARCHLIST, wxDefaultPosition, wxDefaultSize, 0); b3 -> top.Below (m_SearchButton, 10); b3 -> left.SameAs (dummy, wxLeft, 0); b3 -> right.SameAs (dummy, wxRight, 0); b3 -> bottom.SameAs (dummy, wxBottom, 0); m_SearchList -> SetConstraints(b3); dummy -> SetAutoLayout(TRUE); dummy -> Layout(); m_NavigPan -> AddPage(dummy, _("Search")); } RefreshLists(); m_NavigPan -> Show(TRUE); m_HtmlWin -> Show(TRUE); m_Splitter -> SetMinimumPaneSize(20); m_Splitter -> SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos); if (!m_Cfg.navig_on) m_Splitter -> Unsplit(m_NavigPan); wxYield(); } m_Frame -> Show(TRUE); wxYield(); } #define MAX_ROOTS 64 void wxHtmlHelpController::CreateContents() { HtmlContentsItem *it; wxTreeItemId roots[MAX_ROOTS]; bool imaged[MAX_ROOTS]; int count = m_ContentsCnt; m_ContentsBox -> DeleteAllItems(); roots[0] = m_ContentsBox -> AddRoot(_("(Help)")); imaged[0] = TRUE; for (int i = 0; i < count; i++) { it = m_Contents + i; roots[it -> m_Level + 1] = m_ContentsBox -> AppendItem(roots[it -> m_Level], it -> m_Name, IMG_Page, -1, new wxHtmlHelpTreeItemData(it)); if (it -> m_Level == 0) { m_ContentsBox -> SetItemBold(roots[1], TRUE); m_ContentsBox -> SetItemImage(roots[1], IMG_Book); m_ContentsBox -> SetItemSelectedImage(roots[1], IMG_Book); imaged[1] = TRUE; } else imaged[it -> m_Level + 1] = FALSE; if (!imaged[it -> m_Level]) { m_ContentsBox -> SetItemImage(roots[it -> m_Level], IMG_Folder); m_ContentsBox -> SetItemSelectedImage(roots[it -> m_Level], IMG_Folder); imaged[it -> m_Level] = TRUE; } } m_ContentsBox -> Expand(roots[0]); } void wxHtmlHelpController::CreateIndex() { m_IndexBox -> Clear(); for (int i = 0; i < m_IndexCnt; i++) m_IndexBox -> Append(m_Index[i].m_Name, (char*)(m_Index + i)); } void wxHtmlHelpController::RefreshLists() { if (m_Frame) { CreateContents(); CreateIndex(); m_SearchList -> Clear(); } } void wxHtmlHelpController::ReadCustomization(wxConfigBase *cfg, wxString path) { wxString oldpath; wxString tmp; if (path != wxEmptyString) { oldpath = cfg -> GetPath(); cfg -> SetPath(path); } m_Cfg.navig_on = cfg -> Read("hcNavigPanel", m_Cfg.navig_on) != 0; m_Cfg.sashpos = cfg -> Read("hcSashPos", m_Cfg.sashpos); m_Cfg.x = cfg -> Read("hcX", m_Cfg.x); m_Cfg.y = cfg -> Read("hcY", m_Cfg.y); m_Cfg.w = cfg -> Read("hcW", m_Cfg.w); m_Cfg.h = cfg -> Read("hcH", m_Cfg.h); if (path != wxEmptyString) cfg -> SetPath(oldpath); } void wxHtmlHelpController::WriteCustomization(wxConfigBase *cfg, wxString path) { wxString oldpath; wxString tmp; if (path != wxEmptyString) { oldpath = cfg -> GetPath(); cfg -> SetPath(path); } cfg -> Write("hcNavigPanel", m_Cfg.navig_on); cfg -> Write("hcSashPos", (long)m_Cfg.sashpos); cfg -> Write("hcX", (long)m_Cfg.x); cfg -> Write("hcY", (long)m_Cfg.y); cfg -> Write("hcW", (long)m_Cfg.w); cfg -> Write("hcH", (long)m_Cfg.h); if (path != wxEmptyString) cfg -> SetPath(oldpath); } /* EVENT HANDLING : */ void wxHtmlHelpController::OnToolbar(wxCommandEvent& event) { switch (event.GetId()) { case wxID_HTML_BACK : m_HtmlWin -> HistoryBack(); break; case wxID_HTML_FORWARD : m_HtmlWin -> HistoryForward(); break; case wxID_HTML_PANEL : if (m_Splitter -> IsSplit()) { m_Cfg.sashpos = m_Splitter -> GetSashPosition(); m_Splitter -> Unsplit(m_NavigPan); } else { m_NavigPan -> Show(TRUE); m_HtmlWin -> Show(TRUE); m_Splitter -> SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos); } break; } } void wxHtmlHelpController::OnContentsSel(wxTreeEvent& event) { wxHtmlHelpTreeItemData *pg; pg = (wxHtmlHelpTreeItemData*) m_ContentsBox -> GetItemData(event.GetItem()); if (pg) m_HtmlWin -> LoadPage(pg -> GetPage()); } void wxHtmlHelpController::OnIndexSel(wxCommandEvent& event) { HtmlContentsItem *it = (HtmlContentsItem*) m_IndexBox -> GetClientData(m_IndexBox -> GetSelection()); if (it) m_HtmlWin -> LoadPage(it -> m_Book -> GetBasePath() + it -> m_Page); } void wxHtmlHelpController::OnSearchSel(wxCommandEvent& event) { HtmlContentsItem *it = (HtmlContentsItem*) m_SearchList -> GetClientData(m_SearchList -> GetSelection()); if (it) m_HtmlWin -> LoadPage(it -> m_Book -> GetBasePath() + it -> m_Page); } void wxHtmlHelpController::OnCloseWindow(wxCloseEvent& event) { int a, b; m_Cfg.navig_on = m_Splitter -> IsSplit(); if (m_Cfg.navig_on) m_Cfg.sashpos = m_Splitter -> GetSashPosition(); m_Frame -> GetPosition(&a, &b); m_Cfg.x = a, m_Cfg.y = b; m_Frame -> GetSize(&a, &b); m_Cfg.w = a, m_Cfg.h = b; if (m_Config) { WriteCustomization(m_Config, m_ConfigRoot); m_HtmlWin -> WriteCustomization(m_Config, m_ConfigRoot); } m_Frame = NULL; event.Skip(); } void wxHtmlHelpController::OnSearch(wxCommandEvent& event) { wxString sr = m_SearchText -> GetLineText(0); if (sr != wxEmptyString) KeywordSearch(sr); } BEGIN_EVENT_TABLE(wxHtmlHelpController, wxEvtHandler) EVT_TOOL_RANGE(wxID_HTML_PANEL, wxID_HTML_FORWARD, wxHtmlHelpController::OnToolbar) EVT_TREE_SEL_CHANGED(wxID_HTML_TREECTRL, wxHtmlHelpController::OnContentsSel) EVT_LISTBOX(wxID_HTML_INDEXLIST, wxHtmlHelpController::OnIndexSel) EVT_LISTBOX(wxID_HTML_SEARCHLIST, wxHtmlHelpController::OnSearchSel) EVT_CLOSE(wxHtmlHelpController::OnCloseWindow) EVT_BUTTON(wxID_HTML_SEARCHBUTTON, wxHtmlHelpController::OnSearch) EVT_TEXT_ENTER(wxID_HTML_SEARCHTEXT, wxHtmlHelpController::OnSearch) END_EVENT_TABLE() #endif