Creating two or more CEF browser windows - c++

I have been suffering for two weeks, please help me:
And I use the built-in CEF example - "cefsimple" - it works fine: https://bitbucket.org/chromiumembedded/cef/src/master/tests/cefsimple/?at=master
The "cefsimple" example creates a browser window and opens the specified URL in it.
But as soon as I add another browser window creation feature:
CefBrowserHost::CreateBrowser(window_info, my_browser_handler_, "google.com", browser_settings, nullptr, nullptr);
That's where the problems happen.
The second browser window is being created, BUT a problem occurs - the two created windows seem to blink constantly, as if switching between each other very quickly.
I tried the advice - install:
window_info.ex_style = WS_EX_NOACTIVATE;
But it doesn't help at all.
Maybe someone has created more than one window browser in CEF ? What am I doing wrong ?

I've encounter this problem recently, and this may help you.
In your native window proc, process WM_SETFOCUS with:
if (!::GetFocus())
{
// set cef focus;
}
Without call ::GetFocus(), two cef windows will blink constantly.

Related

Load URL in Default Browser and Bring to Front

I have a fullscreen application written in c++ using straight winapi. The application contains an embedded web browser (using CEF, but I don't think that matters in this case). I am currently intercepting any popup windows as the result of clicking on a link and opening them in the systems default browser using ShellExecute. However, on many of our test systems the browser window is displayed behind my application window, which is a problem since my window covers up the task bar so the user has no indication that a new window has been displayed.
I've read everything I can find on this site and others and have not been able to find a single solution that works:
Using ShellExecuteEx to get the process handle, then using the process handle to find the window handle and bringing it to the front - Many times the process handle is NULL, which appears to be related to the browser opening a new tab in an existing window. In addition, if Edge is the default browser then the process handle always seems to be NULL.
Using ShellExecute (or Ex) then finding the new window based on the name - I have no idea what the name of the window will be. It's based on the content that is opened, which may be many different things depending on the link the user clicked (html, pdf, etc).
Attempting to figure out the path to the default browser and then launching it using CreateProcess - So far I haven't had any luck with this if Edge is the default (since apparently Edge is a "modern" application that doesn't have an executable that can be launched with CreateProcess). If anyone knows how to make this work I could see this actually being a decent solution.
So right now I'm heading down a path of enumerating all of the windows before and after launching the browser and attempting to figure out which one is the correct one to bring forward. I'm envisioning all sorts of issues that could possibly occur (a tab opening on an existing browser for instance). If anyone has any solution to the issue I would appreciate it!
Edit: Code I'm using for ShellExecuteEx:
SHELLEXECUTEINFO sxi = { 0 };
sxi.cbSize = sizeof( sxi );
sxi.nShow = SW_NORMAL;
sxi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NOASYNC | SEE_MASK_WAITFORINPUTIDLE;
sxi.lpVerb = _T( "open" );
sxi.lpFile = url;
if( ShellExecuteEx( &sxi ) )

CEF closing/resizing issues inside a big application plugin

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.

How do I force my app to come to the front and take focus?

I'm working on an application that happens to be the bootstrap for an installer that I'm also working on. The application makes a few MSI calls to get information that I need for putting together the wizard that is my application's main window, which causes a progress window to open while the info is being gathered and then go away once that's done. Then the wizard is set up and launched. My problem is that the wizard (derived from CPropertySheet) does not want to come to the front and be the active application without me adding in some calls to do so.
I've solved the problem of bringing it to the front with the following code in my OnInitDialog() method:
SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); // force window to top
SetWindowPos(&wndNoTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); // lose the topmost status that the previous line gave us
My problem is that I still haven't figured out how to make the window self-activate (i.e., make itself be the one that has the focus). SetFocus() won't work in this context. I need something that will force the window to the top of the Z-order and activate it, preferably in as few calls as possible.
My guess is that the progress window opened at the beginning by the MSI calls is causing the main window to screw up, but I have no way to prevent that window from appearing. Also, it wouldn't make sense to hide it, because it lets the user know what's going on before the main window arrives.
Andrew isn't completely correct. Windows does try really hard to stop you from stealing focus, but it is possible using the folowing method.
Attach to the thread of the window that currently has focus.
Bring your window into focus.
Detach from the thread.
And the code for that would go something like this:
DWORD dwCurrentThread = GetCurrentThreadId();
DWORD dwFGThread = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
AttachThreadInput(dwCurrentThread, dwFGThread, TRUE);
// Possible actions you may wan to bring the window into focus.
SetForegroundWindow(hwnd);
SetCapture(hwnd);
SetFocus(hwnd);
SetActiveWindow(hwnd);
EnableWindow(hwnd, TRUE);
AttachThreadInput(dwCurrentThread, dwFGThread, FALSE);
You may or may not need to have to run your program with administrative privileges for this to work, but I've used this code personally and it has go the job done.
You can't steal focus. Period.
See this Old New Thing article:
https://blogs.msdn.microsoft.com/oldnewthing/20090220-00/?p=19083
doesn't ShowWindow(youwindow,SW_SHOWNORMAL) work?
-don
You will find that BringWindowToTop or SetForegroundWindow have requirements that must be met before the window will actually be forced to the front over all other windows (applications). If these aren't met, Windows will only flash the application's icon in the taskbar. This article presents a way around that but as 1800 INFORMATION points out, it is not recommended. I guess you'll just have to accept it.
There ARE good reasons for an app to 'steal' focus. My application is a server loading many driver DLLs. Another application, connecting to the server, has a button that sends a message to the server to show detail information in one of those DLLs (owned by the server, not the client app) for convenience. Unfortunately, this popped open window is usually buried under multiple windows.

Programmatically navigating to the Windows Mobile home screen

We have an application that downloads some files in the background. Our application pops up when an Internet connection is made, and after prompting the user to accept the downloads, we'd like to switch back to the home screen while we do our stuff.
We can't work out how to do to this. We can emulate pressing "back" a few times, which sometimes works, but where you end up depends on what the user was doing when the Internet connection happened.
So, can someone provide pointers to how to do this?
Thanks.
Paul.
Can you try setting the today screen as the foreground window?
HWND hWnd = FindWindow(_T("DesktopExplorerWindow"), _T("Desktop"));
SetForegroundWindow(hWnd);
Why don't you simply hide your app?
Using a Notification shell object instead of popping up a full screen window might be a better alternative. Details here.

How do I set the owner of a FilterGraph renderer?

I have a CView which I would like to host a DirectShow renderer.
I did not write the original code, I am simply cleaning up and moving the code to VS2005. This necessitated an upgrade of certain third party tools and so I'm trying to change the code a bit without having a full understanding of DX/DirectShow.
The problem is that my app hangs when I run
hr = gcap.pFg->QueryInterface(IID_IVideoWindow, (void **)&gcap.pVW);
[trimmed some code]
gcap.pVW->put_Owner((OAHWND) m_pDockWnd->GetSafeHwnd()); // We own the window now
m_pDockWnd is the CView. I can do this when in preview mode, but not when in capture mode. In capture mode, it hangs the app.
If I don't own the render window, there is no problem (although the capture window is owned by the desktop, which won't work for me).
Also, the capture window shows a busy cursor when it is owned by the desktop--probably it's actually not working then either, but it's at least not hanging the app. By hang I mean that the app does not respond to user input, but background threads continue to run.
Update: We were using an old version of DirectX (Aug '06). I compiled/linked against the DirectShow stuff packaged with the Vista SDK and .... no dice.
I've got a resolution for this.
The video stream as getting started from a thread without a message pump, this was causing the video window to become non-responsive. (I guess XP was more tolerant of this, maybe the new display driver model in Vista mucked it up.) Anyways, once I did a SendMessage to the main app window and started the video capture from there, everything seems to work!