// UI elements can be accessed ONLY from UI thread.
// Main UI thread - it is WinForms's UI thread.
// CEF UI thread - it is DIFFERENT thread, when MultiThreadedMessageLoop enabled (default for windows, on other platform inaccessible).
// but now we at CEF IO thread!
// TODO: do not reuse CefClient - provide new CefClient object which will notify your's new browser form (PopupForm2).
// It can be constructed based on current CefClient, but better is provide CefClientFactory.
// I.e. for easy using just assume that you always need ONE CefClient (and dependend CefLifeSpanHandler) instances PER BROWSER. If you want share CefClient - then CefClient impls must dispatch events by actual CefBrowser / etc
// Also don't keep popupfeaturs, windowInfo and settings outside this method. Once this method returned -> this objects will be dispoed.
IntPtr handle = IntPtr.Zero;
DemoApp.MainSynchronizationContext.Send((s) =>
{
customPopUp = new PopupForm2(parentBrowser, popupFeatures, targetUrl, settings);
handle = customPopUp.GetWeBrowserControlHandle();
customPopUp.Show();
}, null);
Trace.Assert(handle != IntPtr.Zero);
windowInfo.SetAsChild(handle);
//windowInfo.SetAsChild(customPopUp.GetWeBrowserControlHandle(), new CefRectangle { X = 0, Y = 0, Width = customPopUp.Width, Height = customPopUp.Height });
// TODO: about same can be implemented without sync, via later reparenting browser's window in target control (when it will be done).
return false;
}
I attach complete fixed modified sample (also added DemoApp.MainSynchronizationContext, which set from MainViewImpl).
CefGlue project now doesn't provide any internal infrastructure, so some things probably unclear, but all of them not so hard.
And read my comments carefully for code (in this post, in code not all present).