How can I use the Winforms WebBrowser control in a webapp? - multithreading

I have developed a library to manipulate HTML to conform to our needs using the WebBrowser control, however I need this library to work on a web app and not a winforms app. The main issue I get is this:
"ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated because the current thread is not in a single-threaded apartment."
I understand this is because the WebBrowser control needs to be ran in a STA Thread, but obviously a web app isn't an STA environment. Its a server side process though so its not in a page itself. Any ideas on how I can get round this? I considered setting the AspCompat="true" attribute on the Page tag of a hidden page and running it from that but I would rather a more elegant solution.
Cheers

Instantiate and perform your work in a new thread upon which you have explicitly set the ApartmentState via SetApartmentState().

Related

Electron custom web browser with on screen keyboard

I am trying to make a custom web browser inside an electron application. Using webview (because iframe is not loading some necessary web pages) I can load a web page.
Then trying to write something into the web pageĀ“s input by clicking on the react-simple-keyboard which causes blur event, so input loses focus.
I figured out, that this approach would not work directly, so via ipc communication I am trying to resend the key button value and then set it to the window with const {keyboard} = require("#nut-tree/nut-js"); keyboard.type(args.value);
In my input, above the webview tag, it works like a charm, but I am not able to type inside the webview.
Can anyone help me to solve this problem or does anyone know a perfect solution how to use other OSK in electron app or how to open native windows osk on input focus? Thank you in advance.
I'm not sure how you'd accomplish that with this library. But you can just use Window's default on-screen-keyboard to accomplish that. Here is a link to how enable it. windows support
You should also use a BrowserView instead of a Webview, as the Webview is not guaranteed to be present in future versions and it's API is unstable.
The BrowserView doesn't work like an HTML element though and you should read the docs here.
But anyways, just use the system's default and you should be fine.
Also, if you're interested, I'm developing a web browser with Electron (in fact, I'm currently writing this using that browser) and as far as I can say, it's written pretty simply and anyone should understand most of it, so take a look if you're in trouble. But I am no expert and you shouldn't rely on my code as a standard of any kind, really.
Well, I might have just found an answer for you.
Firstly, as I mentioned, you should use a BrowserView instead of webView for your external content, and this time it is a requirement for this method to work. I would create a BrowserWindow with the controls at the top, then place a BrowserView to act as a "browser" and create another BrowserView at the bottom and load in the keyboard html file. And then, when a key is pressed on the virtual keyboard, you should send an ipc message to the main script with the information of what key was pressed(it should be done via a preload script for the OSK BrowserView). In the main script, once you recieve the ipc message (via ipcMain.on()) you should then send an input event to the BrowserView containing your external content. That's done by calling contents.sendInputEvent(Event), so it has to be a main script. Here is a link to contents.sendInputEvent(Event), BrowserView (link) and preload script as well as ipc communication (link).
As for invoking the keyboard once you click on the input element, you could probably do it with a preload script for your "browser's" BrowserView, if you can find how you can check whether the focused element is an input element or something like that, and call an ipc message to then hide or show the keyboard. (Hiding and shwoing the keyboard could be done by calling BrowserWindow.addBrowserView(BrowserView) or BrowserWindow.removeBrowserView(BrowserView). But you would have to search the documentation yourself for those methods as I can't write anymore right now. Documentation could anwser any of your questions if you search for it there.

ActiveX project in Browzer get Zoom Settings

I'm maintaining an existing VB6 application.
It's built as an AcitveX control. The build process builds a CAB file which is then fired into a Browser from an HTM file.
My question is, is there any way to detect the Zoom setting once the Application is loaded in the Browser?
It's not a WebBrowser project so, I can't use that object to query the setting, at least I don't think so...
During the ActiveX initialization process you are guaranteed to get a SetClientSite callback, among many others, which will give you an IWebBrowser2 pointer. There may be some timing issues with regards to zoom, but this is a starting point.

SWT Browser component blocks SWT UI thread

I am embedding an org.eclipse.swt.browser.Browser into a view in a modified eclipse (Indigo), for use as a preview pane of a form editor component. On a form model change or an element selection change the code renders the form via vaadin 6 and displays it in the browser component.
Now, this works like a charm in most cases. But for some highly complex forms the HTML+JS generated by vaadin generates a lot of stress on the browser, rendering it unresponsive for up to a few seconds. That in itself wouldn't be tragic (1), but as long as the SWT Browser component is busy rendering that stuff, the entire eclipse UI thread is blocked.
A simple way to reproduce this is to create an HTML page that blocks inside a javascript function (see https://gist.github.com/creinig/5150747 for an example) and display it in the SWT browser. As long as that JS function is running, the entire SWT application is not responding to anything.
The only info I've found on this problem are
one SO question (without resolution) and
one question on EclipseZone (unanswered).
Not that helpful :(
The API docs of the Browser component don't seem to offer any insight on whether its rendering is triggered periodically by the UI thread or if itself triggers something that blocks the UI.
Is there a way to decouple the Browser component's rendering from the SWT UI thread? Or anything else that could be done to protect the eclipse UI from hanging stuff in the browser?
(1): We need forms of this complexity level, we're already optimizing the rendering performance and a switch to vaadin7 will most likely also speed things up. But the problem will certainly persist, if only in reduced severity.
Not a real solution, but a workaround that Works For Me (TM):
As described here it is really easy to launch the system's default browser from SWT. So I'm going to add an option to the view containing the browser control that will "detach" the view by disabling the browser control and opening the system browser instead.
In case the linked page drops off the net, here's the gist:
org.eclipse.swt.program.Program.launch("http://my.funny.url/");
launches the application registered for HTTP URLs. In other words: the system default browser.
Happiness ensues :)

WebServiceHost inside VSTO addin

I'm about developing an application level VSTO addin that consists, among others, of a UI with an embedded Webbrowser control and a simple REST-style service, based upon WCF's WebServiceHost. The service delivers content, in particular flash movies, to the embedded browser. This used to work like a charm until yesterday. For some still unknown reason (maybe some .NET update that changed some internal processing), the complete Word application now freezes when the browser loads a flash movie from the embedded server. It still works when I move the webserver code into a separate process, and it also works when the flash movie is already in the browser cache, so I am quite sure that it is the combination of serving and displaying the flash movie both in the addin that is causing the problem.
I did some research (which I should have done earlier, maybe) and learned that multi-threading and VSTO addins do not go well together. And running a webservice surely implies some kind of multi-threading.
So my question is: is there any chance to make this kind of architecture run reliably? If so: what am I missing? Or should I better try another approach? If so: what would you recommend?
Note: Using "file://" urls and thus loading the content directly from the disk is not an option since I cannot guarantee a common docroot and need to put some logic between the UI and the content serving.
VSTO add-ins are STA, so you should consider researching WCF and STA (see related SO post).
You could always host the WCF service as a windows service to avoid the STA issues of the VSTO add-in host.

Is it possible to using WebBrowser in a Thread ? (Delphi)

I'm using WebBrowser control to fill a web page . is it possible to using WB inside a thread ?
Thank you
TWebBrowser is a VCL control. Therefore, it must be created and operated in the main VCL thread.
The control already acts asynchronously, though. When you tell it to navigate to a page, it will do that in the background and notify you (via OnNavigateComplete and other events) when it's finished.

Resources