CEF closing/resizing issues inside a big application plugin - c++

I'm writing a plugin for a big x64 application in C++. I want the plugin to open a dialog and show a web view of my site.
I'm been able to use WKWebView in macOS and it works well. On Windows I'm evaluating CEF https://bitbucket.org/chromiumembedded/cef (please let me know of any alternative, ideally I would like it to be Webkit-based).
Let's say the application framework that is hosting my plugin has already created a window for my plugin and has it's own message loop, so I can only receive events in a sort of WindowProc. I can also get the HWND of the window.
My implementation is inspired by cefsimple example, because cefclient is way too complicated. I've implemented the subprocess architecture with the external executable and everything works fine until it's rendering the client area of the window. Then I have problems with closing the window (it crashes) and resizing the window interactively (the window frame is resized but the web view in the client area does not resize).
I've tried all possible combinations, but I've run out of ideas. Namely:
If I use CefRunMessageLoop() the web view is rendered correctly but the main application does not process the UI events like close window button. Resize does not work.
If I call CefDoMessageLoopWork() myself once in a while (from WindowProc) the web view is rendered correctly and it processes the close button, but it crashes. Resize does not work.
If I use settings.multi_threaded_message_loop = true the web view is rendered correctly and I can close the window without crash. The destructor of the window calls CefShutdown(). But if I try to reopen the window it crashes! Are CefInitialize and CefShutdown allowed to be called only once?
And resizing still does not work. I don't understand why in the cefsimple example resizing works and in my window it does not work.
Besides message processing issues, probably I'm not closing the browser correctly, any advice? Why is so complicated? WKWebView is so straighforward!

There is no error message, no stack trace, no source code, no OS/CEF version - I doubt this question can be answered.
I can only tell you how to close browser cleanly: call CefShutdown at the right time (see cefclient/cefsimple examples) and do not keep any references to CEF objects when calling shutdown.

Related

Intercepting Windows Messages from Webview2 (Edge/Chromium)

I have recently migrated a project of mine to WebView2 and the last part I can't figure out is how to intercept the Windows Messages for the webview. My code is very similar to webview/webview but I was unable to find help on their GitHub.
Previously, I was able to find the hWnd for the webview and use SetWindowSubclass to add my own wndproc to the webview. However, I've used Spy++ and tried SetWindowSubclass on all the windows that showed up there (see below) but none of them had any windows messages in my wndproc other than some window management ones I did not think were useful - The best I got was WM_PARENTYNOTIFY, but I am interested in WM_MOUSEMOVE and WM_NCHITTEST - neither of which I could find.
My goal is to create a borderless, draggable, resizeable WebView2 based app.
The problem is, that the real window that controls and gets all this input is in another process. You just see a window that shows the output in your process.
Look into Spy++. Everything below Chrome_WidgetWin_0 belongs to a new process (MSEDGEWEBVIEW2) and is not part of your process. So you can't subclass such a window with the normal techniques.
So if you want to subclass this window. You need to inject a new DLL into this new process. This DLL might subclass the real window. And this DLL might communicate with you hosting program via any IPC.

Some of the win32 api calls are not working during a remote desktop session

I have a modeless dialog which I would like to hide for a split second then take a screenshot, then show again. I have tried a few methods like moving the dialog off the screen using the MoveWindow() api call as well as the SetWindowPos() and even ShowWindow(SW_HIDE) none of these seem to be giving me the results I want because my dialog is still contained in the screenshot. If I launch solution during a non remote desktop session, my dialog hides, and it takes the screenshot perfectly. Is there something I am missing when it comes to remote desktop sessions and the win32 api calls? I have also tried using InvalidateRect() followed by UpdateWindow() and have tried RedrawWindow() to no avail. I am using ATL.

MFC: Best place to prevent a window from re-appearing from a Restore operation

When my application is minimized, and the application programmatically closes a child window, the state of the child window between my framework and MFC goes out of sync because MFC will not send a WM_SHOWWINDOW message when the application is minimized. I noticed that Qt had the same problem: https://codereview.qt-project.org/#/c/93410/
Things that I have tried:
Override OnShowWindow() -- if the states are out of sync, then I alter the BOOL parameter before passing it to the CDialog::OnShowWindow. But doing so does nothing. It is as if the BOOL parameter given to the override is read-only.
Handle WM_SHOWWINDOW in PreTranslateMessage -- this does not work because WM_SHOWWINDOW does not appear here.
I know I can check SW_PARENTOPENING to know when to look for out-of-sync problems and handle it, but I just don't know where is the best place to do it.
My current solution is to override OnShowWindow, check for SW_PARENTOPENING, then post a SW_HIDE. It works, but it feels like a waste because I should be able to prevent it from restoring entirely rather than defer it.
Summary:
Basically, I am just programmatically closing a window, say from a timer call, or user's remote command, or whatever, while the main application is minimized. The dialog will be temporarily hidden when minimized (the MFC framework will automatically call ShowWindow(SW_HIDE) but with an internal flag to re-open when the app is restored). If my program sends ShowWindow(SW_HIDE) now, this call will not be registered, and the window will be re-opened by MFC when the app is maximized. To my user, he/she has closed the window remotely and does not expect the window to re-appear, so I need to re-call my ignored ShowWindow(SW_HIDE) somehow when restoring the main app.

Simulate mouse click in background window

I'm trying to use SendMessage to post mouse clicks to a background window (Chrome), which works fine, but brings the window to front after every click. Is there any way to avoid that?
Before anyone says this is a duplicate question, please make sure that the other topic actually mentions not activating the target window, because I couldn't find any.
Update: aha, hiding the window does the trick, almost. It receives simulated mouse/keyboard events as intended, and doesn't show up on screen. However, I can just barely use my own mouse to navigate around the computer, and keyboard input is completely disrupted.
So my question is, how does sending messages to a window affect other applications? Since I'm not actually simulating mouse/keyboard events, shouldn't the other windows be completely oblivious to this?
Is it possibly related to the window calling SetCapture when it receives WM_LBUTTONDOWN? And how would I avoid that, other than hooking the API call (which would be very, very ugly for such a small task)?
The default handling provided by the system (via DefWindowProc) causes windows to come to the front (when clicked on) as a response to the WM_MOUSEACTIVATE message, not WM_LBUTTONDOWN.
The fact that Chrome comes to the front in response to WM_LBUTTONDOWN suggests that it's something Chrome is specifically doing, rather than default system behaviour that you might be able to prevent in some way.
The source code to Chrome is available; I suggest you have a look at it and see if it is indeed something Chrome is doing itself. If so, the only practical way you would be able to prevent it (short of compiling your own version of Chrome) is to inject code into Chrome's process and sub-class its main window procedure.

Qt question to fullscreen flash application

I am using Qt to develop an application and inside we have access to select flash streaming videos like youtube. Is there a way to programmaticly full screen the flash application without requiring interaction from the user?
I am using a "QWebView" control.
try calling showFullScreen for the window where your QWebView control is hosted.
void QWidget::showFullScreen ()
Shows the widget in full-screen
mode.
Calling this function only affects
windows.
To return from full-screen mode, call
showNormal().
I would say: locate the button for the fullscreen application on the page, and send a click using QEVent. Tricky, but might work.
If the button is inside the flash application, you will have difficulties to locate it but if you succeed, you can probably send the click to the flash application area.
You can always inject javascript from Qt into your QWebPage. If there is a javascript API for forcing the flash viewer to full screen, I do not know.