This is a snippet in which wxHtmlWindow and related classes are subclassed to allow an external browser to be launched for a URL included in a help document. Some of the code is copied from parent class handler may not be necessary but we didn't experiment with that. This has been tested only in a wxWidgets 2.4.2 application.
Chris
Header file:
/* $Id: ctrlMyHelp.hpp $
* ===========================================================================
*
* File Description:
*
* For getting external help links to open a browser window.
* Only tested in wxWidgets 2.4.2 code.
*
* ===========================================================================
*/
#ifndef CTRLHELP_HPP
#define CTRLHELP_HPP
#include "wx/splitter.h"
#include "wx/notebook.h"
#include "wx/dirctrl.h"
#include "wx/help.h"
#include "wx/cshelp.h"
#include "wx/html/helpctrl.h"
#include "wx/toolbar.h"
#include "wx/html/helpfrm.h"
#include "wx/html/helpctrl.h"
//-----------------------------------------------------------------------------
// make our own MyHtmlWindow class that handles OnLinkClicked events
// use this class instead of wxHtmlWindow in MyHtmlHelpFrame
//-----------------------------------------------------------------------------
class MyHtmlWindow : public wxHtmlWindow
{
public:
MyHtmlWindow(wxWindow *parent, wxWindowID id = -1,
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
long style = wxHW_SCROLLBAR_AUTO, const wxString& name = _T("htmlWindow"));
void OnLinkClicked(const wxHtmlLinkInfo& link);
};
//-----------------------------------------------------------------------------
// make our own MyHtmlHelpFrame class that allows replacement of its MyHtmlWindow
// use this class instead of wxHtmlHelpFrame in MyHtmlHelpController
//-----------------------------------------------------------------------------
class MyHtmlHelpFrame : public wxHtmlHelpFrame
{
public:
MyHtmlHelpFrame(wxHtmlHelpData* data = NULL);
bool Create2(wxWindow* parent, wxWindowID id, const wxString& title = wxEmptyString,
int style = wxHF_DEFAULT_STYLE);
};
//-----------------------------------------------------------------------------
// make our own MyHtmlHelpController class that allows replacement of its
// MyHtmlHelpFrame use this class instead of wxHtmlHelpController
//-----------------------------------------------------------------------------
class MyHtmlHelpController : public wxHtmlHelpController
{
public:
MyHtmlHelpController(int style = wxHF_DEFAULT_STYLE);
void CreateHelpWindow();
};
#endif
Implementation file:
[/quote]/* $Id: ctrlMyHelp.cpp $
* ===========================================================================
*
* File Description:
*
* For getting external help links to open a browser window.
* Only tested in wxWidgets 2.4.2 code.
*
* ===========================================================================
*/
#include <wx/wx.h>
#include <wx/app.h>
#include <wx/sizer.h>
#include "wx/help.h"
#include "wx/cshelp.h"
#include "wx/artprov.h"
#include "ctrlMyHelp.hpp"
#include <whatever_declares_LaunchWebPage_function.hpp>
MyHtmlWindow::MyHtmlWindow(wxWindow *parent, wxWindowID id, const wxPoint& pos,
const wxSize& size, long style, const wxString& name)
: wxHtmlWindow(parent, id, pos, size, style, name) {
//-------------------------------------------------------------------------
// use default wxHtmlWindow constructor
//-------------------------------------------------------------------------
}
void MyHtmlWindow::OnLinkClicked(const wxHtmlLinkInfo& link) {
//-------------------------------------------------------------------------
// If help doc link is external, launch a browser.
// Replace the condition and function to invoke external browser as required.
//-------------------------------------------------------------------------
if (link.GetHref().StartsWith(_T("http://")))
LaunchWebPage(link.GetHref());
else
wxHtmlWindow::OnLinkClicked(link);
}
MyHtmlHelpFrame::MyHtmlHelpFrame(wxHtmlHelpData* data)
: wxHtmlHelpFrame(data) {
//-------------------------------------------------------------------------
// use default wxHtmlHelpFrame constructor
//-------------------------------------------------------------------------
}
//-------------------------------------------------------------------------
// for reference: copied from wxWindows source.
// needed for MyHtmlHelpFrame::Create2()
// Command IDs :
//-------------------------------------------------------------------------
enum
{
//wxID_HTML_HELPFRAME = wxID_HIGHEST + 1,
wxID_HTML_PANEL = wxID_HIGHEST + 2,
wxID_HTML_BACK,
wxID_HTML_FORWARD,
wxID_HTML_UPNODE,
wxID_HTML_UP,
wxID_HTML_DOWN,
wxID_HTML_PRINT,
wxID_HTML_OPENFILE,
wxID_HTML_OPTIONS,
wxID_HTML_BOOKMARKSLIST,
wxID_HTML_BOOKMARKSADD,
wxID_HTML_BOOKMARKSREMOVE,
wxID_HTML_TREECTRL,
wxID_HTML_INDEXPAGE,
wxID_HTML_INDEXLIST,
wxID_HTML_INDEXTEXT,
wxID_HTML_INDEXBUTTON,
wxID_HTML_INDEXBUTTONALL,
wxID_HTML_NOTEBOOK,
wxID_HTML_SEARCHPAGE,
wxID_HTML_SEARCHTEXT,
wxID_HTML_SEARCHLIST,
wxID_HTML_SEARCHBUTTON,
wxID_HTML_SEARCHCHOICE,
wxID_HTML_COUNTINFO
};
bool MyHtmlHelpFrame::Create2(wxWindow* parent, wxWindowID id,
const wxString& WXUNUSED(title), int style) {
//-------------------------------------------------------------------------
// copied from wxWindows source.
// m_HtmlWin is a MyHtmlWindow instead of a wxHtmlWindow
//-------------------------------------------------------------------------
m_hfStyle = style;
wxImageList *ContentsImageList = new wxImageList(16, 16);
ContentsImageList->Add(wxArtProvider::GetIcon(wxART_HELP_BOOK, wxART_HELP_BROWSER));
ContentsImageList->Add(wxArtProvider::GetIcon(wxART_HELP_FOLDER, wxART_HELP_BROWSER));
ContentsImageList->Add(wxArtProvider::GetIcon(wxART_HELP_PAGE, wxART_HELP_BROWSER));
// Do the config in two steps. We read the MyHtmlWindow customization after we
// create the window.
if (m_Config)
ReadCustomization(m_Config, m_ConfigRoot);
wxFrame::Create(parent, id, _("Help"),
wxPoint(m_Cfg.x, m_Cfg.y), wxSize(m_Cfg.w, m_Cfg.h),
wxDEFAULT_FRAME_STYLE, wxT("wxHtmlHelp"));
GetPosition(&m_Cfg.x, &m_Cfg.y);
SetIcon(wxArtProvider::GetIcon(wxART_HELP, wxART_HELP_BROWSER));
int notebook_page = 0;
CreateStatusBar();
// toolbar?
if (style & (wxHF_TOOLBAR | wxHF_FLAT_TOOLBAR))
{
wxToolBar *toolBar = CreateToolBar(wxNO_BORDER | wxTB_HORIZONTAL |
wxTB_DOCKABLE |
(style & wxHF_FLAT_TOOLBAR ? wxTB_FLAT : 0));
toolBar->SetMargins( 2, 2 );
AddToolbarButtons(toolBar, style);
toolBar->Realize();
}
wxSizer *navigSizer = NULL;
if (style & (wxHF_CONTENTS | wxHF_INDEX | wxHF_SEARCH))
{
// traditional help controller; splitter window with html page on the
// right and a notebook containing various pages on the left
m_Splitter = new wxSplitterWindow(this);
m_HtmlWin = new MyHtmlWindow(m_Splitter);
//m_HtmlWin = new wxHtmlHelpHtmlWindow(this, m_Splitter);
m_NavigPan = new wxPanel(m_Splitter, -1);
m_NavigNotebook = new wxNotebook(m_NavigPan, wxID_HTML_NOTEBOOK,
wxDefaultPosition, wxDefaultSize);
#ifdef __WXMAC__
navigSizer = new wxBoxSizer(wxVERTICAL);
navigSizer->Add(m_NavigNotebook, wxEXPAND);
#else
wxNotebookSizer *nbs = new wxNotebookSizer(m_NavigNotebook);
navigSizer = new wxBoxSizer(wxVERTICAL);
navigSizer->Add(nbs, 1, wxEXPAND);
#endif
m_NavigPan->SetAutoLayout(TRUE);
m_NavigPan->SetSizer(navigSizer);
}
else
{ // only html window, no notebook with index,contents etc
m_HtmlWin = new MyHtmlWindow(this);
//m_HtmlWin = new wxHtmlWindow(this);
}
m_HtmlWin->SetRelatedFrame(this, m_TitleFormat);
m_HtmlWin->SetRelatedStatusBar(0);
if ( m_Config )
m_HtmlWin->ReadCustomization(m_Config, m_ConfigRoot);
// contents tree panel?
if ( style & wxHF_CONTENTS )
{
wxWindow *dummy = new wxPanel(m_NavigNotebook, wxID_HTML_INDEXPAGE);
wxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
topsizer->Add(0, 10);
dummy->SetAutoLayout(TRUE);
dummy->SetSizer(topsizer);
if ( style & wxHF_BOOKMARKS )
{
m_Bookmarks = new wxComboBox(dummy, wxID_HTML_BOOKMARKSLIST,
wxEmptyString,
wxDefaultPosition, wxDefaultSize,
0, NULL, wxCB_READONLY | wxCB_SORT);
m_Bookmarks->Append(_("(bookmarks)"));
for (unsigned i = 0; i < m_BookmarksNames.GetCount(); i++)
m_Bookmarks->Append(m_BookmarksNames);
m_Bookmarks->SetSelection(0);
wxBitmapButton *bmpbt1, *bmpbt2;
bmpbt1 = new wxBitmapButton(dummy, wxID_HTML_BOOKMARKSADD,
wxArtProvider::GetBitmap(wxART_ADD_BOOKMARK,
wxART_HELP_BROWSER));
bmpbt2 = new wxBitmapButton(dummy, wxID_HTML_BOOKMARKSREMOVE,
wxArtProvider::GetBitmap(wxART_DEL_BOOKMARK,
wxART_HELP_BROWSER));
#if wxUSE_TOOLTIPS
bmpbt1->SetToolTip(_("Add current page to bookmarks"));
bmpbt2->SetToolTip(_("Remove current page from bookmarks"));
#endif // wxUSE_TOOLTIPS
wxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(m_Bookmarks, 1, wxALIGN_CENTRE_VERTICAL | wxRIGHT, 5);
sizer->Add(bmpbt1, 0, wxALIGN_CENTRE_VERTICAL | wxRIGHT, 2);
sizer->Add(bmpbt2, 0, wxALIGN_CENTRE_VERTICAL, 0);
topsizer->Add(sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT, 10);
}
m_ContentsBox = new wxTreeCtrl(dummy, wxID_HTML_TREECTRL,
wxDefaultPosition, wxDefaultSize,
wxSUNKEN_BORDER |
wxTR_HAS_BUTTONS | wxTR_HIDE_ROOT |
wxTR_LINES_AT_ROOT);
m_ContentsBox->AssignImageList(ContentsImageList);
topsizer->Add(m_ContentsBox, 1, wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT, 2);
m_NavigNotebook->AddPage(dummy, _("Contents"));
m_ContentsPage = notebook_page++;
}
// index listbox panel?
if ( style & wxHF_INDEX )
{
wxWindow *dummy = new wxPanel(m_NavigNotebook, wxID_HTML_INDEXPAGE);
wxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
dummy->SetAutoLayout(TRUE);
dummy->SetSizer(topsizer);
m_IndexText = new wxTextCtrl(dummy, wxID_HTML_INDEXTEXT, wxEmptyString,
wxDefaultPosition, wxDefaultSize,
wxTE_PROCESS_ENTER);
m_IndexButton = new wxButton(dummy, wxID_HTML_INDEXBUTTON, _("Find"));
m_IndexButtonAll = new wxButton(dummy, wxID_HTML_INDEXBUTTONALL,
_("Show all"));
m_IndexCountInfo = new wxStaticText(dummy, wxID_HTML_COUNTINFO,
wxEmptyString, wxDefaultPosition,
wxDefaultSize,
wxALIGN_RIGHT | wxST_NO_AUTORESIZE);
m_IndexList = new wxListBox(dummy, wxID_HTML_INDEXLIST,
wxDefaultPosition, wxDefaultSize,
0, NULL, wxLB_SINGLE);
#if wxUSE_TOOLTIPS
m_IndexButton->SetToolTip(_("Display all index items that contain given substring. Search is case insensitive."));
m_IndexButtonAll->SetToolTip(_("Show all items in index"));
#endif //wxUSE_TOOLTIPS
topsizer->Add(m_IndexText, 0, wxEXPAND | wxALL, 10);
wxSizer *btsizer = new wxBoxSizer(wxHORIZONTAL);
btsizer->Add(m_IndexButton, 0, wxRIGHT, 2);
btsizer->Add(m_IndexButtonAll);
topsizer->Add(btsizer, 0,
wxALIGN_RIGHT | wxLEFT | wxRIGHT | wxBOTTOM, 10);
topsizer->Add(m_IndexCountInfo, 0, wxEXPAND | wxLEFT | wxRIGHT, 2);
topsizer->Add(m_IndexList, 1, wxEXPAND | wxALL, 2);
m_NavigNotebook->AddPage(dummy, _("Index"));
m_IndexPage = notebook_page++;
}
// search list panel?
if ( style & wxHF_SEARCH )
{
wxWindow *dummy = new wxPanel(m_NavigNotebook, wxID_HTML_INDEXPAGE);
wxSizer *sizer = new wxBoxSizer(wxVERTICAL);
dummy->SetAutoLayout(TRUE);
dummy->SetSizer(sizer);
m_SearchText = new wxTextCtrl(dummy, wxID_HTML_SEARCHTEXT,
wxEmptyString,
wxDefaultPosition, wxDefaultSize,
wxTE_PROCESS_ENTER);
m_SearchChoice = new wxChoice(dummy, wxID_HTML_SEARCHCHOICE,
wxDefaultPosition, wxDefaultSize);
m_SearchCaseSensitive = new wxCheckBox(dummy, -1, _("Case sensitive"));
m_SearchWholeWords = new wxCheckBox(dummy, -1, _("Whole words only"));
m_SearchButton = new wxButton(dummy, wxID_HTML_SEARCHBUTTON, _("Search"));
#if wxUSE_TOOLTIPS
m_SearchButton->SetToolTip(_("Search contents of help book(s) for all occurences of the text you typed above"));
#endif //wxUSE_TOOLTIPS
m_SearchList = new wxListBox(dummy, wxID_HTML_SEARCHLIST,
wxDefaultPosition, wxDefaultSize,
0, NULL, wxLB_SINGLE);
sizer->Add(m_SearchText, 0, wxEXPAND | wxALL, 10);
sizer->Add(m_SearchChoice, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 10);
sizer->Add(m_SearchCaseSensitive, 0, wxLEFT | wxRIGHT, 10);
sizer->Add(m_SearchWholeWords, 0, wxLEFT | wxRIGHT, 10);
sizer->Add(m_SearchButton, 0, wxALL | wxALIGN_RIGHT, 8);
sizer->Add(m_SearchList, 1, wxALL | wxEXPAND, 2);
m_NavigNotebook->AddPage(dummy, _("Search"));
m_SearchPage = notebook_page++;
}
m_HtmlWin->Show(TRUE);
RefreshLists();
if ( navigSizer )
{
navigSizer->SetSizeHints(m_NavigPan);
m_NavigPan->Layout();
}
// showtime
if ( m_NavigPan && m_Splitter )
{
m_Splitter->SetMinimumPaneSize(20);
if ( m_Cfg.navig_on )
m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
if ( m_Cfg.navig_on )
{
m_NavigPan->Show(TRUE);
m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
}
else
{
m_NavigPan->Show(FALSE);
m_Splitter->Initialize(m_HtmlWin);
}
}
return TRUE;
}
MyHtmlHelpController::MyHtmlHelpController(int style)
: wxHtmlHelpController(style) {
//-------------------------------------------------------------------------
// use default wxHtmlHelpController constructor
//-------------------------------------------------------------------------
}
void MyHtmlHelpController::CreateHelpWindow() {
//-------------------------------------------------------------------------
// copied from wxWindows source.
// use MyHtmlHelpFrame instead of wxHtmlHelpFrame
// use MyHtmlHelpFrame's Create2() instead of wxHtmlHelpFrame's Create()
//-------------------------------------------------------------------------
if (m_helpFrame)
{
m_helpFrame->Raise();
return ;
}
if (m_Config == NULL)
{
m_Config = wxConfigBase::Get(FALSE);
if (m_Config != NULL)
m_ConfigRoot = _T("wxWindows/wxHtmlHelpController");
}
m_helpFrame = new MyHtmlHelpFrame(&m_helpData);
//m_helpFrame = CreateHelpFrame(&m_helpData);
m_helpFrame->SetController(this);
if (m_Config)
m_helpFrame->UseConfig(m_Config, m_ConfigRoot);
((MyHtmlHelpFrame*)m_helpFrame)->Create2(NULL, wxID_HTML_HELPFRAME, wxEmptyString, m_FrameStyle);
//m_helpFrame->Create(NULL, wxID_HTML_HELPFRAME, wxEmptyString, m_FrameStyle);
m_helpFrame->SetTitleFormat(m_titleFormat);
m_helpFrame->Show(TRUE);
}