// Copyright © 2010 The CefSharp Authors. All rights reserved. // // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using System.Threading.Tasks; using System.Windows.Forms; using CefSharp.Example; using CefSharp.Example.Callback; using CefSharp.Example.Handlers; using CefSharp.WinForms.Host; namespace CefSharp.WinForms.Example { public partial class BrowserForm : Form { private const string DefaultUrlForAddedTabs = "https://www.google.com"; // Default to a small increment: private const double ZoomIncrement = 0.10; private bool multiThreadedMessageLoopEnabled; public BrowserForm(bool multiThreadedMessageLoopEnabled) { InitializeComponent(); var bitness = RuntimeInformation.ProcessArchitecture.ToString().ToLowerInvariant(); Text = "CefSharp.WinForms.Example - " + bitness; WindowState = FormWindowState.Maximized; Load += BrowserFormLoad; //Only perform layout when control has completly finished resizing ResizeBegin += (s, e) => SuspendLayout(); ResizeEnd += (s, e) => ResumeLayout(true); this.multiThreadedMessageLoopEnabled = multiThreadedMessageLoopEnabled; } public IContainer Components { get { if (components == null) { components = new Container(); } return components; } } private void BrowserFormLoad(object sender, EventArgs e) { AddTab(CefExample.DefaultUrl); } /// /// Used to add a Popup browser as a Tab /// /// public void AddTab(ChromiumHostControl browserHostControl, string url) { browserTabControl.SuspendLayout(); var browser = new BrowserTabUserControl(browserHostControl) { Dock = DockStyle.Fill, Bounds = browserTabControl.Bounds }; var tabPage = new TabPage(url) { Dock = DockStyle.Fill }; tabPage.Controls.Add(browser); browserTabControl.TabPages.Add(tabPage); //Make newly created tab active browserTabControl.SelectedTab = tabPage; browserTabControl.ResumeLayout(true); } private void AddTab(string url, int? insertIndex = null) { browserTabControl.SuspendLayout(); var browser = new BrowserTabUserControl(AddTab, url, multiThreadedMessageLoopEnabled) { Dock = DockStyle.Fill, Bounds = browserTabControl.Bounds }; var tabPage = new TabPage(url) { Dock = DockStyle.Fill }; //This call isn't required for the sample to work. //It's sole purpose is to demonstrate that #553 has been resolved. browser.CreateControl(); tabPage.Controls.Add(browser); if (insertIndex == null) { browserTabControl.TabPages.Add(tabPage); } else { browserTabControl.TabPages.Insert(insertIndex.Value, tabPage); } //Make newly created tab active browserTabControl.SelectedTab = tabPage; browserTabControl.ResumeLayout(true); } private void ExitMenuItemClick(object sender, EventArgs e) { ExitApplication(); } private void ExitApplication() { Close(); } private void AboutToolStripMenuItemClick(object sender, EventArgs e) { new AboutBox().ShowDialog(); } public void RemoveTab(ChromiumHostControl ctrl) { if (!ctrl.IsDisposed) { var tabPage = ctrl.GetParentOfType(); if(tabPage == null) { throw new Exception("Unable to find parent TabPage"); } browserTabControl.TabPages.Remove(tabPage); } } private void FindMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { control.ShowFind(); } } private void CopySourceToClipBoardAsyncClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { control.CopySourceToClipBoardAsync(); } } private BrowserTabUserControl GetCurrentTabControl() { if (browserTabControl.SelectedIndex == -1) { return null; } var tabPage = browserTabControl.Controls[browserTabControl.SelectedIndex]; var control = tabPage.Controls[0] as BrowserTabUserControl; return control; } private void NewTabToolStripMenuItemClick(object sender, EventArgs e) { AddTab(DefaultUrlForAddedTabs); } private void CloseTabToolStripMenuItemClick(object sender, EventArgs e) { if (browserTabControl.TabPages.Count == 0) { return; } var currentIndex = browserTabControl.SelectedIndex; var tabPage = browserTabControl.TabPages[currentIndex]; var control = GetCurrentTabControl(); if (control != null && !control.IsDisposed) { control.Dispose(); } browserTabControl.TabPages.Remove(tabPage); tabPage.Dispose(); browserTabControl.SelectedIndex = currentIndex - 1; if (browserTabControl.TabPages.Count == 0) { ExitApplication(); } } private void UndoMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { control.Browser.Undo(); } } private void RedoMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { control.Browser.Redo(); } } private void CutMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { control.Browser.Cut(); } } private void CopyMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { control.Browser.Copy(); } } private void PasteMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { control.Browser.Paste(); } } private void DeleteMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { control.Browser.Delete(); } } private void SelectAllMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { control.Browser.SelectAll(); } } private void PrintToolStripMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { control.Browser.Print(); } } private async void ShowDevToolsMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { var isDevToolsOpen = await control.CheckIfDevToolsIsOpenAsync(); if (!isDevToolsOpen) { control.Browser.ShowDevTools(); } } } private async void ShowDevToolsDockedMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { var isDevToolsOpen = await control.CheckIfDevToolsIsOpenAsync(); if (!isDevToolsOpen) { var chromiumWebBrowser = control.Browser as ChromiumWebBrowser; if (chromiumWebBrowser != null && chromiumWebBrowser.LifeSpanHandler != null) { control.ShowDevToolsDocked(); } } } } private async void CloseDevToolsMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { //Check if DevTools is open before closing, this isn't strictly required //If DevTools isn't open and you call CloseDevTools it's a No-Op, so prefectly //safe to call without checking var isDevToolsOpen = await control.CheckIfDevToolsIsOpenAsync(); if (isDevToolsOpen) { control.Browser.CloseDevTools(); } } } private void ZoomInToolStripMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { var task = control.Browser.GetZoomLevelAsync(); task.ContinueWith(previous => { if (previous.Status == TaskStatus.RanToCompletion) { var currentLevel = previous.Result; control.Browser.SetZoomLevel(currentLevel + ZoomIncrement); } else { throw new InvalidOperationException("Unexpected failure of calling CEF->GetZoomLevelAsync", previous.Exception); } }, TaskContinuationOptions.ExecuteSynchronously); } } private void ZoomOutToolStripMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { var task = control.Browser.GetZoomLevelAsync(); task.ContinueWith(previous => { if (previous.Status == TaskStatus.RanToCompletion) { var currentLevel = previous.Result; control.Browser.SetZoomLevel(currentLevel - ZoomIncrement); } else { throw new InvalidOperationException("Unexpected failure of calling CEF->GetZoomLevelAsync", previous.Exception); } }, TaskContinuationOptions.ExecuteSynchronously); } } private void CurrentZoomLevelToolStripMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { var task = control.Browser.GetZoomLevelAsync(); task.ContinueWith(previous => { if (previous.Status == TaskStatus.RanToCompletion) { var currentLevel = previous.Result; MessageBox.Show("Current ZoomLevel: " + currentLevel.ToString()); } else { MessageBox.Show("Unexpected failure of calling CEF->GetZoomLevelAsync: " + previous.Exception.ToString()); } }, TaskContinuationOptions.HideScheduler); } } private void DoesActiveElementAcceptTextInputToolStripMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { var frame = control.Browser.GetFocusedFrame(); //Execute extension method frame.ActiveElementAcceptsTextInput().ContinueWith(task => { string message; var icon = MessageBoxIcon.Information; if (task.Exception == null) { var isText = task.Result; message = string.Format("The active element is{0}a text entry element.", isText ? " " : " not "); } else { message = string.Format("Script evaluation failed. {0}", task.Exception.Message); icon = MessageBoxIcon.Error; } MessageBox.Show(message, "Does active element accept text input", MessageBoxButtons.OK, icon); }); } } private void DoesElementWithIdExistToolStripMenuItemClick(object sender, EventArgs e) { // This is the main thread, it's safe to create and manipulate form // UI controls. var dialog = new InputBox { Instructions = "Enter an element ID to find.", Title = "Find an element with an ID" }; dialog.OnEvaluate += (senderDlg, eDlg) => { // This is also the main thread. var control = GetCurrentTabControl(); if (control != null) { var frame = control.Browser.GetFocusedFrame(); //Execute extension method frame.ElementWithIdExists(dialog.Value).ContinueWith(task => { // Now we're not on the main thread, perhaps the // Cef UI thread. It's not safe to work with // form UI controls or to block this thread. // Queue up a delegate to be executed on the // main thread. BeginInvoke(new Action(() => { string message; if (task.Exception == null) { message = task.Result.ToString(); } else { message = string.Format("Script evaluation failed. {0}", task.Exception.Message); } dialog.Result = message; })); }); } }; dialog.Show(this); } private void GoToDemoPageToolStripMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { control.Browser.LoadUrl("custom://cefsharp/ScriptedMethodsTest.html"); } } private void InjectJavascriptCodeToolStripMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { var frame = control.Browser.GetFocusedFrame(); //Execute extension method frame.ListenForEvent("test-button", "click"); } } private async void PrintToPdfToolStripMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { var dialog = new SaveFileDialog { DefaultExt = ".pdf", Filter = "Pdf documents (.pdf)|*.pdf" }; if (dialog.ShowDialog() == DialogResult.OK) { var success = await control.Browser.PrintToPdfAsync(dialog.FileName, new PdfPrintSettings { MarginType = CefPdfPrintMarginType.Custom, MarginBottom = 10, MarginTop = 0, MarginLeft = 20, MarginRight = 10 }); if (success) { MessageBox.Show("Pdf was saved to " + dialog.FileName); } else { MessageBox.Show("Unable to save Pdf, check you have write permissions to " + dialog.FileName); } } } } private void OpenDataUrlToolStripMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { const string html = "Test

Html Encoded in URL!

"; control.Browser.LoadHtml(html, false); } } private void OpenHttpBinOrgToolStripMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { control.Browser.LoadUrl("https://httpbin.org/"); } } private void RunFileDialogToolStripMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { control.Browser.GetBrowserHost().RunFileDialog(CefFileDialogMode.Open, "Open", null, new List { "*.*" }, new RunFileDialogCallback()); } } private void JavascriptBindingStressTestToolStripMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if (control != null) { control.Browser.LoadUrl(CefExample.BindingTestUrl); control.Browser.LoadingStateChanged += (o, args) => { if (args.IsLoading == false) { Task.Delay(10000).ContinueWith(t => { if (control.Browser != null) { control.Browser.Reload(); } }); } }; } } private void HideScrollbarsToolStripMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); _ = control?.HideScrollbarsAsync(); } private async void TakeScreenShotMenuItemClick(object sender, EventArgs e) { var control = GetCurrentTabControl(); if(control == null) { return; } var chromiumWebBrowser = (ChromiumWebBrowser)control.Browser; var contentSize = await chromiumWebBrowser.GetContentSizeAsync(); //Capture current scrollable area var viewPort = new DevTools.Page.Viewport { Width = contentSize.Width, Height = contentSize.Height, }; var data = await chromiumWebBrowser.CaptureScreenshotAsync(viewPort: viewPort, captureBeyondViewport: true); // Make a file to save it to (e.g. C:\Users\[user]\Desktop\CefSharp screenshot.png) var screenshotPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "CefSharp screenshot" + DateTime.Now.Ticks + ".png"); File.WriteAllBytes(screenshotPath, data); // Tell Windows to launch the saved image. Process.Start(new ProcessStartInfo(screenshotPath) { // UseShellExecute is false by default on .NET Core. UseShellExecute = true }); } } }