/// <summary> /// Asynchronously wait for the Chromium widget window to be created for the given ChromiumWebBrowser, /// and when created hook into its Windows message loop. /// </summary> /// <param name="browser">The browser to intercept Windows messages for.</param> /// <param name="forwardAction">This action will be called whenever a Windows message is received.</param> internal static void SetupLoop(ChromiumWebBrowser browser, Action <Message> forwardAction) { Task.Factory.StartNew(() => { try { bool foundWidget = false; while (!foundWidget) { browser.Invoke((Action)(() => { IntPtr chromeWidgetHostHandle; if (ChromeWidgetHandleFinder.TryFindHandle(browser, out chromeWidgetHostHandle)) { foundWidget = true; new ChromeWidgetMessageInterceptor(browser, chromeWidgetHostHandle, forwardAction); } else { // Chrome hasn't yet set up its message-loop window. Thread.Sleep(10); } })); } } catch { // Errors are likely to occur if browser is disposed, and no good way to check from another thread } }); }
/// <summary> /// Chrome's message-loop Window isn't created synchronously, so this may not find it. /// If so, you need to wait and try again later. /// </summary> public static bool TryFindHandle(ChromiumWebBrowser browser, out IntPtr chromeWidgetHostHandle) { var browserHandle = browser.Handle; var windowHandleInfo = new ChromeWidgetHandleFinder(browserHandle); const string chromeWidgetHostClassName = "Chrome_RenderWidgetHostHWND"; chromeWidgetHostHandle = windowHandleInfo.FindDescendantByClassName(chromeWidgetHostClassName); return(chromeWidgetHostHandle != IntPtr.Zero); }