Skip to content

Commit

Permalink
Add Minimal WinForms Designer Support (#1946)
Browse files Browse the repository at this point in the history
* Fixed designer support
* Adapted to feedback
* Revert "Adapted to feedback"
This reverts commit a1541c9.
* Adapted to feedback
* Added missing summary
  • Loading branch information
merceyz authored and amaitland committed Feb 16, 2017
1 parent 55f2c82 commit e844bed
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 20 deletions.
1 change: 1 addition & 0 deletions CefSharp.Core/CefSharp.Core.vcxproj
Expand Up @@ -139,6 +139,7 @@
<MapExports>false</MapExports>
<KeyFile>$(LinkKeyFile)</KeyFile>
<AdditionalOptions>/ignore:4099 %(AdditionalOptions)</AdditionalOptions>
<DelayLoadDLLs>libcef.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
Expand Down
143 changes: 123 additions & 20 deletions CefSharp.WinForms/ChromiumWebBrowser.cs
Expand Up @@ -2,11 +2,12 @@
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

using System;
using System.Windows.Forms;
using CefSharp.Internals;
using CefSharp.ModelBinding;
using CefSharp.WinForms.Internals;
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Forms;

namespace CefSharp.WinForms
{
Expand All @@ -30,12 +31,22 @@ public class ChromiumWebBrowser : Control, IWebBrowserInternal, IWinFormsWebBrow
/// The browser
/// </summary>
private IBrowser browser;
/// <summary>
/// A flag that indicates whether or not the designer is active
/// NOTE: DesignMode becomes false by the time we get to the destructor/dispose so it gets stored here
/// </summary>
private bool designMode;
/// <summary>
/// A flag that indicates whether or not Initialize() has been called
/// </summary>
private bool initialized;

/// <summary>
/// Set to true while handing an activating WM_ACTIVATE message.
/// MUST ONLY be cleared by DefaultFocusHandler.
/// </summary>
/// <value><c>true</c> if this instance is activating; otherwise, <c>false</c>.</value>
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public bool IsActivating { get; set; }

/// <summary>
Expand All @@ -54,11 +65,13 @@ public class ChromiumWebBrowser : Control, IWebBrowserInternal, IWinFormsWebBrow
/// <value><c>true</c> if this instance is loading; otherwise, <c>false</c>.</value>
/// <remarks>In the WPF control, this property is implemented as a Dependency Property and fully supports data
/// binding.</remarks>
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public bool IsLoading { get; private set; }
/// <summary>
/// The text that will be displayed as a ToolTip
/// </summary>
/// <value>The tooltip text.</value>
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public string TooltipText { get; private set; }
/// <summary>
/// The address (URL) which the browser control is currently displaying.
Expand All @@ -67,6 +80,7 @@ public class ChromiumWebBrowser : Control, IWebBrowserInternal, IWinFormsWebBrow
/// <value>The address.</value>
/// <remarks>In the WPF control, this property is implemented as a Dependency Property and fully supports data
/// binding.</remarks>
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public string Address { get; private set; }

/// <summary>
Expand Down Expand Up @@ -233,20 +247,23 @@ public class ChromiumWebBrowser : Control, IWebBrowserInternal, IWinFormsWebBrow
/// <value><c>true</c> if this instance can go forward; otherwise, <c>false</c>.</value>
/// <remarks>In the WPF control, this property is implemented as a Dependency Property and fully supports data
/// binding.</remarks>
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public bool CanGoForward { get; private set; }
/// <summary>
/// A flag that indicates whether the state of the control current supports the GoBack action (true) or not (false).
/// </summary>
/// <value><c>true</c> if this instance can go back; otherwise, <c>false</c>.</value>
/// <remarks>In the WPF control, this property is implemented as a Dependency Property and fully supports data
/// binding.</remarks>
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public bool CanGoBack { get; private set; }
/// <summary>
/// A flag that indicates whether the WebBrowser is initialized (true) or not (false).
/// </summary>
/// <value><c>true</c> if this instance is browser initialized; otherwise, <c>false</c>.</value>
/// <remarks>In the WPF control, this property is implemented as a Dependency Property and fully supports data
/// binding.</remarks>
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public bool IsBrowserInitialized { get; private set; }

/// <summary>
Expand All @@ -270,28 +287,90 @@ private static void OnApplicationExit(object sender, EventArgs e)
Cef.Shutdown();
}

/// <summary>
/// Initializes a new instance of the <see cref="ChromiumWebBrowser"/> class.
/// NOTE: Should only be used by the designer
/// </summary>
[Obsolete("Should only be used by the designer")]
public ChromiumWebBrowser()
{

}

/// <summary>
/// Initializes a new instance of the <see cref="ChromiumWebBrowser"/> class.
/// </summary>
/// <param name="address">The address.</param>
/// <exception cref="System.InvalidOperationException">Cef::Initialize() failed</exception>
public ChromiumWebBrowser(string address)
{
if (!Cef.IsInitialized && !Cef.Initialize())
Dock = DockStyle.Fill;
Address = address;
InitializeBrowser();
}

[MethodImpl(MethodImplOptions.NoInlining)]
private void InitializeBrowser()
{
if (!initialized)
{
throw new InvalidOperationException("Cef::Initialize() failed");
}
if (!Cef.IsInitialized && !Cef.Initialize())
{
throw new InvalidOperationException("Cef::Initialize() failed");
}

Cef.AddDisposable(this);
Address = address;
Cef.AddDisposable(this);

Dock = DockStyle.Fill;
if (FocusHandler == null)
{
FocusHandler = new DefaultFocusHandler(this);
}

FocusHandler = new DefaultFocusHandler(this);
ResourceHandlerFactory = new DefaultResourceHandlerFactory();
BrowserSettings = new BrowserSettings();
if (ResourceHandlerFactory == null)
{
ResourceHandlerFactory = new DefaultResourceHandlerFactory();
}

managedCefBrowserAdapter = new ManagedCefBrowserAdapter(this, false);
if (BrowserSettings == null)
{
BrowserSettings = new BrowserSettings();
}

managedCefBrowserAdapter = new ManagedCefBrowserAdapter(this, false);

initialized = true;
}
}

/// <summary>
/// Finalizes an instance of the <see cref="ChromiumWebBrowser"/> class.
/// </summary>
~ChromiumWebBrowser()
{
if (designMode)
{
base.Dispose(false);
}
else
{
Dispose(false);
}
}

/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public new void Dispose()
{
if (designMode)
{
base.Dispose(true);
}
else
{
Dispose(true);
}

GC.SuppressFinalize(this);
}

/// <summary>
Expand Down Expand Up @@ -375,6 +454,8 @@ public void RegisterJsObject(string name, object objectToBind, BindingOptions op
throw new Exception("Browser is already initialized. RegisterJsObject must be" +
"called before the underlying CEF browser is created.");
}

InitializeBrowser();

//Enable WCF if not already enabled
CefSharpSettings.WcfEnabled = true;
Expand All @@ -400,6 +481,9 @@ public void RegisterAsyncJsObject(string name, object objectToBind, BindingOptio
throw new Exception("Browser is already initialized. RegisterJsObject must be" +
"called before the underlying CEF browser is created.");
}

InitializeBrowser();

managedCefBrowserAdapter.RegisterAsyncJsObject(name, objectToBind, options);
}

Expand All @@ -409,14 +493,30 @@ public void RegisterAsyncJsObject(string name, object objectToBind, BindingOptio
/// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
protected override void OnHandleCreated(EventArgs e)
{
if (((IWebBrowserInternal)this).HasParent == false)
designMode = DesignMode;

if (!designMode)
{
managedCefBrowserAdapter.CreateBrowser(BrowserSettings, RequestContext, Handle, Address);
InitializeBrowser();

// NOTE: Had to move the code out of this function otherwise the designer would crash
CreateBrowser();

ResizeBrowser();
}

base.OnHandleCreated(e);
}

[MethodImpl(MethodImplOptions.NoInlining)]
private void CreateBrowser()
{
if (((IWebBrowserInternal)this).HasParent == false)
{
managedCefBrowserAdapter.CreateBrowser(BrowserSettings, RequestContext, Handle, Address);
}
}

/// <summary>
/// Called after browser created.
/// </summary>
Expand Down Expand Up @@ -609,8 +709,11 @@ public override bool Focused
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);

ResizeBrowser();

if (!designMode && initialized)
{
ResizeBrowser();
}
}

/// <summary>
Expand Down Expand Up @@ -666,14 +769,14 @@ protected override bool IsInputKey(Keys keyData)
case Keys.Up:
case Keys.Down:
case Keys.Tab:
{
{
return true;
}
case Keys.Shift | Keys.Right:
case Keys.Shift | Keys.Left:
case Keys.Shift | Keys.Up:
case Keys.Shift | Keys.Down:
{
{
return true;
}
}
Expand Down

0 comments on commit e844bed

Please sign in to comment.