]> git.saurik.com Git - wxWidgets.git/blobdiff - contrib/src/applet/appletwindow.cpp
Rework modal dialog code to not depend on now obsolete wxDIALOG_MODAL flag.
[wxWidgets.git] / contrib / src / applet / appletwindow.cpp
index b7effb3bd048d552e07085c29f501167bfabd025..9329a0bb20470721d75e28d4a92fd157740ace57 100644 (file)
@@ -5,23 +5,19 @@
 *               Copyright (C) 1991-2001 SciTech Software, Inc.
 *                            All rights reserved.
 *
 *               Copyright (C) 1991-2001 SciTech Software, Inc.
 *                            All rights reserved.
 *
-*  ======================================================================
-*  |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW|
-*  |                                                                    |
-*  |This copyrighted computer code is a proprietary trade secret of     |
-*  |SciTech Software, Inc., located at 505 Wall Street, Chico, CA 95928 |
-*  |USA (www.scitechsoft.com).  ANY UNAUTHORIZED POSSESSION, USE,       |
-*  |VIEWING, COPYING, MODIFICATION OR DISSEMINATION OF THIS CODE IS     |
-*  |STRICTLY PROHIBITED BY LAW.  Unless you have current, express       |
-*  |written authorization from SciTech to possess or use this code, you |
-*  |may be subject to civil and/or criminal penalties.                  |
-*  |                                                                    |
-*  |If you received this code in error or you would like to report      |
-*  |improper use, please immediately contact SciTech Software, Inc. at  |
-*  |530-894-8400.                                                       |
-*  |                                                                    |
-*  |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW|
-*  ======================================================================
+*  ========================================================================
+*
+*    The contents of this file are subject to the wxWindows License
+*    Version 3.0 (the "License"); you may not use this file except in
+*    compliance with the License. You may obtain a copy of the License at
+*    http://www.wxwindows.org/licence3.txt
+*
+*    Software distributed under the License is distributed on an
+*    "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+*    implied. See the License for the specific language governing
+*    rights and limitations under the License.
+*
+*  ========================================================================
 *
 * Language:     ANSI C++
 * Environment:  Any
 *
 * Language:     ANSI C++
 * Environment:  Any
 *
 ****************************************************************************/
 
 *
 ****************************************************************************/
 
-// For compilers that support precompilation
-#include "wx/wxprec.h"
-#include "wx/html/forcelnk.h"
-
 // Include private headers
 #include "wx/applet/applet.h"
 #include "wx/applet/window.h"
 #include "wx/applet/loadpage.h"
 // Include private headers
 #include "wx/applet/applet.h"
 #include "wx/applet/window.h"
 #include "wx/applet/loadpage.h"
+#include "wx/applet/plugin.h"
 
 // Preprocessor Stuff
 #include "wx/applet/prepinclude.h"
 #include "wx/applet/prepecho.h"
 #include "wx/applet/prepifelse.h"
 
 
 // Preprocessor Stuff
 #include "wx/applet/prepinclude.h"
 #include "wx/applet/prepecho.h"
 #include "wx/applet/prepifelse.h"
 
+// wxWindows headers
+
+// Kind of pointless to use precompiled headers when this is the only
+// file in this lib that would need them.
+#include "wx/defs.h"
+#include "wx/spawnbrowser.h"
+#include "wx/html/forcelnk.h"
+#include "wx/log.h"
+#include "wx/msgdlg.h"
+#include "wx/tbarbase.h"
+
+// crt
+#ifdef __WXMSW__
+#include <process.h>        // spawnl()
+#endif
 
 /*---------------------------- Global variables ---------------------------*/
 
 
 /*---------------------------- Global variables ---------------------------*/
 
@@ -62,6 +70,9 @@ END_EVENT_TABLE()
 // Implement the class functions for wxHtmlAppletWindow
 IMPLEMENT_CLASS(wxHtmlAppletWindow, wxHtmlWindow);
 
 // Implement the class functions for wxHtmlAppletWindow
 IMPLEMENT_CLASS(wxHtmlAppletWindow, wxHtmlWindow);
 
+// Implement the dynamic class so it can be constructed dynamically
+IMPLEMENT_DYNAMIC_CLASS(VirtualData, wxObject);
+       
 // Define the wxAppletList implementation
 #include "wx/listimpl.cpp"
 WX_DEFINE_LIST(wxAppletList);
 // Define the wxAppletList implementation
 #include "wx/listimpl.cpp"
 WX_DEFINE_LIST(wxAppletList);
@@ -80,30 +91,33 @@ wxHtmlAppletWindow::wxHtmlAppletWindow(
     const wxSize& size,
     long style,
     const wxString& name)
     const wxSize& size,
     long style,
     const wxString& name)
-    : wxHtmlWindow(parent,id,pos,size,style,name)
+    : wxHtmlWindow(parent,id,pos,size,style,name), m_AppletList(wxKEY_STRING)
 {
 {
-    //setup client navbars
+    // Init our locks
+    UnLock();
+
+    // setup client navbars
     if (navBar) {
     if (navBar) {
+        m_NavBarEnabled = true;
         m_NavBar = navBar;
         m_NavBackId = navBackId;
         m_NavForwardId = navForwardId;
         }
     else {
         m_NavBar = navBar;
         m_NavBackId = navBackId;
         m_NavForwardId = navForwardId;
         }
     else {
+        m_NavBarEnabled = false;
         m_NavBar = NULL;
         }
 
         m_NavBar = NULL;
         }
 
-    //Add HTML preprocessors
-    // deleting preprocessors is done by the code within the window
+    m_NavBackId = navBackId;
+    m_NavForwardId = navForwardId;
 
 
+    // Add HTML preprocessors
+    // deleting preprocessors is done by the code within the window
     incPreprocessor = new wxIncludePrep(); // #include preprocessor
     incPreprocessor = new wxIncludePrep(); // #include preprocessor
-    wxEchoPrep * echoPreprocessor = new wxEchoPrep(); // #echo preprocessor
-    wxIfElsePrep * ifPreprocessor = new wxIfElsePrep();
-
+    incPreprocessor->ChangeDirectory(m_FS); // give it access to our filesys object
     this->AddProcessor(incPreprocessor);
     this->AddProcessor(incPreprocessor);
-    this->AddProcessor(echoPreprocessor);
-    this->AddProcessor(ifPreprocessor);
-
-
+    this->AddProcessor(new wxEchoPrep());
+    this->AddProcessor(new wxIfElsePrep());
 }
 
 /****************************************************************************
 }
 
 /****************************************************************************
@@ -114,6 +128,18 @@ wxHtmlAppletWindow::~wxHtmlAppletWindow()
 {
 }
 
 {
 }
 
+/****************************************************************************
+PARAMETERS:
+dc  - wxDC object to draw on
+
+REMARKS:
+****************************************************************************/
+void wxHtmlAppletWindow::OnDraw(
+    wxDC& dc)
+{
+    wxHtmlWindow::OnDraw(dc);
+}
+
 /****************************************************************************
 PARAMETERS:
 className       - Name of the applet class to create an object for
 /****************************************************************************
 PARAMETERS:
 className       - Name of the applet class to create an object for
@@ -135,12 +161,7 @@ wxApplet *wxHtmlAppletWindow::CreateApplet(
     const wxSize& size)
 {
     // Dynamically create the class instance at runtime
     const wxSize& size)
 {
     // Dynamically create the class instance at runtime
-    wxClassInfo *info = wxClassInfo::FindClass(classId.c_str());
-    if (!info)
-        return NULL;
-    wxObject *obj = info->CreateObject();
-    if (!obj)
-        return NULL;
+    wxObject *obj = wxCreateDynamicObject(classId.c_str());
     wxApplet *applet = wxDynamicCast(obj,wxApplet);
     if (!applet)
         return NULL;
     wxApplet *applet = wxDynamicCast(obj,wxApplet);
     if (!applet)
         return NULL;
@@ -148,10 +169,50 @@ wxApplet *wxHtmlAppletWindow::CreateApplet(
         delete applet;
         return NULL;
         }
         delete applet;
         return NULL;
         }
-    m_AppletList.Append(iName,applet);
+    else {
+        // do some fixups on the size if its screwed up
+        wxSize nsize = applet->GetBestSize();
+        if (nsize.x < size.x) nsize.x = size.x;
+        if (nsize.y < size.y) nsize.y = size.y;
+        applet->SetSize(nsize);
+        }
+
+    m_AppletList.Append(iName,(wxObject*)applet);
     return applet;
 }
 
     return applet;
 }
 
+/****************************************************************************
+PARAMETERS:
+classId       - Name of the Plugin class to create an object for
+
+RETURNS:
+Pointer to the wxplugIn created, or NULL if unable to create the PlugIn.
+
+REMARKS:
+This function is used to create new wxPlugIn objects dynamically based on the
+class name as a string. This allows instances of wxPlugIn classes to be
+created dynamically based on string values embedded in the custom tags of an
+HTML page.
+****************************************************************************/
+bool wxHtmlAppletWindow::CreatePlugIn(
+    const wxString& classId,
+    const wxString& cmdLine)
+{
+    // Dynamically create the class instance at runtime, execute it
+    // and then destroy it.
+    wxObject *obj = wxCreateDynamicObject(classId.c_str());
+    wxPlugIn *plugIn = wxDynamicCast(obj,wxPlugIn);
+    if (!plugIn)
+        return false;
+    if (!plugIn->Create(this)) {
+        delete plugIn;
+        return false;
+        }
+    plugIn->Run(cmdLine);
+    delete plugIn;
+    return true;
+}
+
 /****************************************************************************
 PARAMETERS:
 appletName      - Name of the applet class to find
 /****************************************************************************
 PARAMETERS:
 appletName      - Name of the applet class to find
@@ -207,58 +268,110 @@ Remove an applet from the manager. Called during applet destruction
 bool wxHtmlAppletWindow::LoadPage(
     const wxString& link)
 {
 bool wxHtmlAppletWindow::LoadPage(
     const wxString& link)
 {
-    wxString    href(link);
+    wxString href(link);
 
 
-    // TODO: This needs to be made platform inde if possible.
     if (link.GetChar(0) == '?'){
         wxString cmd = link.BeforeFirst('=');
         wxString cmdValue = link.AfterFirst('=');
 
     if (link.GetChar(0) == '?'){
         wxString cmd = link.BeforeFirst('=');
         wxString cmdValue = link.AfterFirst('=');
 
-        if(!(cmd.CmpNoCase("?EXTERNAL"))){
-#ifdef  __WINDOWS__
-                ShellExecute(this ? (HWND)this->GetHWND() : NULL,NULL,cmdValue.c_str(),NULL,"",SW_SHOWNORMAL);
-#else
-                #error Platform not implemented yet!
-#endif
-            return true;
+        // Launches the default Internet browser for the system.
+        if(!(cmd.CmpNoCase("?EXTERNAL"))) {
+            return wxSpawnBrowser(this, cmdValue.c_str());
             }
             }
-        if (!(cmd.CmpNoCase("?EXECUTE"))){
-            wxMessageBox(cmdValue);
-            return true;
+
+        // Launches an external program on the system.
+        if (!(cmd.CmpNoCase("?EXECUTE"))) {
+            int waitflag = P_NOWAIT;
+            bool ret;
+            wxString currentdir;
+            wxString filename, path, ext;
+
+            // Parse the params sent to the execute command. For now the only
+            // parm is "wait". wait will cause spawn wait, default is nowait.
+            // Since we only need one param for now I am not going to make this
+            // any smater then it needs to be. If we need more params later i'll
+            // fix it.
+            int i = cmdValue.Find('(');
+            if (i != -1) {
+                wxString param = cmdValue.AfterFirst('(');
+                cmdValue.Truncate(i);
+                if (!param.CmpNoCase("wait)"))
+                    waitflag = P_WAIT;
+                }
+
+            currentdir = wxGetCwd();
+            //we don't want to change the path of the virtual file system so we have to use these
+            //functions rather than the filesystem
+            wxSplitPath(cmdValue, &path, &filename, &ext);
+            if (path.CmpNoCase("") != 0) wxSetWorkingDirectory(path);
+
+            ret = !spawnl( waitflag, cmdValue , NULL );
+            //HACK should use wxExecute
+            //ret = wxExecute(filename, bool sync = FALSE, wxProcess *callback = NULL)
+            wxSetWorkingDirectory(currentdir);
+
+            return ret;
             }
             }
+
+        // Looks for a href in a variable stored as a cookie. The href can be
+        // changed on the fly.
         if (!(cmd.CmpNoCase("?VIRTUAL"))){
         if (!(cmd.CmpNoCase("?VIRTUAL"))){
-            VirtualData& temp = *((VirtualData*)FindCookie(cmdValue));
-            if (&temp) {
-                href = temp.GetHref();
+            wxObject *obj = FindCookie(cmdValue);
+            VirtualData *virtData = wxDynamicCast(obj,VirtualData);
+            if (virtData) {
+                // recurse and loadpage, just in case the link is like another
+                // ? link
+                return LoadPage(virtData->GetHref());
                 }
             else {
 #ifdef CHECKED
                 }
             else {
 #ifdef CHECKED
-                wxMessageBox("VIRTUAL LINK ERROR: " + cmdValue + " does not exist.");
+                wxLogError(_T("VIRTUAL LINK ERROR: '%s' does not exist."), cmdValue.c_str());
 #endif
                 return true;
                 }
             }
 #endif
                 return true;
                 }
             }
-        }
 
 
-    // Grab the directory from the string for use in the include preprocessor
-    // make sure we get either type of / or \.
-    int ch = link.Find('\\', true);
-    if (ch == -1) ch = link.Find('/', true);
-    if (ch != -1) {
-        wxFileSystem fs;
-        wxString tmp = link.Mid(0, ch+1);
-        fs.ChangePathTo(incPreprocessor->GetDirectory(), true);
-        fs.ChangePathTo(tmp, true);
-        incPreprocessor->ChangeDirectory(fs.GetPath());
+        // This launches a qlet - It is like an applet but is more generic in that it
+        // can be of any wxWin type so it then has the freedom to do more stuff.
+        if (!(cmd.CmpNoCase("?WXPLUGIN"))){
+            if (!cmdValue.IsNull()) {
+                // TODO: We are going to need to add code to parse the command line
+                //       parameters string in here in the future...
+                wxString cmdLine = link.AfterFirst('(');
+                cmdLine = cmdLine.BeforeLast(')');
+                if (!CreatePlugIn(cmdValue,cmdLine)) {
+#ifdef CHECKED
+                    wxLogError(_T("Launch PlugIn ERROR: '%s' does not exist."), cmdValue.c_str());
+#endif
+                    }
+                }
+             return true;
+            }
+
+        // This used in a link or href will take you back in the history.
+        if (!(cmd.CmpNoCase("?BACK"))){
+            HistoryBack();
+            return true;
+            }
+
+        // This used in a link or href will take you forward in the history
+        if (!(cmd.CmpNoCase("?FORWARD"))){
+            HistoryForward();
+            return true;
+            }
         }
 
     // Inform all the applets that the new page is being loaded
     for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext())
         (node->GetData())->OnLinkClicked(wxHtmlLinkInfo(href));
         }
 
     // Inform all the applets that the new page is being loaded
     for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext())
         (node->GetData())->OnLinkClicked(wxHtmlLinkInfo(href));
+    Show(false);
+
+    m_openedlast = href;
     bool stat = wxHtmlWindow::LoadPage(href);
     bool stat = wxHtmlWindow::LoadPage(href);
+    Show(true);
 
     // Enable/Dis the navbar tools
 
     // Enable/Dis the navbar tools
-    if (m_NavBar) {
+    if (m_NavBarEnabled) {
         m_NavBar->EnableTool(m_NavForwardId,HistoryCanForward());
         m_NavBar->EnableTool(m_NavBackId,HistoryCanBack());
         }
         m_NavBar->EnableTool(m_NavForwardId,HistoryCanForward());
         m_NavBar->EnableTool(m_NavBackId,HistoryCanBack());
         }
@@ -313,6 +426,37 @@ bool wxHtmlAppletWindow::HistoryBack()
     return wxHtmlWindow::HistoryBack();
 }
 
     return wxHtmlWindow::HistoryBack();
 }
 
+/****************************************************************************
+REMARKS:
+This function is used to disable the navigation bars. If you want to
+toggle to the navbars off you must call this function.
+****************************************************************************/
+void wxHtmlAppletWindow::DisableNavBar()
+{
+    m_NavBarEnabled = false;
+}
+
+/****************************************************************************
+REMARKS:
+This function is used to enable the nav bars. If you toggle the nav bars on
+you must call this function.
+****************************************************************************/
+void wxHtmlAppletWindow::EnableNavBar()
+{
+    m_NavBarEnabled = true;
+}
+
+/****************************************************************************
+REMARKS:
+This function is used to set the nav bar to a new nav bar if you deleted the
+one that you were useing. Usally this happens when you toggle a nav bar
+on or off.
+****************************************************************************/
+void wxHtmlAppletWindow::SetNavBar(wxToolBarBase *navBar)
+{
+    m_NavBar = navBar;
+}
+
 /****************************************************************************
 PARAMETERS:
 msg - wxEvent message to be sent to all wxApplets
 /****************************************************************************
 PARAMETERS:
 msg - wxEvent message to be sent to all wxApplets
@@ -323,24 +467,16 @@ to all other applets on the current page. This is the primary form of
 communication between applets on the page if they need to inform each
 other of internal information.
 
 communication between applets on the page if they need to inform each
 other of internal information.
 
-Note that the event handling terminates as soon as the first wxApplet
-handles the event. If the event should be handled by all wxApplet's,
-the event handlers for the applets should not reset the wxEvent::Skip()
-value (ie: by default it is true).
 ****************************************************************************/
 ****************************************************************************/
-void wxHtmlAppletWindow::SendMessage(
-    wxEvent& msg)
+void wxHtmlAppletWindow::SendAppletMessage(
+    wxAppletEvent& msg)
 {
 {
-    // Preset the skip flag
-    msg.Skip();
+    // TODO: make a named target for messages, only send a message to the correct
+    // named applet
 
     // Process all applets in turn and send them the message
     for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext()) {
         (node->GetData())->OnMessage(msg);
 
     // Process all applets in turn and send them the message
     for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext()) {
         (node->GetData())->OnMessage(msg);
-        if (!msg.GetSkipped()){
-            wxMessageBox("BREAK");
-            break;
-            }
         }
 }
 
         }
 }
 
@@ -431,10 +567,17 @@ need to change the page for the current window to a new window.
 void wxHtmlAppletWindow::OnLoadPage(
     wxLoadPageEvent &event)
 {
 void wxHtmlAppletWindow::OnLoadPage(
     wxLoadPageEvent &event)
 {
-    if (event.GetHtmlWindow() == this){
-        if (LoadPage(event.GetHRef())){
-            wxPageLoadedEvent evt;
+    // Test the mutex lock.
+    if (!(IsLocked())) {
+        Lock();
+        if (event.GetHtmlWindow() == this) {
+            if (LoadPage(event.GetHRef())) {
+                // wxPageLoadedEvent evt;
+                // NOTE: This is reserved for later use as we might need to send
+                // page loaded events to applets.
+                }
             }
             }
+        UnLock();
         }
 }
 
         }
 }
 
@@ -452,6 +595,23 @@ void wxHtmlAppletWindow::OnPageLoaded(
     Enable(true);
 }
 
     Enable(true);
 }
 
+/****************************************************************************
+PARAMETERS:
+none
+
+REMARKS:
+This function tries to lock the mutex. If it can't, returns
+immediately with false.
+***************************************************************************/
+bool wxHtmlAppletWindow::TryLock()
+{
+    if (!m_mutexLock) {
+        m_mutexLock = true;
+        return true;
+        }
+    return false;
+}
+
 /****************************************************************************
 PARAMETERS:
 name    - name of the last applet that changed the data in this object
 /****************************************************************************
 PARAMETERS:
 name    - name of the last applet that changed the data in this object
@@ -464,11 +624,25 @@ VirtualData is used to store information on the virtual links.
 VirtualData::VirtualData(
     wxString& name,
     wxString& group,
 VirtualData::VirtualData(
     wxString& name,
     wxString& group,
-    wxString& href )
+    wxString& href,
+    wxString& plugin )
 {
     m_name = name;
     m_group = group;
     m_href = href;
 {
     m_name = name;
     m_group = group;
     m_href = href;
+    m_plugIn = plugin;
+}
+
+/****************************************************************************
+PARAMETERS:
+REMARKS:
+VirtualData is used to store information on the virtual links.
+****************************************************************************/
+VirtualData::VirtualData()
+{
+    m_name.Empty();
+    m_group.Empty();
+    m_href.Empty();
 }
 
 #include "wx/html/m_templ.h"
 }
 
 #include "wx/html/m_templ.h"
@@ -490,43 +664,66 @@ TAG_HANDLER_PROC(tag)
     wxString            name;
     int                                width, height;
 
     wxString            name;
     int                                width, height;
 
+    // Get access to our wxHtmlAppletWindow class
        wnd = m_WParser->GetWindow();
        wnd = m_WParser->GetWindow();
+       if ((appletWindow = wxDynamicCast(wnd,wxHtmlAppletWindow)) == NULL)
+        return false;
 
 
-       if ((appletWindow = wxDynamicCast(wnd,wxHtmlAppletWindow)) != NULL){
-               tag.ScanParam("WIDTH", "%i", &width);
-               tag.ScanParam("HEIGHT", "%i", &height); 
-        if (tag.HasParam("CLASSID")){
-            classId = tag.GetParam("CLASSID");
-            if ( classId.IsNull() || classId.Len() == 0 ){
-                wxMessageBox("wxApplet tag error: CLASSID is NULL or empty.","Error",wxICON_ERROR);
-                return false;
-                }
-            if (tag.HasParam("NAME"))
-                name = tag.GetParam("NAME");
-
-            // If the name is NULL or len is zero then we assume that the html guy
-            // didn't include the name param which is optional.
-            if ( name.IsNull() || name.Len() == 0 )
-                name = classId;
-
-            // We got all the params and can now create the applet
-                       if ((applet = appletWindow->CreateApplet(classId, name, tag , wxSize(width, height))) != NULL){
-                               applet->Show(true);
-                               m_WParser->OpenContainer()->InsertCell(new wxHtmlWidgetCell(applet,0));
-                               }
-            else
-                wxMessageBox("wxApplet error: Could not create:" + classId + "," + name);
-                       }
-        else{
-            wxMessageBox("wxApplet tag error: Can not find CLASSID param.","Error",wxICON_ERROR);
+    // Parse the applet dimensions from the tag
+    wxSize size = wxDefaultSize;
+    int al;
+    if (tag.HasParam("WIDTH")) {
+        tag.GetParamAsInt("WIDTH", &width);
+        size.SetWidth(width);
+        }
+    if (tag.HasParam("HEIGHT")) {
+        tag.GetParamAsInt("HEIGHT", &height);
+        size.SetHeight(height);
+        }
+
+    // Parse the applet alignment from the tag
+    al = wxHTML_ALIGN_BOTTOM;
+    if (tag.HasParam(wxT("ALIGN"))) {
+        wxString alstr = tag.GetParam(wxT("ALIGN"));
+        alstr.MakeUpper();  // for the case alignment was in ".."
+        if (alstr == wxT("TEXTTOP") || alstr == wxT("TOP"))
+            al = wxHTML_ALIGN_TOP;
+        else if ((alstr == wxT("CENTER")) || (alstr == wxT("ABSCENTER")))
+            al = wxHTML_ALIGN_CENTER;
+        }
+
+    // Create the applet based on it's class
+    if (tag.HasParam("CLASSID")) {
+        classId = tag.GetParam("CLASSID");
+        if (classId.IsNull() || classId.Len() == 0) {
+            wxMessageBox("wxApplet tag error: CLASSID is NULL or empty.","Error",wxICON_ERROR);
             return false;
             }
             return false;
             }
-        //Add more param parsing here. If or when spec changes.
-        //For now we'll ignore any other params those HTML guys
-        //might put in our tag.
+        if (tag.HasParam("NAME"))
+            name = tag.GetParam("NAME");
+
+        // If the name is NULL or len is zero then we assume that the html guy
+        // didn't include the name param which is optional.
+        if (name.IsNull() || name.Len() == 0)
+            name = classId;
+
+        // We got all the params and can now create the applet
+        if ((applet = appletWindow->CreateApplet(classId, name, tag , size)) != NULL) {
+            applet->Show(true);
+            m_WParser->OpenContainer()->InsertCell(new wxHtmlAppletCell(applet,al));
+            }
+        else
+            wxMessageBox("wxApplet error: Could not create:" + classId + "," + name);
+        }
+    else {
+        wxMessageBox("wxApplet tag error: Can not find CLASSID param.","Error",wxICON_ERROR);
+        return false;
         }
 
         }
 
-       return false;
+    // Add more param parsing here. If or when spec changes.
+    // For now we'll ignore any other params those HTML guys
+    // might put in our tag.
+       return true;
 }
 
 TAG_HANDLER_END(wxApplet)
 }
 
 TAG_HANDLER_END(wxApplet)
@@ -535,6 +732,102 @@ TAGS_MODULE_BEGIN(wxApplet)
     TAGS_MODULE_ADD(wxApplet)
 TAGS_MODULE_END(wxApplet)
 
     TAGS_MODULE_ADD(wxApplet)
 TAGS_MODULE_END(wxApplet)
 
+/****************************************************************************
+REMARKS:
+Constructor for the HTML cell class to store our wxApplet windows in
+the HTML page to be rendered by wxHTML.
+****************************************************************************/
+wxHtmlAppletCell::wxHtmlAppletCell(
+    wxWindow *wnd,
+    int align)
+    : wxHtmlCell()
+{
+    int sx, sy;
+    m_Wnd = wnd;
+    m_Wnd->GetSize(&sx, &sy);
+    m_Width = sx, m_Height = sy;
+    switch (align) {
+        case wxHTML_ALIGN_TOP :
+            m_Descent = m_Height;
+            break;
+        case wxHTML_ALIGN_CENTER :
+            m_Descent = m_Height / 2;
+            break;
+        case wxHTML_ALIGN_BOTTOM :
+        default :
+            m_Descent = 0;
+            break;
+        }
+    SetCanLiveOnPagebreak(FALSE);
+}
+
+/****************************************************************************
+REMARKS:
+Implementation for the HTML cell class to store our wxApplet windows in
+the HTML page to be rendered by wxHTML.
+****************************************************************************/
+wxHtmlAppletCell::~wxHtmlAppletCell()
+{
+    delete m_Wnd;
+}
+
+/****************************************************************************
+REMARKS:
+Code to draw the html applet cell
+****************************************************************************/
+void wxHtmlAppletCell::Draw(
+    wxDC& WXUNUSED(dc),
+    int WXUNUSED(x),
+    int WXUNUSED(y),
+    int WXUNUSED(view_y1),
+    int WXUNUSED(view_y2))
+{
+    int         absx = 0, absy = 0, stx, sty;
+    wxHtmlCell  *c = this;
+
+    while (c) {
+        absx += c->GetPosX();
+        absy += c->GetPosY();
+        c = c->GetParent();
+        }
+    ((wxScrolledWindow*)(m_Wnd->GetParent()))->GetViewStart(&stx, &sty);
+    m_Wnd->Move(absx - wxHTML_SCROLL_STEP * stx, absy  - wxHTML_SCROLL_STEP * sty);
+}
+
+/****************************************************************************
+REMARKS:
+Code to draw the html applet cell invisibly
+****************************************************************************/
+void wxHtmlAppletCell::DrawInvisible(
+    wxDC& WXUNUSED(dc),
+    int WXUNUSED(x),
+    int WXUNUSED(y))
+{
+    int         absx = 0, absy = 0, stx, sty;
+    wxHtmlCell  *c = this;
+
+    while (c) {
+        absx += c->GetPosX();
+        absy += c->GetPosY();
+        c = c->GetParent();
+        }
+    ((wxScrolledWindow*)(m_Wnd->GetParent()))->GetViewStart(&stx, &sty);
+    m_Wnd->Move(absx - wxHTML_SCROLL_STEP * stx, absy  - wxHTML_SCROLL_STEP * sty);
+}
+
+/****************************************************************************
+REMARKS:
+Code to layout the html applet cell.
+****************************************************************************/
+void wxHtmlAppletCell::Layout(
+    int w)
+{
+    int sx, sy;
+    m_Wnd->GetSize(&sx, &sy);
+    m_Width = sx, m_Height = sy;
+    wxHtmlCell::Layout(w);
+}
+
 // This is our little forcelink hack.
 FORCE_LINK(loadpage)
 
 // This is our little forcelink hack.
 FORCE_LINK(loadpage)