2018-09-10 02:41:13 +02:00
|
|
|
// Copyright © 2015 The CefSharp Authors. All rights reserved.
|
2015-01-29 19:34:28 +10:00
|
|
|
//
|
|
|
|
|
// 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;
|
|
|
|
|
|
|
|
|
|
namespace CefSharp.WinForms.Internals
|
|
|
|
|
{
|
2016-06-15 13:44:16 +10:00
|
|
|
/// <summary>
|
|
|
|
|
/// ControlExtensions.
|
|
|
|
|
/// </summary>
|
2015-01-29 19:34:28 +10:00
|
|
|
public static class ControlExtensions
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Executes the Action asynchronously on the UI thread, does not block execution on the calling thread.
|
2019-12-02 20:37:41 +10:00
|
|
|
/// No action will be performed if the control doesn't have a valid handle or the control is Disposed/Disposing.
|
2015-01-29 19:34:28 +10:00
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="control">the control for which the update is required</param>
|
|
|
|
|
/// <param name="action">action to be performed on the control</param>
|
2019-12-02 20:37:41 +10:00
|
|
|
internal static void InvokeOnUiThreadIfRequired(this Control control, Action action)
|
2015-01-29 19:34:28 +10:00
|
|
|
{
|
2019-12-02 14:49:03 +10:00
|
|
|
//No action
|
2019-12-02 20:37:41 +10:00
|
|
|
if (control.Disposing || control.IsDisposed || !control.IsHandleCreated)
|
2019-12-02 14:49:03 +10:00
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-29 19:34:28 +10:00
|
|
|
if (control.InvokeRequired)
|
|
|
|
|
{
|
2019-12-02 20:37:41 +10:00
|
|
|
control.BeginInvoke((Action)(() =>
|
|
|
|
|
{
|
|
|
|
|
//No action
|
|
|
|
|
if (control.Disposing || control.IsDisposed || !control.IsHandleCreated)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
action();
|
|
|
|
|
}));
|
2015-01-29 19:34:28 +10:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
action.Invoke();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-04 14:51:49 +10:00
|
|
|
/// <summary>
|
|
|
|
|
/// Executes the Action sync on the UI thread, blocks execution on the calling thread.
|
|
|
|
|
/// No action will be performed if the control doesn't have a valid handle or the control is Disposed/Disposing.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="control">the control for which the update is required</param>
|
|
|
|
|
/// <param name="action">action to be performed on the control</param>
|
|
|
|
|
internal static void InvokeSyncOnUiThreadIfRequired(this Control control, Action action)
|
|
|
|
|
{
|
|
|
|
|
//No action
|
|
|
|
|
if (control.Disposing || control.IsDisposed || !control.IsHandleCreated)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (control.InvokeRequired)
|
|
|
|
|
{
|
|
|
|
|
control.Invoke(action);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
action();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-15 13:44:16 +10:00
|
|
|
/// <summary>
|
|
|
|
|
/// Activates the specified control.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="control">The control.</param>
|
|
|
|
|
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
2015-03-06 02:31:05 -05:00
|
|
|
public static bool Activate(this Control control)
|
2015-01-29 19:34:28 +10:00
|
|
|
{
|
2015-02-03 22:41:43 +10:00
|
|
|
// Notify WinForms world that inner browser window got focus. This will trigger Leave event to previous focused control
|
2015-01-29 19:34:28 +10:00
|
|
|
var containerControl = control.GetContainerControl();
|
|
|
|
|
if (containerControl != null)
|
|
|
|
|
{
|
2015-03-06 02:31:05 -05:00
|
|
|
return containerControl.ActivateControl(control);
|
2015-01-29 19:34:28 +10:00
|
|
|
}
|
2015-03-06 02:31:05 -05:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-15 12:42:15 -04:00
|
|
|
/// <summary>
|
|
|
|
|
/// Returns whether the supplied control is the currently
|
|
|
|
|
/// active control.
|
|
|
|
|
/// </summary>
|
2015-11-03 14:45:44 +01:00
|
|
|
/// <param name="control">the control to check</param>
|
|
|
|
|
/// <returns>true if the control is the currently active control</returns>
|
2015-03-06 02:31:05 -05:00
|
|
|
public static bool IsActiveControl(this Control control)
|
|
|
|
|
{
|
2016-08-30 09:16:02 -04:00
|
|
|
Form form = control.FindForm();
|
|
|
|
|
if (form == null)
|
2018-09-10 02:41:13 +02:00
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-30 09:16:02 -04:00
|
|
|
Control activeControl = form.ActiveControl;
|
2015-03-06 02:31:05 -05:00
|
|
|
while (activeControl != null
|
2015-05-28 22:12:47 -04:00
|
|
|
&& (activeControl is ContainerControl)
|
2015-03-06 02:31:05 -05:00
|
|
|
&& !Object.ReferenceEquals(control, activeControl))
|
|
|
|
|
{
|
2015-05-28 22:12:47 -04:00
|
|
|
var containerControl = activeControl as ContainerControl;
|
2015-03-06 02:31:05 -05:00
|
|
|
activeControl = containerControl.ActiveControl;
|
|
|
|
|
}
|
|
|
|
|
return Object.ReferenceEquals(control, activeControl);
|
2015-01-29 19:34:28 +10:00
|
|
|
}
|
|
|
|
|
|
2016-06-15 13:44:16 +10:00
|
|
|
/// <summary>
|
|
|
|
|
/// Selects the next control.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="control">The control.</param>
|
|
|
|
|
/// <param name="next">if set to <c>true</c> [next].</param>
|
2015-01-29 19:34:28 +10:00
|
|
|
public static void SelectNextControl(this Control control, bool next)
|
|
|
|
|
{
|
|
|
|
|
var containerControl = control.GetContainerControl();
|
|
|
|
|
|
|
|
|
|
while (containerControl != null)
|
|
|
|
|
{
|
|
|
|
|
var containerControlAsControl = containerControl as Control;
|
|
|
|
|
if (containerControlAsControl == null)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var activeControl = containerControl.ActiveControl;
|
|
|
|
|
if (containerControlAsControl.SelectNextControl(activeControl, next, true, true, false))
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (containerControlAsControl.Parent == null)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
containerControl = containerControlAsControl.Parent.GetContainerControl();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|