FoxPro Programming
Using the Web Browser Control in FoxPro Applications
Gravatar is a globally recognized avatar based on your email address. Using the Web Browser Control in FoxPro Applications
  Rob Corbett
  All
  Apr 12, 2021 @ 12:01pm

Hi Rick,

I just have to start with a thank you for all the insights you provide in your blog/articles/white papers. It's a treasure trove of knowledge that I've used extensively over the years. I'm one of those die hard VFP developers that can't seem to give up this wonderful data-centric tool.

In your article "Using the Web Browser Control in FoxPro Applications (2017, October 20th)" you discuss halting browser navigation with the BeforeNavigate2 event and the Cancel parameter. We've made extensive use of these principles to create a library allowing our entire User Interface to exist in the browser control. Unfortunately, when the VFP thread get's really busy (sometimes with a timer used to create micro-slices), the BeforeNavigate2 event is not always fired on the control. What ends up happening then (since we didn't 'Cancel' the nav), the browser tries navigating to our custom protocol (e.g. fox://action); creating another navigation to res://ieframe.dll/unknownprotocol.htm, causing another BeforeNavigate2 event that we do catch.

Anyway, just wondering if you have any insights about why the BeforeNavigate2 event is not always fired and/or a good method to handle this scenario.

Thanks, Rob Corbett

Gravatar is a globally recognized avatar based on your email address. re: Using the Web Browser Control in FoxPro Applications
  Rick Strahl
  Rob Corbett
  Apr 13, 2021 @ 11:09am

There's no way around that problem. FoxPro blocks the main thread while doing some operations and browser is using that same thread so when FoxPro's main thread is busy the browser thread is also blocked and may fail to fire events when it tries to catch up (or fires them multiple times).

I've had issues with this as well in Help Builder but actually in reverse where large browser page updates would end up tying up the FoxPro interface and then causing a backup of operations to fire in Fox which in turn would slow down the Web Browser and so on. Self-perpetuating slow down machine 😄.

Bottom line: Both FoxPro and the Browser compete for the same thread and if either app doesn't give up cycles you can run into these types of issues. The best you can do is try to minimize these situations by liberally using DoEvents() in your code.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Using the Web Browser Control in FoxPro Applications
  Rob Corbett
  Rob Corbett
  Apr 13, 2021 @ 02:59pm

I was afraid of that. We try to keep our tasks small and fast; unfortunately this app also employs sockets for IPC, another blocking operation. We're using the wwSocket library with nTimeout at the minimum of 1 second. I was considering employing Named Pipes instead; especially the technique you discuss in "10 Cool Examples of using wwDotnetBridge, 2016". I thought this would help by letting some of the work be performed on another thread. I was curious about your C# code in this example:

public event Action<string> ReceiveString;

This string Action event doesn't seem to be employed anywhere. Is it needed?

Also, am I understanding correctly that the pipe is one-way? For bidirectional communication, each application would need a Server and Client implementation, using two pipe names...?

If I go with Named Pipes, is there anything special I should do with the Callback function? One of our guys implemented a Promise class that helps decouple asynchronous events; I would think the OnReceiveMessage() method a good candidate for Promise adoption.

Your thoughts?

Gravatar is a globally recognized avatar based on your email address. re: Using the Web Browser Control in FoxPro Applications
  Rick Strahl
  Rob Corbett
  Apr 14, 2021 @ 01:46pm

You can offload processing to .NET on a separate thread yes that works. In fact, wwDotnetBridge makes that pretty easy via the InvokeTaskMethodAsync() and InvokeMethodAsync() which can run .NET Tasks (like promises) or spin up new threads (the latter) to run an operation and then call back into FoxPro. Both will run asynchronously off the main thread. But to do this you're into .NET code.

Pipes are one way and yes if you need two way communication you need to have client and server on both ends. If that's what you need there may be other ways to do this. Sockets or Web Sockets perhaps or if you're interacting with a Web server plain HTTP requests.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Using the Web Browser Control in FoxPro Applications
  Rob Corbett
  Rick Strahl
  Apr 14, 2021 @ 03:55pm

Actually the communications are strictly local IPC only. We simply have two local VFP apps talking to each other (i.e. the socket client connects to loopback at 127.0.0.1). So you recommended Sockets, but that's what we're using. The wwSocket blocks, at least for nTimeout. I guess your suggesting a .Net socket implementation that can be started with InvokeMethodAsync()? Is that any better than a Named Pipe? I guess Sockets at least provide bidirectional communication, but your Named Pipe code is already written and I've successfully updated and compiled it on VS2019 ...that's why I was asking about the string Action event. Anyway, thanks for your input.

Gravatar is a globally recognized avatar based on your email address. re: Using the Web Browser Control in FoxPro Applications
  Rick Strahl
  Rob Corbett
  Apr 15, 2021 @ 02:20pm

Yeah the wwWebSocket C++ implementation is ancient and very simplistic for simple send and receive operations, but frankly I wouldn't use that.

If I had to do this I would build the socket interface in .NET and then interact with it from FoxPro. Have a Send() (or equivalent method) that you pass a FoxPro object to, then have the .NET code use that object to send the data on the socket. For receiving you can pass a FoxPro object to the .NET instance and when a message comes in you fire a method in FoxPro on the cached object in .NET.

Key is - when you receive the message in FoxPro, pull it out, but don't block then and there. Just capture the message and store it (in a Db or memory) and then use some other mechanism like a queue to process the message when FoxPro is not busy.

The key is that callbacks don't do anything lengthy. In fact, you may be able to do this with your existing code. When events fire, store the data and return immediately then process the method separetely when FoxPro is not blocking or busy.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Using the Web Browser Control in FoxPro Applications
  Alejandro A Sosa
  Rob Corbett
  Apr 18, 2021 @ 09:17am

Hi Rob,

Showing a FoxPro application's User Interface in the browser control would be very eye catching, even in small doses!

Please tell us more about how you do it.

Alex

© 1996-2021