下一篇CefSharp 集成谷歌浏览器详解(五)–官网示例解析2 winform 捕获ChromiumWebBrowser消息

来源:互联网 发布:windows自带编程软件 编辑:程序博客网 时间:2024/06/10 08:11

捕捉浏览器消息事件是为了下拉菜单的点击事件不被浏览器吞掉。如果被吞掉下拉菜单就不会自动缩回

在BrowserInitializedChanged注册事件。
在BrowserTabUserControl里面

browser.IsBrowserInitializedChanged += OnIsBrowserInitializedChanged;private void OnIsBrowserInitializedChanged(object sender, IsBrowserInitializedChangedEventArgs args)    {        if (args.IsBrowserInitialized)        {            //Get the underlying browser host wrapper            var browserHost = Browser.GetBrowser().GetHost();            var requestContext = browserHost.RequestContext;            string errorMessage;            // Browser must be initialized before getting/setting preferences            var success = requestContext.SetPreference("enable_do_not_track", true, out errorMessage);            if(!success)            {                this.InvokeOnUiThreadIfRequired(() => MessageBox.Show("Unable to set preference enable_do_not_track errorMessage: " + errorMessage));            }            //Example of disable spellchecking            //success = requestContext.SetPreference("browser.enable_spellchecking", false, out errorMessage);            var preferences = requestContext.GetAllPreferences(true);            var doNotTrack = (bool)preferences["enable_do_not_track"];            //Use this to check that settings preferences are working in your code            //success = requestContext.SetPreference("webkit.webprefs.minimum_font_size", 24, out errorMessage);            //If we're using CefSetting.MultiThreadedMessageLoop (the default) then to hook the message pump,            // which running in a different thread we have to use a NativeWindow            if (multiThreadedMessageLoopEnabled)            {                Task.Run(() =>                {                    try                    {                        while (true)                        {                            IntPtr chromeWidgetHostHandle;                            if                            (ChromeWidgetHandleFinder.TryFindHandle(browserHandle, out chromeWidgetHostHandle))                            {                                messageInterceptor = new ChromeWidgetMessageInterceptor((Control)Browser, chromeWidgetHostHandle, message =>                                {                                    const int WM_MOUSEACTIVATE = 0x0021;                                    const int WM_NCLBUTTONDOWN = 0x00A1;                                    const int WM_LBUTTONDOWN = 0x0201;                                    if (message.Msg == WM_MOUSEACTIVATE)                                    {                                        // The default processing of WM_MOUSEACTIVATE results in MA_NOACTIVATE,                                        // and the subsequent mouse click is eaten by Chrome.                                        // This means any .NET ToolStrip or ContextMenuStrip does not get closed.                                        // By posting a WM_NCLBUTTONDOWN message to a harmless co-ordinate of the                                        // top-level window, we rely on the ToolStripManager's message handling                                        // to close any open dropdowns:                                        // http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/ToolStripManager.cs,1249                                        var topLevelWindowHandle = message.WParam;                                        PostMessage(topLevelWindowHandle, WM_NCLBUTTONDOWN, IntPtr.Zero, IntPtr.Zero);                                    }                                    //Forward mouse button down message to browser control                                    //else if(message.Msg == WM_LBUTTONDOWN)                                    //{                                    //    PostMessage(browserHandle, WM_LBUTTONDOWN, message.WParam, message.LParam);                                    //}                                    // The ChromiumWebBrowserControl does not fire MouseEnter/Move/Leave events, because Chromium handles these.                                    // However we can hook into Chromium's messaging window to receive the events.                                    //                                    //const int WM_MOUSEMOVE = 0x0200;                                    //const int WM_MOUSELEAVE = 0x02A3;                                    //                                    //switch (message.Msg) {                                    //    case WM_MOUSEMOVE:                                    //        Console.WriteLine("WM_MOUSEMOVE");                                    //        break;                                    //    case WM_MOUSELEAVE:                                    //        Console.WriteLine("WM_MOUSELEAVE");                                    //        break;                                    //}                                });                                break;                            }                            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                    }                });            }        }if                       (ChromeWidgetHandleFinder.TryFindHandle(browserHandle, out chromeWidgetHostHandle))

这句就是用windows本地的API查寻浏览器点击的消息句柄。如果有就执行if里面的逻辑POST一个鼠标点击消息到windwos form让菜单自动缩回。

看看查找浏览器消息句柄

private static bool EnumWindow(IntPtr hWnd, IntPtr lParam)    {        const string chromeWidgetHostClassName = "Chrome_RenderWidgetHostHWND";        var buffer = new StringBuilder(128);        GetClassName(hWnd, buffer, buffer.Capacity);        if (buffer.ToString() == chromeWidgetHostClassName)        {            var gcHandle = GCHandle.FromIntPtr(lParam);            var classDetails = (ClassDetails)gcHandle.Target;            classDetails.DescendantFound = hWnd;            return false;        }        return true;    }

这个提一下,Chrome_RenderWidgetHostHWND是谷歌浏览器在windows 里面的特征字符串,在winfrom里面每一个控件都是一个windows,所以用遍历子控件的方式查找浏览器的消息句柄。

上一篇CefSharp 集成谷歌浏览器详解(四)–官网示例解析3 RegisterJsObject CefSharpSchemeHandlerFactory

官方示例比较复杂的就讲完啦。

阅读全文
0 0