Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Shell.explorer.2 create document from variable
Message
General information
Forum:
Visual FoxPro
Category:
ActiveX controls in VFP
Environment versions
Visual FoxPro:
VFP 9 SP1
OS:
Windows XP SP2
Database:
Visual FoxPro
Application:
Web
Miscellaneous
Thread ID:
01660900
Message ID:
01661201
Views:
168
UPDATED ZIP: The vcx contained an unnecessary reference to a vcx that is not part of the zip.
UPDATED ZIP: I have removed some unnecessary classes from the classlib.

Hi Rick, Cetin and Yousfi,

Last week(s) I have learned a lot about the DOM, also here from you three. I have created a RichTextEditor (named RTE) and ATTACH RICHTEXTEDITOR.ZIP HERE. I hope you will comment on my various solutions. These solutions are documented within and outside the code. About some of the solutions I am not sure, meaning that there are likely better solutions. Here are some topics for discussion.

The HTMLLoad() function uses navigate2('about:blank') only to create a document object, Then it gets a CSS-like string and replaces its body-section with the saved outerhtml text. Then it does a write().

While the navigate2() is checked with .busy and readystate, the write() is checked with my waitTillReady() function. That function waits for the document.readystate='complete', but it has additional code to prevent that all 'hangs' due to an almost endless 'loading' or 'interactive'.

WBEventHandler() is based on what Yousfi published, but I found some 'issues', searched for solutions, did some experiments and implemented my solutions to those 'issues'. @Yousfi, I hope you can implement my solutions in your example code.

@Rick, some of your solutions are not yet explored by me, esp. Initializeinterop, DocumentComplete and NavigateComplete. Do you think my code can still be improved by using those?

Greeting, Peter




>There are a couple of proper ways to do this:
>
>* Wait for ReadyState = 4
>* Use DocumentComplete or NavigateComplete events for processing
>
>Everything else is not 100% reliable. The browser exposes DocumentComplete and NavigateComplete events which you can use to detect when navigation is complete and when the document is complete. The only issue is that DocumentComplete waits for everything on the page to load (including images etc.) so this can take way longer than is required to start accessing the document. The document events are also asynchronous which can make things a litle more difficult to work with in FoxPro.
>
>I tend to use the ReadyState check or explicit probing for the document or something inside of the document (an object or specific DOM element). The readystate check is easy can can be made quite generic by implementing a method in the control (or create a UDF() and pass in the browser):
>
>
>FUNCTION WaitForReadyState
>LPARAMETERS lnReadyState, lnMilliSeconds
>
>IF EMPTY(lnReadyState)
>  lnReadyState = 4
>ENDIF
>
>IF EMPTY(lnMilliSeconds)
>   lnMilliSeconds = this.nDocumentTimeout 
>ENDIF
>
>DECLARE INTEGER Sleep IN WIN32API INTEGER nMSecs
>
>lnX = 0
>DO WHILE this.ReadyState # lnReadyState AND ;
>         lnX < lnMilliSeconds
>  DOEVENTS
>  lnX = lnX + 1 
>  WAIT WINDOW "" TIMEOUT 0.01  && give up timeslice so UI doesn't freeze
>ENDDO
>
>IF lnX * 100 < lnMilliSeconds
>  RETURN .T. && Not timed out
>ENDIF
>
>RETURN .F.
>
>For example in HelpBuilder I use an JavaScript/HTML based text editor and I load the editor on `INIT()` but won't access the document immediately, and rather delay until I assign the value to it which may be a few milliseconds later. Most of the time by the time this happens the document is already loaded anyway.
>
>But there's logic there that checks like this:
>
>
>LPARAMETERS lcValue, llNoEditorUpdate
>LOCAL lcAff, lcDic, lnX
>
>*** Text Editor is the JavaScript TextEditor model we talk to
>*** Ensure it's loaded
>IF VARTYPE(THIS.TextEditor) != "O"
>	THIS.waitforreadystate()
>	
>	DOEVENTS
>    
>	lnX = 0
>	DO WHILE VARTYPE(THIS.TextEditor) != "O" AND lnX < 50
>		TRY
>			THIS.TextEditor = THIS.DOCUMENT.parentWindow.initializeinterop(THISFORM,THIS)
>		CATCH
>			WAIT WINDOW "" TIMEOUT 0.1
>		ENDTRY
>		lnX = lnX + 1 
>	ENDDO		
>	IF lnX > 49
>	   MESSAGEBOX("Unable to create editor instance.")
>	   return
>	ENDIF
>ENDIF
>
>IF !(lcValue == THIS.oHiddenTextBox.Value)	
>   IF !llNoEditorUpdate
>	   THIS.TextEditor.setvalue(lcValue)   
>   ENDIF
>   DOEVENTS
>   THIS.oHiddenTextBox.Value = lcValue   
>ENDIF
>
>
>
>Note that in almost all cases it's better to load the initial HTML from disk or Web URL rather than assigning the entire document via the HTML Document so that there's a proper base URL assigned to the document. If you use about:blank no base URL is set and you won't be able to find related CSS/Images etc.
>
>Hope this helps,
>
>
>+++ Rick ---
>
>>Hi All,
>>
>>Currently I'm creating a HTML-editbox that uses the shell.explorer.2 webbrowser. The html-formatted texts are in a memo field. Suppose the object reference is oleControl1. I could start with such a text by writing it to a file first and then use oleControl1.NAVIGATE( "some file" ) or using a URL as parameter, like in my example.
>>
>>I have tried to find the way to fill the editbox with the contents of a variable (the memo field). Esp. INNERHTML and OUTERHTML had my attention. But sofar I fail unless I first use NAVIGATE(). The problem is that, without navigate(), the DOCUMENT object is not created. And INNERHTML and OUTERHTML are sub-properties of DOCUMENT.
>>
>>I have also first declared NAVIGATE("about:blank"), thus creating an empty DOCUMENT. Is this the obliged way to go? Or is there another way to create the DOCUMENT object that does not require the use of NAVIGATE()?
>>
>>
>>PUBLIC oform1
>>
>>oform1=NEWOBJECT("form1")
>>oform1.Show
>>RETURN
>>
>>DEFINE CLASS form1 AS form
>>
>>
>>	DoCreate = .T.
>>	Caption = "Form1"
>>	Name = "Form1"
>>
>>
>>	ADD OBJECT olecontrol1 AS olecontrol WITH ;
>>		oleclass = "shell.explorer.2", ;
>>		Top = 0, ;
>>		Left = 0, ;
>>		Height = 100, ;
>>		Width = 100, ;
>>		Name = "Olecontrol1"
>>
>>
>>	PROCEDURE Init
>>		this.olecontrol1.navigate("https://www.google.nl/")
>>		this.resize()
>>	ENDPROC
>>
>>
>>	PROCEDURE Resize
>>		with this
>>			.olecontrol1.height = .height
>>			.olecontrol1.width = .width
>>		endwith
>>	ENDPROC
>>
>>
>>ENDDEFINE
>>*
>>*-- EndDefine: form1
>>**************************************************
>>
Groet,
Peter de Valença

Constructive frustration is the breeding ground of genius.
If there’s no willingness to moderate for the sake of good debate, then I have no willingness to debate at all.
Let's develop superb standards that will end the holy wars.
"There are three types of people: Alphas and Betas", said the beta decisively.
If you find this message rude or offensive or stupid, please take a step away from the keyboard and try to think calmly about an eventual a possible alternative explanation of my message.
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform