]> git.saurik.com Git - wxWidgets.git/blame_incremental - contrib/src/applet/appletwindow.cpp
fixed bug with the caret positioning after SetValue() introduced by the last commit
[wxWidgets.git] / contrib / src / applet / appletwindow.cpp
... / ...
CommitLineData
1/****************************************************************************
2*
3* wxWindows HTML Applet Package
4*
5* Copyright (C) 1991-2001 SciTech Software, Inc.
6* All rights reserved.
7*
8* ========================================================================
9*
10* The contents of this file are subject to the wxWindows License
11* Version 3.0 (the "License"); you may not use this file except in
12* compliance with the License. You may obtain a copy of the License at
13* http://www.wxwindows.org/licence3.txt
14*
15* Software distributed under the License is distributed on an
16* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
17* implied. See the License for the specific language governing
18* rights and limitations under the License.
19*
20* ========================================================================
21*
22* Language: ANSI C++
23* Environment: Any
24*
25* Description: Main wxHtmlAppletWindow class implementation
26*
27****************************************************************************/
28
29// For compilers that support precompilation
30#include "wx/wxprec.h"
31#include "wx/utils.h"
32#include "wx/process.h"
33#include "wx/spawnbrowser.h"
34#include "wx/html/forcelnk.h"
35
36// crt
37#ifdef __WXMSW__
38#include <process.h> // spawnl()
39#endif
40
41// Include private headers
42#include "wx/applet/applet.h"
43#include "wx/applet/window.h"
44#include "wx/applet/loadpage.h"
45#include "wx/applet/plugin.h"
46
47// Preprocessor Stuff
48#include "wx/applet/prepinclude.h"
49#include "wx/applet/prepecho.h"
50#include "wx/applet/prepifelse.h"
51
52/*---------------------------- Global variables ---------------------------*/
53
54wxHashTable wxHtmlAppletWindow::m_Cookies;
55
56/*------------------------- Implementation --------------------------------*/
57
58// Empty event handler. We include this event handler simply so that
59// sub-classes of wxApplet can reference wxApplet in the event tables
60// that they create as necessary.
61BEGIN_EVENT_TABLE(wxHtmlAppletWindow, wxHtmlWindow)
62 EVT_LOAD_PAGE(wxHtmlAppletWindow::OnLoadPage)
63 EVT_PAGE_LOADED(wxHtmlAppletWindow::OnPageLoaded)
64END_EVENT_TABLE()
65
66// Implement the class functions for wxHtmlAppletWindow
67IMPLEMENT_CLASS(wxHtmlAppletWindow, wxHtmlWindow);
68
69// Define the wxAppletList implementation
70#include "wx/listimpl.cpp"
71WX_DEFINE_LIST(wxAppletList);
72
73/****************************************************************************
74REMARKS:
75Constructor for the applet window class.
76****************************************************************************/
77wxHtmlAppletWindow::wxHtmlAppletWindow(
78 wxWindow *parent,
79 wxWindowID id,
80 wxToolBarBase *navBar,
81 int navBackId,
82 int navForwardId,
83 const wxPoint& pos,
84 const wxSize& size,
85 long style,
86 const wxString& name,
87 const wxPalette& globalPalette)
88 : wxHtmlWindow(parent,id,pos,size,style,name), m_globalPalette(globalPalette)
89{
90 // Init our locks
91 UnLock();
92
93 // setup client navbars
94 if (navBar) {
95 m_NavBarEnabled = true;
96 m_NavBar = navBar;
97 m_NavBackId = navBackId;
98 m_NavForwardId = navForwardId;
99 }
100 else {
101 m_NavBarEnabled = false;
102 m_NavBar = NULL;
103 }
104
105 m_NavBackId = navBackId;
106 m_NavForwardId = navForwardId;
107
108
109 // Set the key_type for applets
110 m_AppletList = wxAppletList(wxKEY_STRING);
111
112 // Add HTML preprocessors
113 // deleting preprocessors is done by the code within the window
114
115 incPreprocessor = new wxIncludePrep(); // #include preprocessor
116 incPreprocessor->ChangeDirectory(m_FS); // give it access to our filesys object
117
118 wxEchoPrep * echoPreprocessor = new wxEchoPrep(); // #echo preprocessor
119 wxIfElsePrep * ifPreprocessor = new wxIfElsePrep();
120
121 this->AddProcessor(incPreprocessor);
122 this->AddProcessor(echoPreprocessor);
123 this->AddProcessor(ifPreprocessor);
124}
125
126/****************************************************************************
127REMARKS:
128Destructor for the applet window class.
129****************************************************************************/
130wxHtmlAppletWindow::~wxHtmlAppletWindow()
131{
132}
133
134#include "scitech.h"
135
136/****************************************************************************
137PARAMETERS:
138dc - wxDC object to draw on
139
140REMARKS:
141This function handles drawing the HTML applet window. Because the standard
142wxWindows classes don't properly handle palette management, we add code
143in here to properly select the global palette that we use for all drawing
144into the DC before we allow the regular wxWindows code to finish the
145drawing process.
146****************************************************************************/
147void wxHtmlAppletWindow::OnDraw(
148 wxDC& dc)
149{
150 // TODO: Only do this for <= 8bpp modes!
151 dc.SetPalette(m_globalPalette);
152 wxHtmlWindow::OnDraw(dc);
153}
154
155/****************************************************************************
156PARAMETERS:
157className - Name of the applet class to create an object for
158size - Initial size of the applet to be created
159
160RETURNS:
161Pointer to the wxApplet created, or NULL if unable to create the applet.
162
163REMARKS:
164This function is used to create new wxApplet objects dynamically based on the
165class name as a string. This allows instances of wxApplet classes to be
166created dynamically based on string values embedded in the custom tags of an
167HTML page.
168****************************************************************************/
169wxApplet *wxHtmlAppletWindow::CreateApplet(
170 const wxString& classId,
171 const wxString& iName,
172 const wxHtmlTag& params,
173 const wxSize& size)
174{
175 // Dynamically create the class instance at runtime
176 wxClassInfo *info = wxClassInfo::FindClass(classId.c_str());
177 if (!info)
178 return NULL;
179 wxObject *obj = info->CreateObject();
180 if (!obj)
181 return NULL;
182 wxApplet *applet = wxDynamicCast(obj,wxApplet);
183 if (!applet)
184 return NULL;
185 if (!applet->Create(this,params,size)) {
186 delete applet;
187 return NULL;
188 }
189 else {
190 // do some fixups on the size if its screwed up
191 wxSize nsize = applet->GetBestSize();
192 if (nsize.x < size.x) nsize.x = size.x;
193 if (nsize.y < size.y) nsize.y = size.y;
194 applet->SetSize(nsize);
195 }
196
197 m_AppletList.Append(iName,(wxObject*)applet);
198 return applet;
199}
200
201/****************************************************************************
202PARAMETERS:
203classId - Name of the Plugin class to create an object for
204
205RETURNS:
206Pointer to the wxplugIn created, or NULL if unable to create the PlugIn.
207
208REMARKS:
209This function is used to create new wxPlugIn objects dynamically based on the
210class name as a string. This allows instances of wxPlugIn classes to be
211created dynamically based on string values embedded in the custom tags of an
212HTML page.
213****************************************************************************/
214bool wxHtmlAppletWindow::CreatePlugIn(
215 const wxString& classId )
216{
217 // Dynamically create the class instance at runtime
218 wxClassInfo *info = wxClassInfo::FindClass(classId.c_str());
219 if (!info)
220 return false;
221 wxObject *obj = info->CreateObject();
222 if (!obj)
223 return false;
224 wxPlugIn *plugIn = wxDynamicCast(obj,wxPlugIn);
225 if (!plugIn)
226 return false;
227 if (!plugIn->Create(this)) {
228 delete plugIn;
229 return false;
230 }
231 return true;
232}
233
234/****************************************************************************
235PARAMETERS:
236appletName - Name of the applet class to find
237
238RETURNS:
239Pointer to the wxApplet found, or NULL if not found.
240
241REMARKS:
242Find an instance of an applet based on it's name
243****************************************************************************/
244wxApplet *wxHtmlAppletWindow::FindApplet(
245 const wxString& appletName)
246{
247 wxAppletList::Node *node = m_AppletList.Find(appletName);
248 if (!node)
249 return NULL;
250 return node->GetData();
251}
252
253/****************************************************************************
254PARAMETERS:
255applet - Pointer to the applet object to remove from the list
256
257RETURNS:
258True if the applet was found and removed, false if not. The applet itself
259is *not* destroyed!
260
261REMARKS:
262Remove an applet from the manager. Called during applet destruction
263****************************************************************************/
264bool wxHtmlAppletWindow::RemoveApplet(
265 const wxApplet *applet)
266{
267 for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext()) {
268 if (node->GetData() == applet) {
269 m_AppletList.DeleteNode(node);
270 return true;
271 }
272 }
273 return false;
274}
275
276/****************************************************************************
277PARAMETERS:
278URL - New URL for the page to load
279
280RETURNS:
281True if page loaded successfully, false if not
282
283REMARKS:
284Remove an applet from the manager. Called during applet destruction
285****************************************************************************/
286bool wxHtmlAppletWindow::LoadPage(
287 const wxString& link)
288{
289 wxString href(link);
290
291 if (link.GetChar(0) == '?'){
292 wxString cmd = link.BeforeFirst('=');
293 wxString cmdValue = link.AfterFirst('=');
294
295 // Launches the default Internet browser for the system.
296 if(!(cmd.CmpNoCase("?EXTERNAL"))){
297 return wxSpawnBrowser(this, cmdValue.c_str());
298 }
299
300 // Launches an external program on the system.
301 if (!(cmd.CmpNoCase("?EXECUTE"))){
302 int code = spawnl( P_NOWAIT, cmdValue , NULL );
303 return (!code);
304 }
305
306 // Looks for a href in a variable stored as a cookie. The href can be
307 // changed on the fly.
308 if (!(cmd.CmpNoCase("?VIRTUAL"))){
309 VirtualData& temp = *((VirtualData*)FindCookie(cmdValue));
310 if (&temp) {
311 href = temp.GetHref();
312 }
313 else {
314#ifdef CHECKED
315 wxLogError(_T("VIRTUAL LINK ERROR: '%s' does not exist."), cmdValue.c_str());
316#endif
317 return true;
318 }
319 }
320
321 // This launches a qlet - It is like an applet but is more generic in that it
322 // can be of any wxWin type so it then has the freedom to do more stuff.
323 if (!(cmd.CmpNoCase("?WXAPPLET"))){
324 if (!cmdValue.IsNull()){
325 if (!CreatePlugIn(cmdValue)){
326#ifdef CHECKED
327 wxLogError(_T("Launch Applet ERROR: '%s' does not exist."), cmdValue.c_str());
328#endif
329 }
330 }
331 return true;
332 }
333 }
334
335 // Inform all the applets that the new page is being loaded
336 for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext())
337 (node->GetData())->OnLinkClicked(wxHtmlLinkInfo(href));
338 Show(false);
339
340 bool stat = wxHtmlWindow::LoadPage(href);
341 Show(true);
342
343 // Enable/Dis the navbar tools
344 if (m_NavBarEnabled) {
345 m_NavBar->EnableTool(m_NavForwardId,HistoryCanForward());
346 m_NavBar->EnableTool(m_NavBackId,HistoryCanBack());
347 }
348 return stat;
349}
350
351/****************************************************************************
352PARAMETERS:
353URL - String URL that we are navigating to
354
355REMARKS:
356Called when the user navigates to a new URL from the current page. We simply
357call the LoadPage function above to load the new page and display it.
358****************************************************************************/
359void wxHtmlAppletWindow::OnLinkClicked(
360 const wxHtmlLinkInfo& link)
361{
362 LoadPage(link.GetHref());
363}
364
365/****************************************************************************
366REMARKS:
367Called when the user navigates forward within the HTML history stack.
368We call all the applets in turn allowing them to handle the navigation
369command prior to being destructed when the current page is destroyed.
370****************************************************************************/
371bool wxHtmlAppletWindow::HistoryForward()
372{
373 if (!HistoryCanForward())
374 return false;
375
376 for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext())
377 (node->GetData())->OnHistoryForward();
378
379 return wxHtmlWindow::HistoryForward();
380}
381
382/****************************************************************************
383REMARKS:
384Called when the user navigates backwards within the HTML history stack.
385We call all the applets in turn allowing them to handle the navigation
386command prior to being destructed when the current page is destroyed.
387****************************************************************************/
388bool wxHtmlAppletWindow::HistoryBack()
389{
390 if (!HistoryCanBack())
391 return false;
392
393 for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext())
394 (node->GetData())->OnHistoryBack();
395
396 return wxHtmlWindow::HistoryBack();
397}
398
399/****************************************************************************
400REMARKS:
401This function is used to disable the navigation bars. If you want to
402toggle to the navbars off you must call this function.
403****************************************************************************/
404void wxHtmlAppletWindow::DisableNavBar()
405{
406 m_NavBarEnabled = false;
407}
408
409/****************************************************************************
410REMARKS:
411This function is used to enable the nav bars. If you toggle the nav bars on
412you must call this function.
413****************************************************************************/
414void wxHtmlAppletWindow::EnableNavBar()
415{
416 m_NavBarEnabled = true;
417}
418
419/****************************************************************************
420REMARKS:
421This function is used to set the nav bar to a new nav bar if you deleted the
422one that you were useing. Usally this happens when you toggle a nav bar
423on or off.
424****************************************************************************/
425void wxHtmlAppletWindow::SetNavBar(wxToolBarBase *navBar)
426{
427 m_NavBar = navBar;
428}
429
430/****************************************************************************
431PARAMETERS:
432msg - wxEvent message to be sent to all wxApplets
433
434REMARKS:
435This function is called by the wxApplet's when they need to send a message
436to all other applets on the current page. This is the primary form of
437communication between applets on the page if they need to inform each
438other of internal information.
439
440Note that the event handling terminates as soon as the first wxApplet
441handles the event. If the event should be handled by all wxApplet's,
442the event handlers for the applets should not reset the wxEvent::Skip()
443value (ie: by default it is true).
444****************************************************************************/
445void wxHtmlAppletWindow::SendMessage(
446 wxEvent& msg)
447{
448 // Preset the skip flag
449 msg.Skip();
450
451 // Process all applets in turn and send them the message
452 for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext()) {
453 (node->GetData())->OnMessage(msg);
454 if (!msg.GetSkipped()){
455 wxMessageBox("BREAK");
456 break;
457 }
458 }
459}
460
461/****************************************************************************
462PARAMETERS:
463name - Uniq wxString used as hash key
464cookie - wxObject data returned when name is found.
465
466RETURNS:
467True if new cookie was added, false if cookie with same name already exists.
468
469REMARKS:
470This function is called by the wxApplet's when they need register a cookie
471of data in the applet window's cookie table. Cookies are arbitrary data
472objects that are references by unique name's by the wxApplet. These
473values can be used to store and retrieve data that needs to remain
474persisent across invocations of the wxApplet. Ie: The first time an
475applet is created it would use the cookie to store data to maintain
476it's present state so that if you navigated back to the same page
477is would be able to re-load the prior state as though the applet
478was never actually destructed.
479
480Note: If a cookie with the same name already exists, this function returns
481 false. Hence if you wish to replace a cookie you should first call
482 UnRegisterCookie to ensure the cookie is deleted and then call this
483 function.
484****************************************************************************/
485bool wxHtmlAppletWindow::RegisterCookie(
486 const wxString& name,
487 wxObject *cookie)
488{
489 // Fail if the named cookie already exists!
490 if (m_Cookies.Get(name))
491 return false;
492 m_Cookies.Put(name,cookie);
493 return true;
494}
495
496/****************************************************************************
497PARAMETERS:
498name - wxString uniq haskey used to remove item from hash
499
500RETURNS:
501True if found and deleted, false if not found in table.
502
503REMARKS:
504This function is called by the wxApplet's when they need de-register a
505cookie of data in the applet window's cookie table. The data in the
506cookie itself is also deleted before it is removed from the table.
507****************************************************************************/
508bool wxHtmlAppletWindow::UnRegisterCookie(
509 const wxString& name)
510{
511 wxObject *data = m_Cookies.Delete(name);
512 if (data) {
513 delete data;
514 return true;
515 }
516 return false;
517}
518
519/****************************************************************************
520PARAMETERS:
521msg - wxEvent message to be sent to all wxApplets
522
523RETURNS:
524Pointer to the cookie data if found, NULL if not found.
525
526REMARKS:
527This function is called by the wxApplet's when they need to find a cookie
528of data given it's public name. If the cookie is not found, NULL is
529returned.
530****************************************************************************/
531wxObject *wxHtmlAppletWindow::FindCookie(
532 const wxString& name)
533{
534 return m_Cookies.Get(name);
535}
536
537/****************************************************************************
538PARAMETERS:
539event - Event to handle
540
541REMARKS:
542This function handles delayed LoadPage events posted from applets that
543need to change the page for the current window to a new window.
544****************************************************************************/
545void wxHtmlAppletWindow::OnLoadPage(
546 wxLoadPageEvent &event)
547{
548 // Test the mutex lock.
549 if (!(IsLocked())){
550 Lock();
551 if (event.GetHtmlWindow() == this){
552 if (LoadPage(event.GetHRef())){
553 // wxPageLoadedEvent evt;
554 // NOTE: This is reserved for later use as we might need to send
555 // page loaded events to applets.
556 }
557 }
558 UnLock();
559 }
560}
561
562/****************************************************************************
563PARAMETERS:
564event - Event to handle
565
566REMARKS:
567This function handles delayed LoadPage events posted from applets that
568need to change the page for the current window to a new window.
569****************************************************************************/
570void wxHtmlAppletWindow::OnPageLoaded(
571 wxPageLoadedEvent &)
572{
573 Enable(true);
574}
575
576/****************************************************************************
577PARAMETERS:
578none
579
580REMARKS:
581This function tries to lock the mutex. If it can't, returns
582immediately with false.
583***************************************************************************/
584bool wxHtmlAppletWindow::TryLock()
585{
586 if (!m_mutexLock) {
587 m_mutexLock = true;
588 return true;
589 }
590 return false;
591}
592
593/****************************************************************************
594PARAMETERS:
595name - name of the last applet that changed the data in this object
596group - name of the group the allplet belongs to.
597href - webpage to go to.
598
599REMARKS:
600VirtualData is used to store information on the virtual links.
601****************************************************************************/
602VirtualData::VirtualData(
603 wxString& name,
604 wxString& group,
605 wxString& href )
606{
607 m_name = name;
608 m_group = group;
609 m_href = href;
610}
611
612/****************************************************************************
613PARAMETERS:
614REMARKS:
615VirtualData is used to store information on the virtual links.
616****************************************************************************/
617VirtualData::VirtualData()
618{
619 m_name.Empty();
620 m_group.Empty();
621 m_href.Empty();
622}
623
624/****************************************************************************
625PARAMETERS:
626REMARKS:
627****************************************************************************/
628void AppletProcess::OnTerminate(
629 int,
630 int )
631{
632 // we're not needed any more
633 delete this;
634}
635
636#include "wx/html/m_templ.h"
637
638/****************************************************************************
639REMARKS:
640Implementation for the <embed> HTML tag handler. This handler takes care
641of automatically constructing the wxApplet objects of the appropriate
642class based on the <embed> tag information.
643****************************************************************************/
644TAG_HANDLER_BEGIN(wxApplet, "WXAPPLET")
645
646TAG_HANDLER_PROC(tag)
647{
648 wxWindow *wnd;
649 wxHtmlAppletWindow *appletWindow;
650 wxApplet *applet;
651 wxString classId;
652 wxString name;
653 int width, height;
654
655 wnd = m_WParser->GetWindow();
656
657 if ((appletWindow = wxDynamicCast(wnd,wxHtmlAppletWindow)) != NULL){
658 wxSize size = wxDefaultSize;
659 int al;
660 if (tag.HasParam("WIDTH")) {
661 tag.GetParamAsInt("WIDTH", &width);
662 size.SetWidth(width);
663 }
664
665 if (tag.HasParam("HEIGHT")) {
666 tag.GetParamAsInt("HEIGHT", &height);
667 size.SetHeight(height);
668 }
669
670 al = wxHTML_ALIGN_BOTTOM;
671 if (tag.HasParam(wxT("ALIGN"))) {
672 wxString alstr = tag.GetParam(wxT("ALIGN"));
673 alstr.MakeUpper(); // for the case alignment was in ".."
674 if (alstr == wxT("TEXTTOP") || alstr == wxT("TOP"))
675 al = wxHTML_ALIGN_TOP;
676 else if ((alstr == wxT("CENTER")) || (alstr == wxT("ABSCENTER")))
677 al = wxHTML_ALIGN_CENTER;
678 }
679
680 if (tag.HasParam("CLASSID")){
681 classId = tag.GetParam("CLASSID");
682 if ( classId.IsNull() || classId.Len() == 0 ){
683 wxMessageBox("wxApplet tag error: CLASSID is NULL or empty.","Error",wxICON_ERROR);
684 return false;
685 }
686 if (tag.HasParam("NAME"))
687 name = tag.GetParam("NAME");
688
689 // If the name is NULL or len is zero then we assume that the html guy
690 // didn't include the name param which is optional.
691 if ( name.IsNull() || name.Len() == 0 )
692 name = classId;
693
694 // We got all the params and can now create the applet
695 if ((applet = appletWindow->CreateApplet(classId, name, tag , size)) != NULL){
696 applet->Show(true);
697 m_WParser->OpenContainer()->InsertCell(new wxHtmlAppletCell(applet,al));
698 }
699 else
700 wxMessageBox("wxApplet error: Could not create:" + classId + "," + name);
701 }
702 else{
703 wxMessageBox("wxApplet tag error: Can not find CLASSID param.","Error",wxICON_ERROR);
704 return false;
705 }
706 //Add more param parsing here. If or when spec changes.
707 //For now we'll ignore any other params those HTML guys
708 //might put in our tag.
709 }
710
711 return false;
712}
713
714TAG_HANDLER_END(wxApplet)
715
716TAGS_MODULE_BEGIN(wxApplet)
717 TAGS_MODULE_ADD(wxApplet)
718TAGS_MODULE_END(wxApplet)
719
720/*********************************************************************************
721wxHtmlAppletCell
722*********************************************************************************/
723wxHtmlAppletCell::wxHtmlAppletCell(wxWindow *wnd, int align) : wxHtmlCell()
724{
725 int sx, sy;
726 m_Wnd = wnd;
727 m_Wnd->GetSize(&sx, &sy);
728 m_Width = sx, m_Height = sy;
729
730 switch (align) {
731 case wxHTML_ALIGN_TOP :
732 m_Descent = m_Height;
733 break;
734 case wxHTML_ALIGN_CENTER :
735 m_Descent = m_Height / 2;
736 break;
737 case wxHTML_ALIGN_BOTTOM :
738 default :
739 m_Descent = 0;
740 break;
741 }
742
743 SetCanLiveOnPagebreak(FALSE);
744}
745
746
747void wxHtmlAppletCell::Draw(wxDC& WXUNUSED(dc), int WXUNUSED(x), int WXUNUSED(y), int WXUNUSED(view_y1), int WXUNUSED(view_y2))
748{
749 int absx = 0, absy = 0, stx, sty;
750 wxHtmlCell *c = this;
751
752 while (c)
753 {
754 absx += c->GetPosX();
755 absy += c->GetPosY();
756 c = c->GetParent();
757 }
758
759 ((wxScrolledWindow*)(m_Wnd->GetParent()))->GetViewStart(&stx, &sty);
760 m_Wnd->Move(absx - wxHTML_SCROLL_STEP * stx, absy - wxHTML_SCROLL_STEP * sty);
761}
762
763
764
765void wxHtmlAppletCell::DrawInvisible(wxDC& WXUNUSED(dc), int WXUNUSED(x), int WXUNUSED(y))
766{
767 int absx = 0, absy = 0, stx, sty;
768 wxHtmlCell *c = this;
769
770 while (c)
771 {
772 absx += c->GetPosX();
773 absy += c->GetPosY();
774 c = c->GetParent();
775 }
776
777 ((wxScrolledWindow*)(m_Wnd->GetParent()))->GetViewStart(&stx, &sty);
778 m_Wnd->Move(absx - wxHTML_SCROLL_STEP * stx, absy - wxHTML_SCROLL_STEP * sty);
779}
780
781
782
783void wxHtmlAppletCell::Layout(int w)
784{
785 int sx, sy;
786 m_Wnd->GetSize(&sx, &sy);
787 m_Width = sx, m_Height = sy;
788
789 wxHtmlCell::Layout(w);
790}
791
792
793
794
795// This is our little forcelink hack.
796FORCE_LINK(loadpage)
797