Should i use WPF or WinForms/WindowsFormsHost in WPF app?

Having problems with building or using the CefGlue .NET/Mono binding? Ask your questions here.

Moderator: fddima

Should i use WPF or WinForms/WindowsFormsHost in WPF app?

Postby AndyB » Fri Jun 09, 2017 11:55 am

I want to use CefGlue in my WPF app.
Most important for me is that the integrated browser does not crash or freeze my app.
What's your recommendation, use WPF control or WinForms/WindowsFormsHost ?
AndyB
Techie
 
Posts: 39
Joined: Sun Apr 16, 2017 3:00 pm

Re: Should i use WPF or WinForms/WindowsFormsHost in WPF app

Postby Czarek » Fri Jun 16, 2017 7:21 am

I think that WPF uses off-screen rendering and WinForms uses windowed rendering, so you can't use these interchangeably.
Maintainer of the CEF Python, PHP Desktop and CEF C API projects. My LinkedIn.
User avatar
Czarek
Virtuoso
 
Posts: 1927
Joined: Sun Nov 06, 2011 2:12 am

Re: Should i use WPF or WinForms/WindowsFormsHost in WPF app

Postby AndyB » Mon Jun 19, 2017 9:53 am

I can use the CefGlue WinForms or WPF control in my WPF application, both basically works.
The usage seems not so different, most of my code will be the same, it will try both version and see what works best.
AndyB
Techie
 
Posts: 39
Joined: Sun Apr 16, 2017 3:00 pm

Re: Should i use WPF or WinForms/WindowsFormsHost in WPF app

Postby fddima » Sat Jun 24, 2017 10:01 pm

If your WPF application doesnt expect transforms on control content (i.e. no useless control rotations), then stick to windowed / WinForms (WinFormsHosting is basically ok, can be bit tricky, because you also even doesnt need in WM_ERASE or similar stuff from host window over browser region). It works much more efficient in all senses. There is should be mandatory choice.
fddima
Master
 
Posts: 788
Joined: Tue Dec 07, 2010 6:10 am

Re: Should i use WPF or WinForms/WindowsFormsHost in WPF app

Postby AndyB » Wed Jul 05, 2017 2:36 pm

I have implemented now WinForms (windowed rendering) and WPF (offscreen) based on your sample projects.
WinForms works great so far, i published a beta version of my app today with this option, hope i get no issues reported back.

WPF basically works, but:

1) Tooltips are displayed a bit "shake".
I think because in the sample, each change of the tooltip adds an additional event handler to _tooltipTimer.Tick.
After changing this it works fine.

2) The context menu does not close when i click on a free area.
I worked around this by displaying a custom context menu.

3) No touch screen support.
That's a key requirement for me because my app is used on tablets (Microsoft Surface)
I have implemented a custom touch scroll, using Manipulation events and SendMouseWheelEvent, works ok for me.

4) No good HighDPI support, text looks too bold and blurry.
Maybe i take a look on this some time. CefSharp works fine on this point, so i probably look how they do the rendering.


Thank you and all others for this awesome project!
AndyB
Techie
 
Posts: 39
Joined: Sun Apr 16, 2017 3:00 pm

Re: Should i use WPF or WinForms/WindowsFormsHost in WPF app

Postby fddima » Wed Jul 05, 2017 3:06 pm

AndyB wrote:I have implemented now WinForms (windowed rendering) and WPF (offscreen) based on your sample projects.
WinForms works great so far, i published a beta version of my app today with this option, hope i get no issues reported back.

WPF basically works, but:

1) Tooltips are displayed a bit "shake".
I think because in the sample, each change of the tooltip adds an additional event handler to _tooltipTimer.Tick.
After changing this it works fine.

2) The context menu does not close when i click on a free area.
I worked around this by displaying a custom context menu.

3) No touch screen support.
That's a key requirement for me because my app is used on tablets (Microsoft Surface)
I have implemented a custom touch scroll, using Manipulation events and SendMouseWheelEvent, works ok for me.

4) No good HighDPI support, text looks too bold and blurry.
Maybe i take a look on this some time. CefSharp works fine on this point, so i probably look how they do the rendering.


Thank you and all others for this awesome project!


CefGlue WPF OSR sample has been created from contribution of one of CefGlue user. It is very far from "just use" usage. So even bugs are exists. I'm use it only as OSR demo and some quick-tests. WPF also chosen... because it has been chosen in initial implementation. I.e. demo's goal is demo of OSR capabilities rather than ready to use WPF-centric control.

For WPF or WinForms control we need create "brand-new" implementations. For WinForms it is not very needed, because it is usually already covers many aspects internally, as you mentioned. Projects which i'm touch personally are far from standard UI apps, so even when i'm need UI control - project has own implementation which adjusted as it needed to best suit to whole project without worrying about unneeded feats. If someone want to create WPF and WinForms controls (i'm mean design it in first place - implementations are more trivial), then i'm like to accept this contributions. But from design point it is not very easy: control need CefClient and related things. CefSharp's way is based on interfaces, but i'm disallow this idea, because it is violates possible calls directions (you can see, that protected methods are called only by CEF, and public by client code in CefGlue). Also in CEF C++ headers all methods in handlers are public, but it is already considered as design error and they should be protected. And with interfaces we make possible to call this methods from both sides.

So... basically controls requires some concept and API. Also they should not hide CEF possibilities. For example control can introduce CefClientFactory and use CefClient provided by factory, but this is doesn't work well all times and with form designers to which some peoples stick forever. So... to effectively use CEF APIs - you need known CEF APIs. Due to nature of CEF - control can be work in same way as WinForm's WebBrowser work. When user has this knowledges - they usually are more advanced, and can accept more sophisticated APIs.

When peoples want easy-to-use control - i'm always suggest CefSharp actually. CefGlue is for peoples who more like access to nearly raw CEF API. Generally i'm started CefGlue in times when CefSharp doesn't cover even 90% of CEF API, and any addition requires CefSharp recompilation. And it that times it is also required custom CEF build... what was a pain (it was CEF1 times.) Now CefSharp is much easier in all senses: good/complete or nearly-complete CEF API coverage, has ready-to-use WPF (OSR-based) control has WinForms-based control? and has lot of samples which CefGlue misses and work on standard CEF builds (again - in past times it always required custom build, while CefGlue was aim to utilize standard builds without touching C++/CLI.)

So back to your notices:

1) Tooltips - i'm think it was bug initially and never noticed in first place.

2) The context menu: looks strange, but custom menus definitely should be a way to go.

3) OSR+touchscreen: CEF misses this, has PR #104 Touch processing for OSR, different API. But again, it will require event translation... which is not very easy to debug/make correct. Current sample doesn't uses WM_POINTER message for modern systems, so... So, again, in cases when you not needed OSR - good choice is windowed browser which do it internally and chrome team worry about such details.

4) No good HighDPI support, text looks too bold and blurry: i think sample code just doesn't do nothing about (starting from correct app.manifest), but OSR already has all required abilities to do it correctly (device scale factor should be provided by CefRenderHandler).
fddima
Master
 
Posts: 788
Joined: Tue Dec 07, 2010 6:10 am

Re: Should i use WPF or WinForms/WindowsFormsHost in WPF app

Postby AndyB » Wed Jul 05, 2017 4:28 pm

I switched from CefSharp to CefGlue because of some issues (occasional app crash, freeze, mouse wheel not working reliable).

After basically finished now with integrating CefGlue in my app.... i like the approach to not supply ready to use full featured, fully customizable controls, and to be close to the CEF api.
Finally it's "easy" to implement the custom app code by inheriting and changing CefApp, CefClient, CefLifeSpanHandler, CefLoadHandler, CefRequestHandler, CefDownloadHandler.....
No un-necessary code is executed, understanding of CEF is much better than with using an abstract "fancy" control, easier to fix something if an error happens.

Yes, there could be a bit more samples for CefGlue,
for ex. how to get a value back from a javascript function (XHR works good for me now, no need for potential "buggy" custom IPC implementation)
and a Quickstart/FAQ, for ex. "enable Microsoft.Windows.Common-Controls in the manifest" to get tooltips displayed, "check off Enable the Visual Studio hosting process" if you don't have a separate app for the child processes....

I think the problem with WPF/OSR is that using WinForms and WindowsFormsHost is easy and seems to work fine. No big motivation for developers to make it working perfect.
My experience when i had issues with the WPF version... "just use WinForms" is the most given answer.
AndyB
Techie
 
Posts: 39
Joined: Sun Apr 16, 2017 3:00 pm

Re: Should i use WPF or WinForms/WindowsFormsHost in WPF app

Postby fddima » Wed Jul 05, 2017 5:13 pm

Yep. Thanks for feedback.

AndyB wrote:for ex. how to get a value back from a javascript function (XHR works good for me now, no need for potential "buggy" custom IPC implementation)

There is always had been tricky / many ways to achieve same result.

(1) I'm not sure why you mention XHR here... Do you call JS from C# and want to get results back? Correct? Then you use XHR to notify caller that results are done? Main good thing in this way, is that you can use any renderer process without any specific enhancements. There is solid choice exactly because it is built on "standard" technologies as much as possible.

(2) I'm usually use other way for same: this requires extend renderer process (what are should be ok for you as i'm understand).
1. Write ExecuteScriptAsync() function on browser side which:
1.a. Uses browser.SendProcessMessage to send message in renderer with target (frame id) and script body (and some unique message id).
1.b. At renderer you handles this message, and then you find frame (you already has CefBrowser because IPC linked to browser, so you easily can get frame by it's ID or get main frame).
1.c. With frame now you can ready to execute script: You can get V8 context from frame, enter in it (not sure that entering needed at this stage, but from API usage it should be correct), execute script with CefV8Context::Eval (TryEval in CefGlue as i'm remember).
1.d. Convert result from CefV8Value to string, and use browser.SendProcessMessage to send reply back to browser. (Then clear all stuff that no more needed, for example call CefV8Value::Dispose on all objects during this process is mandatory, because: 1) in renderer process GC triggered extremely rarely due to lack of activity, 2) we should release all references to any CefV8Value objects when V8 context is released.
1.e. Handle message on browser side and provide script result to associated TaskCompletionSource with unique message id.

Second approach can be harder. But generally it is not harder that using XHR (and some parts like 1.a and 1.e actually similar / can be shared). But of course we need here working sample rather than step-by-step explanation each time which new users never can implement.

AndyB wrote:I think the problem with WPF/OSR is that using WinForms and WindowsFormsHost is easy and seems to work fine. No big motivation for developers to make it working perfect.
My experience when i had issues with the WPF version... "just use WinForms" is the most given answer.

WindowsFormsHost is not perfect itself, but solid choice. There is exist few situations when OSR is really needed: users want draw browser-generated content inside own graphical applications (like games) or automated operations. In all other cases within current CEF versions (i.e. when OSR is software rendered) - OSR becomes sub-optimal choice even if it is fits in WPF better. BTW, nothing prevent write WPF's control which will act like WindowsFormsHost but actually creates native windowed browser and properly position it on window. CefGlue's GTK demo doing exactly in this way (but need to be improved by some hacks/tricks - by GTK's weird nature). I'm personally always recommend use windowed browser, but peoples anyway choose OSR-based browsers which often bound to WPF (happens often with CefGlue's sample and with CefSharp). There is probably peoples think that WPF control is better suit to their WPF, while actually WindowsFormsHost+WinForms is are choice what should be tried in first place. Yep. Lack of documentation.
fddima
Master
 
Posts: 788
Joined: Tue Dec 07, 2010 6:10 am

Re: Should i use WPF or WinForms/WindowsFormsHost in WPF app

Postby AndyB » Thu Jul 06, 2017 9:31 am

Yes, i execute JavaScript code from VB.NET. I have about 10 web automation scripts to auto fill fields, click buttons and links...
I think you wrote somewhere in this forum that you recommend using XHR for communication between JavaScript and C#.
It took me some time to get this working, as with most things at the end it's not too difficult. A working sample probably would have saved me lot of time.
Your second approach sounds also to be a good solution. Yes, 1a "some unique message id" and 1e is very similar to the XHR way.

There is probably peoples think that WPF control is better suit to their WPF

I had some trouble with WinForms and WindowsFormsHost in CefSharp.
- mentioned app freezes which i figured out may be caused by my bad
- closing browser takes a few seconds, probably caused by the CefSharp WCF IPC communication.
If it works fine with CefGlue WinForms/WindowsFormsHost then i feel comfortable with this now.
AndyB
Techie
 
Posts: 39
Joined: Sun Apr 16, 2017 3:00 pm

Re: Should i use WPF or WinForms/WindowsFormsHost in WPF app

Postby fddima » Thu Jul 06, 2017 10:06 am

AndyB wrote:Yes, i execute JavaScript code from VB.NET. I have about 10 web automation scripts to auto fill fields, click buttons and links...
I think you wrote somewhere in this forum that you recommend using XHR for communication between JavaScript and C#.
It took me some time to get this working, as with most things at the end it's not too difficult. A working sample probably would have saved me lot of time.
Your second approach sounds also to be a good solution. Yes, 1a "some unique message id" and 1e is very similar to the XHR way.

XHR-way easier for beginners because they can completely ignore multi-process nature. So it is easier to debug/etc. There is really not very easy deal with multiple processes even if you know all tricks. Damn, i'm always forget all this tricks and should re-learn again when i'm needed: but it is much easier when you know what you want to find. :)

Also, in my previous posts there is was bit different times. Now (after late 2016), CefV8Context::Eval ignore any content security policy rules, but in past it was not, and this is was been unhandy in some situations. But CefFrame::ExecuteJavaScript ignores CSP rules all the times, so ExecuteJavaScript+XHR again was (and still) a solid pick. Also XHR do JS->browser marshalling with any data type, while another way makes it like JS->renderer->browser, and you are responsible to convert values. XHR calls should be logged by devtools also... can be handy.

Only one clear advantage of second way, is that it is allow build transparent marshaling for some runtime types, like JS promise and wrap it in some way (providing full functionality or provide only result to caller). // there just thinking out loud


AndyB wrote:
There is probably peoples think that WPF control is better suit to their WPF

I had some trouble with WinForms and WindowsFormsHost in CefSharp.
- mentioned app freezes which i figured out may be caused by my bad
- closing browser takes a few seconds, probably caused by the CefSharp WCF IPC communication.
If it works fine with CefGlue WinForms/WindowsFormsHost then i feel comfortable with this now.

I'm used CefGlue some years ago in WPF-based project with WinForms/WindowsFormsHost without problems. But chromium changed a lot, so... it is can be not only WCF IPC related issues. But integrating WinForms browser from CefGlue.WinForms project should be easy.

PS: VB.NET... ugh. Last time i'm stuck with it, and it is... something what i'm hate anyway. Too verbose syntax + some implicit conversions can make cry anyone.
fddima
Master
 
Posts: 788
Joined: Tue Dec 07, 2010 6:10 am

Next

Return to CefGlue Forum

Who is online

Users browsing this forum: No registered users and 18 guests