1///////////////////////////////////////////////////////////////////////////// 2// Name: virtua;.cpp 3// Purpose: wxHtml testing example 4// demonstrates virtual file systems feature 5///////////////////////////////////////////////////////////////////////////// 6 7// For compilers that support precompilation, includes "wx/wx.h". 8#include "wx/wxprec.h" 9 10#ifdef __BORLANDC__ 11 #pragma hdrstop 12#endif 13 14// for all others, include the necessary headers (this file is usually all you 15// need because it includes almost all "standard" wxWidgets headers 16#ifndef WX_PRECOMP 17 #include "wx/wx.h" 18#endif 19 20 21#include "wx/html/htmlwin.h" 22 23 24// new handler class: 25 26#include "wx/wfstream.h" 27#include "wx/mstream.h" 28 29 30 31class MyVFS : public wxFileSystemHandler 32{ 33public: 34 MyVFS() : wxFileSystemHandler() {} 35 36 wxFSFile* OpenFile(wxFileSystem& fs, const wxString& location); 37 bool CanOpen(const wxString& location); 38}; 39 40 41bool MyVFS::CanOpen(const wxString& location) 42{ 43 return (GetProtocol(location) == wxT("myVFS")); 44} 45 46 47 48wxFSFile* MyVFS::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString& location) 49{ 50 wxFSFile *f; 51 wxInputStream *str; 52 static char buf[1024]; 53 const wxWX2MBbuf loc = location.ToAscii(); 54 55 sprintf(buf, "<html><body><h2><i>You're in Node <u>%s</u></i></h2><p>" 56 "Where do you want to go?<br><blockquote>" 57 "<a href=\"%s-1\">sub-1</a><br>" 58 "<a href=\"%s-2\">sub-2</a><br>" 59 "<a href=\"%s-3\">sub-3</a><br>" 60 "</blockquote></body></html>", 61 (const char*)loc, (const char*)loc, (const char*)loc, 62 (const char*)loc); 63 64 // NB: There's a terrible hack involved: we fill 'buf' with new data every 65 // time this method is called and return new wxMemoryInputStream pointing to it. 66 // This won't work as soon as there are 2+ myVFS files opened. Fortunately, 67 // this won't happen because wxHTML keeps only one "page" file opened at the 68 // time. 69 str = new wxMemoryInputStream(buf, strlen(buf)); 70 f = new wxFSFile(str, location, wxT("text/html"), wxEmptyString, wxDateTime::Today()); 71 72 return f; 73} 74 75 76 77// ---------------------------------------------------------------------------- 78// private classes 79// ---------------------------------------------------------------------------- 80 81// Define a new application type, each program should derive a class from wxApp 82 class MyApp : public wxApp 83 { 84 public: 85 // override base class virtuals 86 // ---------------------------- 87 88 // this one is called on application startup and is a good place for the app 89 // initialization (doing it here and not in the ctor allows to have an error 90 // return: if OnInit() returns false, the application terminates) 91 virtual bool OnInit(); 92 }; 93 94// Define a new frame type: this is going to be our main frame 95 class MyFrame : public wxFrame 96 { 97 public: 98 // ctor(s) 99 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size); 100 101 // event handlers (these functions should _not_ be virtual) 102 void OnQuit(wxCommandEvent& event); 103 void OnBack(wxCommandEvent& event); 104 void OnForward(wxCommandEvent& event); 105 106 private: 107 // any class wishing to process wxWidgets events must use this macro 108 DECLARE_EVENT_TABLE() 109 }; 110 111// ---------------------------------------------------------------------------- 112// constants 113// ---------------------------------------------------------------------------- 114 115// IDs for the controls and the menu commands 116 enum 117 { 118 // menu items 119 Minimal_Quit = 1, 120 Minimal_Back, 121 Minimal_Forward, 122 123 // controls start here (the numbers are, of course, arbitrary) 124 Minimal_Text = 1000 125 }; 126 127// ---------------------------------------------------------------------------- 128// event tables and other macros for wxWidgets 129// ---------------------------------------------------------------------------- 130 131// the event tables connect the wxWidgets events with the functions (event 132// handlers) which process them. It can be also done at run-time, but for the 133// simple menu events like this the static method is much simpler. 134 BEGIN_EVENT_TABLE(MyFrame, wxFrame) 135 EVT_MENU(Minimal_Quit, MyFrame::OnQuit) 136 EVT_MENU(Minimal_Back, MyFrame::OnBack) 137 EVT_MENU(Minimal_Forward, MyFrame::OnForward) 138 END_EVENT_TABLE() 139 140 // Create a new application object: this macro will allow wxWidgets to create 141 // the application object during program execution (it's better than using a 142 // static object for many reasons) and also declares the accessor function 143 // wxGetApp() which will return the reference of the right type (i.e. MyApp and 144 // not wxApp) 145 IMPLEMENT_APP(MyApp) 146 147 // ============================================================================ 148 // implementation 149 // ============================================================================ 150 151 // ---------------------------------------------------------------------------- 152 // the application class 153 // ---------------------------------------------------------------------------- 154 155 // `Main program' equivalent: the program execution "starts" here 156 bool MyApp::OnInit() 157 { 158 // Create the main application window 159 MyFrame *frame = new MyFrame(_("wxHtmlWindow testing application"), 160 wxDefaultPosition, wxSize(640, 480)); 161 162 // Show it and tell the application that it's our main window 163 // @@@ what does it do exactly, in fact? is it necessary here? 164 frame->Show(true); 165 SetTopWindow(frame); 166 wxFileSystem::AddHandler(new MyVFS); 167 168 // success: wxApp::OnRun() will be called which will enter the main message 169 // loop and the application will run. If we returned false here, the 170 // application would exit immediately. 171 return true; 172 } 173 174// ---------------------------------------------------------------------------- 175// main frame 176// ---------------------------------------------------------------------------- 177 178wxHtmlWindow *html; 179 180// frame constructor 181 MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) 182 : wxFrame((wxFrame *)NULL, wxID_ANY, title, pos, size) 183 { 184 // create a menu bar 185 wxMenu *menuFile = new wxMenu; 186 wxMenu *menuNav = new wxMenu; 187 188 menuFile->Append(Minimal_Quit, _("E&xit")); 189 menuNav->Append(Minimal_Back, _("Go &BACK")); 190 menuNav->Append(Minimal_Forward, _("Go &FORWARD")); 191 192 // now append the freshly created menu to the menu bar... 193 wxMenuBar *menuBar = new wxMenuBar; 194 menuBar->Append(menuFile, _("&File")); 195 menuBar->Append(menuNav, _("&Navigate")); 196 197 // ... and attach this menu bar to the frame 198 SetMenuBar(menuBar); 199 200#if wxUSE_STATUSBAR 201 CreateStatusBar(2); 202#endif // wxUSE_STATUSBAR 203 204 html = new wxHtmlWindow(this); 205 html -> SetRelatedFrame(this, _("VFS Demo: '%s'")); 206#if wxUSE_STATUSBAR 207 html -> SetRelatedStatusBar(1); 208#endif // wxUSE_STATUSBAR 209 html -> LoadPage(wxT("start.htm")); 210 } 211 212 213// event handlers 214 215 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) 216 { 217 // true is to force the frame to close 218 Close(true); 219 } 220 221 void MyFrame::OnBack(wxCommandEvent& WXUNUSED(event)) 222 { 223 if (!html -> HistoryBack()) wxMessageBox(_("You reached prehistory era!")); 224 } 225 226 227 void MyFrame::OnForward(wxCommandEvent& WXUNUSED(event)) 228 { 229 if (!html -> HistoryForward()) wxMessageBox(_("No more items in history!")); 230 } 231