Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
HTML mailmerge templates
Message
De
29/11/2020 15:21:25
Walter Meester
HoogkarspelPays-Bas
 
 
À
29/11/2020 09:19:31
Information générale
Forum:
Visual FoxPro
Catégorie:
Contrôles ActiveX en VFP
Divers
Thread ID:
01677316
Message ID:
01677326
Vues:
60
Thanks thomas for the elaborate insight.

My understanding so far is, that there is so much investment in the IE webcontrol, that Microsoft is never going to drop support for it. I'm not prepared to do anything else which might even have a more shaky future.

We are not doing any complex matters with the control, merely using it as a html text editor and displaying documents. The support for merge fields is as complex as it gets (so far). Performance is not an issue at all, so the marshalling is fine for me, nor is it a problem to deal with COM collections. I'm aware of the risks. If some problem pops up in the future, we will weigh our options at that point.

Our application are only run on full windows installations. There is absolutely no intent to run it on linux. In the more distant future, we want to make this all full web based, but it is a major challenge to get the proper resources (getting smart people who are able to dive into the complexity and be productive) to do this for an application that has been around for 24 years and has load and loads of functionality. We are currently doing this slowly bit by bit.

Walter,


>Hi Walter,
>
>Antonio already pointed you to the proper way to do things as seen by W3C.
>I have not checked your zip, but you asked about WebBrowser - which is IE based ;-))
>In the early days (IE5, IE6) working was often eased if done via document.all, but that is NOT standard.
>
>Before starting to code, take an eagle eye view on possible future needs, speeds, trends and budget.
>Largest worry for me would be the question how to be certain that CreateObject() to IE/WebBrowser, which is/was considered part of the Windows operating system, will succeed for long time on all customer machines. At the moment this is only evoking head scratching in weird fringes Dragan and myself visit: trying to run vfp under Linux with Wine as compatibility layer - which does not work, as the scripts to invoke last separate "IE install" (IE4 and IE5) did not work last time I quick-checked.
>
>Under proper Windows I expect first troubles to materialize on ARM 64, which might interest a larger group of weirdos in the future, trying things like
>https://www.notebookcheck.com/Das-schnellste-ARM-Windows-Windows-10-laeuft-bereits-auf-Apple-M1-Macs.506549.0.html
>with 32 Bit WindowsOnArm and somewhen coming pureAmd64 Windows or WindowsAmd64_plus_xx128 next in line - Vfp Advanced64 will give you a good chance to run even then but IE install is not under your control.
>
>That said: while IE is considered dumb, slow step child today, for limited tasks the well-tested API with problems often encountered before is a choice with benefits in that area.
>
>Chance has it I looked around in that area last week:

    >
  • There is a video by Christoph on using CEF with vfp on Youtube in the Virtual Fox Fest, which describes how you can use the OS version of Chrome, Chromium within vfp
    >
  • MS has declared official support for WebView2 in Winforms, WPF, Win32-C++ and soon UWP. Webview2 gives you a ChromiumEdge based control, which should be usable in a Dotnet-wrapped WinForm or WPF control in a vfp form accessed either via wwDotnet or compiled with a COM wrapper.
    >
  • For a couple of years cross-browser testing has been done most of the time with Selenium, which is available in Java, Python and Dotnet. Dotnet itself offers a specific API to connect to Selenium driver - not certain if only for ChromiumEdge or other browsers as well.
    >
  • There is a company offering a InternetExplorer API to a Chromium based browser with a licensing policy ok if # of developers is low and # of customers is high when I encountered them. Christoph mentions the company in his video early on as well - not tested here, but might be maintainance and money saving if you do a lot with IE interfaces and run into trouble in a few years.

>Rick already has started testing with Webview2 and even filed some early bug reports AND a solution to current API shortcomings loading disk files ;-)
>Couple of years ago I did small web queries again - ran into trouble with IE automation and some web sites, moved approach to Selenium - worked, but I was not very proud of the stuff I did back then, IE having problems and Selenium needing intermediate COM layer (did Java via JaCOB and Python, last had Python analytic "biz code" calling into specific vfp COM methods later) as no direct bindings for vfp exist. Reason for me looking into that area again is to find reasonably elegant/well architected approach for such tasks ;-)
>
>Architecture:
>Antonio already showed best practices for code with vfp "in the drivers seat". But such an approach is going against my 2. mantra "chunky, not chatty"- If you look closer
>       PROCEDURE ProcessField (FieldId AS String, FieldValue AS String)
>		This.HtmlViewer.Document.getElementById(m.FieldId).innerText = m.FieldValue
>	ENDPROC
>
>	PROCEDURE GetFieldsInDocument () AS Collection
>		m.AllFields = CREATEOBJECT("Collection")
>		m.Spans = This.HtmlViewer.Document.getElementsByTagName("span")
>		FOR EACH m.Span IN m.Spans
>			IF m.Span.className == "field"
>				m.AllFields.Add(m.Span.Id)
>			ENDIF
>		ENDFOR
>
>		RETURN m.AllFields
>	ENDPROC		
>
>the single line in ProcessField invokes several times marshalling, even with caching the .document as a property done in production this is not eliminated to major degree.
>m.Spans = This.HtmlViewer.Document.getElementsByTagName("span")
>shows best way to minimize such marshalling: calling into Javascript/DOM methods eliminates marshalling when drilling down, but chances are that returned Spans collection is a COM collection of COM objects. Again you could mitigate some marshalling by adding a reference to each HTML control in the vfp collection object, giving you direct access for each id, but in "reactive DOM" environments not under your control those elements might be moved or deleted, making that approach more brittle/needing more check logic than dumb new call across COM barrier.
>For me the best solution is to inject more of the "biz logic" into the Javascript engine and call from vfp with few methods having JSON payload - those call multiple methods in browser, for instance setting all .innerText for the property names inside a JSON object with a single call across COM.
>If you must switch the hosted browser or the hosting mechanism, you only need to reengineer the 6 or so methods calling into browser via blocking, event - asynch or similar nature plus injection if not done in original HTML file.
>On a reasonable client machine a couple of thousand COM calls will not be that bad, but if you decide to run many instances in a terminal server or webserver based setup might become more important. Also such behaviour is unneccessary cruelty towards poor CPU ;-)
>Probably 10-20% more cost to develop if developer not as firm in JS as in vfp, but in the long run better as less technical debt is added.
>
>my 0.22€ - and IAC visit Ricks site (again) before deciding or coding!
>thomas
>
>>Excellent. Thanks very much. This will get me closer to where I want to go.
>>
>>One last question. What is the best way to iterate through the fields to process them. Is there a collection I can iterate through to get all the fields ?
>>
>>Walter,
>>
>>
>>>>>>Hi All,
>>>>>>
>>>>>>I'm looking into the ability to create a mailmerge template (in the web browser control) and display when values are being filled in from a table. Just the way Word does it. I have been able to create a text editor from the IE web control (see attachment).
>>>>>>I want to be able to create a button on the toolbar to insert a mailmerge field which is just a placeholder for the actual value after merging (just like in word).
>>>>>>
>>>>>>Moreover The HTML should preserve the mergefield so that the mergefields can update the values if they change.
>>>>>>
>>>>>>Has anyone have experience with this ?
>>>>>
>>>>>Walter,
>>>>>
>>>>>Can you insert a
>>>>>
>>>>><span id="fieldid" class="mergefield">Field name</span>
>>>>>
>>>>>in the document that the editor will not change? If so, you could pre- or post-process your document and fill in the fields according to their ids.
>>>>
>>>>Thanks antonio,
>>>>
>>>>Do you happen to have some VFP code to iterate throught the document to replace those values ?
>>>
>>>A crude demo, Walter:
>>>
>>>
>>>LOCAL HTMLSource AS String
>>>
>>>TEXT TO m.HTMLSource NOSHOW FLAGS 1
>>><html>
>>> <head>
>>>  <title>A document</title>
>>>  <style>.field {color: red}</style>
>>> </head>
>>> <body>
>>>  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
>>>  dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
>>>  commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
>>>  nulla pariatur. <span id="field001" class="field">Field #1</span> Excepteur sint occaecat cupidatat non
>>>  proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
>>> </body>
>>></html>
>>>ENDTEXT
>>>
>>>STRTOFILE(m.HTMLSource, "wm.html")
>>>
>>>LOCAL Browser AS BrowserForm
>>>
>>>m.Browser = CREATEOBJECT("BrowserForm")
>>>m.Browser.Show()
>>>WAIT WINDOW "Load the document..."
>>>m.Browser.LoadDocument(FULLPATH("wm.html"))
>>>WAIT WINDOW "Set the field value..."
>>>m.Browser.ProcessField("field001", "Walter")
>>>WAIT WINDOW "Done!"
>>>
>>>DEFINE CLASS BrowserForm AS Form
>>>
>>>	ADD OBJECT HtmlViewer AS OleControl WITH Width = This.Width, Height = This.Height, OleClass = "Shell.Explorer"
>>>
>>>	PROCEDURE Init
>>>		This.HtmlViewer.Navigate2("about:blank")
>>>	ENDPROC
>>>
>>>	PROCEDURE LoadDocument (Document AS String)
>>>		This.HtmlViewer.Navigate2(m.Document)
>>>	ENDPROC
>>>
>>>	PROCEDURE ProcessField (FieldId AS String, FieldValue AS String)
>>>		This.HtmlViewer.Document.getElementById(m.FieldId).innerText = m.FieldValue
>>>	ENDPROC
>>>
>>>ENDDEFINE
>>>
Précédent
Répondre
Fil
Voir

Click here to load this message in the networking platform