Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Integration / System / Windows / Integration / WindowsFormsHost.cs / 2 / WindowsFormsHost.cs
using MS.Win32;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Windows.Interop;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Automation.Provider;
using System.Windows.Automation.Peers;
using SD = System.Drawing;
using SW = System.Windows;
using SWC = System.Windows.Controls;
using SWF = System.Windows.Forms;
using SWM = System.Windows.Media;
using SWI = System.Windows.Input;
using System.Collections.Generic;
using System.Windows.Input;
namespace System.Windows.Forms.Integration
{
///
/// An element that allows you to host a Windows Forms control on a
/// Windows Presentation Foundation page.
///
[System.ComponentModel.DesignerCategory("code")]
[ContentProperty("Child")]
[DefaultEvent("ChildChanged")]
public class WindowsFormsHost : HwndHost, IKeyboardInputSink
{
private SWM.Brush _cachedBackbrush;
private HandleRef _hwndParent;
private WinFormsAdapter _hostContainerInternal;
#region Constructors
[SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")]
static WindowsFormsHost()
{
//Keyboard tabbing support
FocusableProperty.OverrideMetadata(typeof(WindowsFormsHost), new FrameworkPropertyMetadata(true));
SWC.Control.IsTabStopProperty.OverrideMetadata(typeof(WindowsFormsHost), new FrameworkPropertyMetadata(true));
}
///
/// Initializes a new instance of the WindowsFormsHost class.
///
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
public WindowsFormsHost()
: base()
{
this._hostContainerInternal = new WinFormsAdapter(this);
_propertyMap = new WindowsFormsHostPropertyMap(this);
}
#endregion
#region Focus
///
/// Notifies Avalon that focus has moved within this WindowsFormsHost.
///
void NotifyFocusWithinHost()
{
DependencyObject focusScope = GetFocusScopeForElement(this);
if (null != focusScope)
{ System.Windows.Input.FocusManager.SetFocusedElement(focusScope, this); }
}
///
/// When implemented in a derived class, accesses the window process of the hosted child window.
///
///
///
///
///
///
///
protected override IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
{
case NativeMethods.WM_CHILDACTIVATE:
_hostContainerInternal.HandleChildActivate();
break;
case NativeMethods.WM_SETFOCUS:
case NativeMethods.WM_MOUSEACTIVATE:
NotifyFocusWithinHost();
break;
case NativeMethods.WM_GETOBJECT:
handled = true;
return OnWmGetObject(wParam, lParam);
}
return base.WndProc(hwnd, msg, wParam, lParam, ref handled);
}
///
/// Critical - Calls critical HwndHost.Handle.
/// TreatAsSafe - This demands full trust, so it's safe
///
[SecurityCritical, SecurityTreatAsSafe]
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
private IntPtr OnWmGetObject(IntPtr wparam, IntPtr lparam)
{
IntPtr result = IntPtr.Zero;
WindowsFormsHostAutomationPeer peer = UIElementAutomationPeer.CreatePeerForElement(this) as WindowsFormsHostAutomationPeer;
if(peer != null)
{
// get the element proxy
IRawElementProviderSimple el = peer.GetProvider();
//This requires FullTrust but we already have it.
result = AutomationInteropProvider.ReturnRawElementProvider(Handle, wparam, lparam, el);
}
return result;
}
private static DependencyObject GetFocusScopeForElement(DependencyObject element)
{
//Walk up the visual tree until we find an element that is a focus scope (or we run out of elements).
//This will usually be the root Avalon Window.
while (null != element && !FocusManager.GetIsFocusScope(element))
{ element = VisualTreeHelper.GetParent(element); }
return element;
}
#endregion
#region Layout
private Vector _currentScale = new Vector(1.0, 1.0);
///
/// Scales the hosted Windows Forms control, and tracks the scale factor.
///
///
/// The new scale factor
protected virtual Vector ScaleChild(Vector newScale)
{
if (newScale != _currentScale)
{
if (Child != null)
{
Child.Scale(new System.Drawing.SizeF((float)(newScale.X / _currentScale.X), (float)(newScale.Y / _currentScale.Y)));
}
}
return newScale;
}
private void ScaleChild()
{
bool skewed;
Vector newScale = HostUtils.GetScale(this, out skewed);
if (skewed)
{
OnLayoutError();
}
_currentScale = ScaleChild(newScale);
}
private event EventHandler _layoutError;
///
/// Occurs when a layout error, such as a skew or rotation that WindowsFormsHost does not support,
/// is encountered.
///
public event EventHandler LayoutError
{
add { _layoutError += value; }
remove { _layoutError -= value; }
}
private void OnLayoutError()
{
InvalidOperationException exception = new InvalidOperationException(SR.Get(SRID.Host_CannotRotateWindowsFormsHost));
LayoutExceptionEventArgs args = new LayoutExceptionEventArgs(exception);
if (_layoutError != null)
{
_layoutError(this, args);
}
if (args.ThrowException)
{
throw exception;
}
}
///
/// Overrides the base class implementation of MeasureOverride to measure
/// the size of a WindowsFormsHost object and return the proper size to the layout engine.
///
protected override SW.Size MeasureOverride(SW.Size constraint)
{
if (this.Visibility == Visibility.Collapsed || Child == null)
{
//Child takes up no space
return new Size(0, 0);
}
ScaleChild();
SD.Size constraintSize = Convert.ConstraintToSystemDrawingSize(constraint, _currentScale);
SD.Size preferredSize = Child.GetPreferredSize(constraintSize);
System.Windows.Size returnSize = Convert.ToSystemWindowsSize(preferredSize, _currentScale);
// Apply constraints to the preferred size
returnSize.Width = Math.Min(returnSize.Width, constraint.Width);
returnSize.Height = Math.Min(returnSize.Height, constraint.Height);
return returnSize;
}
// Note: the WPF layout engine may call ArrangeOverride multiple times in succession
private Size _priorConstraint;
///
/// When implemented in a derived class, positions child elements and determines a
/// size for a FrameworkElement-derived class.
///
///
///
protected override Size ArrangeOverride(Size finalSize)
{
if (this.Visibility == Visibility.Collapsed || Child == null)
{
//Child takes up no space
return new Size(0, 0);
}
Vector originalScale = _currentScale;
ScaleChild();
bool scaled = (_currentScale != originalScale);
SD.Size targetSize = Convert.ConstraintToSystemDrawingSize(finalSize, _currentScale);
if ((Child.Size != targetSize) && ((finalSize != _priorConstraint) || scaled))
{
_priorConstraint = finalSize;
Child.Size = targetSize;
}
Size returnSize = Convert.ToSystemWindowsSize(Child.Size, _currentScale);
returnSize.Width = Math.Min(returnSize.Width, finalSize.Width);
returnSize.Height = Math.Min(returnSize.Height, finalSize.Height);
if (HostContainerInternal.BackgroundImage != null)
{
_propertyMap.OnPropertyChanged(this, "Background", this.Background);
}
return returnSize;
}
#endregion Layout
#region Containership
///
/// Occurs when the Child property is set.
///
public event EventHandler ChildChanged;
///
/// Gets or sets the child control hosted by the WindowsFormsHost element.
///
public Control Child
{
get
{
return _hostContainerInternal.Child;
}
set
{
#pragma warning disable 1634, 1691
#pragma warning disable 56526
Control oldChild = Child;
SWF.Form form = value as SWF.Form;
if (form != null)
{
if (form.TopLevel)
{ //WinOS #1030878 - Can't host top-level forms
throw new ArgumentException(SR.Get(SRID.Host_ChildCantBeTopLevelForm));
}
else
{
form.ControlBox = false;
}
}
_hostContainerInternal.Child = value;
if (Child != null)
{
_propertyMap.ApplyAll();
Child.Margin = SWF.Padding.Empty;
Child.Dock = DockStyle.None;
Child.AutoSize = false;
Child.Location = SD.Point.Empty;
// clear the cached size
_priorConstraint = new Size(double.NaN, double.NaN);
}
OnChildChanged(oldChild);
#pragma warning restore 1634, 1691, 56526
}
}
private void OnChildChanged(Control oldChild)
{
if (ChildChanged != null)
{
ChildChanged(this, new ChildChangedEventArgs(oldChild));
}
}
internal WinFormsAdapter HostContainerInternal
{
get
{
return _hostContainerInternal;
}
}
#endregion Containership
#region Rendering
static Brush defaultBrush = SystemColors.WindowBrush;
///
/// Manually searches up the parent tree to find the first FrameworkElement that
/// has a non-null background, and returns that Brush.
/// If no parent is found with a brush, then this returns WindowBrush.
///
///
///
private static SWM.Brush FindBackgroundParent(SW.DependencyObject dependencyObject)
{
if (dependencyObject == null)
{
return defaultBrush;
}
Brush backgroundBrush = null;
backgroundBrush = (Brush)dependencyObject.GetValue(SWC.Control.BackgroundProperty);
if (backgroundBrush == null)
{
SW.FrameworkElement frameworkElement = dependencyObject as SW.FrameworkElement;
if (frameworkElement != null)
{
DependencyObject parentElement = VisualTreeHelper.GetParent(frameworkElement);
backgroundBrush = FindBackgroundParent(parentElement);
}
}
return backgroundBrush ?? defaultBrush;
}
///
/// This is called by the OnPaintBackground method of the host container.
///
internal void PaintBackground()
{
SWM.Brush parentBrush = FindBackgroundParent(this);
if (parentBrush != null)
{
if (_cachedBackbrush != parentBrush)
{
_cachedBackbrush = parentBrush;
_propertyMap.OnPropertyChanged(this, "Background", parentBrush);
}
}
}
#endregion Rendering
#region Keyboarding
///
/// Enables Windows Forms forms to function correctly when opened modelessly from
/// Windows Presentation Foundation.
///
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
public static void EnableWindowsFormsInterop()
{
ApplicationInterop.EnableWindowsFormsInterop();
}
///
/// Forwards focus from Windows Presentation Foundation to the hosted Windows Forms control.
///
public virtual bool TabInto(SWI.TraversalRequest request)
{
return HostContainerInternal.FocusNext(request);
}
#endregion Keyboarding
#region Activation
private Control _focusedChild;
private void RestoreFocusedChild()
{
_hostContainerInternal.Focus();
_hostContainerInternal.ActiveControl = _focusedChild;
_focusedChild = null;
}
private void NotifyActivateApp(ref Message m)
{
if (m.WParam != IntPtr.Zero)
{
if (null != _focusedChild)
{ _hostContainerInternal.BeginInvoke(new MethodInvoker(RestoreFocusedChild)); }
}
else
{
IntPtr currentFocus = UnsafeNativeMethods.GetFocus();
if (currentFocus == Handle || UnsafeNativeMethods.IsChild(Handle, currentFocus))
{ _focusedChild = _hostContainerInternal.ActiveControl; }
}
}
private ActivateWindowListener _activateWindowListener;
private class ActivateWindowListener : NativeWindow, IDisposable
{
WindowsFormsHost _host;
public ActivateWindowListener(WindowsFormsHost host)
{ _host = host; }
protected override void WndProc(ref Message m)
{
if (NativeMethods.WM_ACTIVATEAPP == m.Msg)
{ _host.NotifyActivateApp(ref m); }
base.WndProc(ref m);
}
public void Dispose()
{ this.ReleaseHandle(); }
}
#endregion
#region Window Handling & Misc
///
/// Overrides the base class implementation of BuildWindowCore to build the hosted
/// Windows Forms control.
///
protected override HandleRef BuildWindowCore(HandleRef hwndParent)
{
this.Loaded += new RoutedEventHandler(ApplyAllProperties);
Debug.WriteLineIf(_traceHandle.TraceVerbose, String.Format(CultureInfo.CurrentCulture, "WindowsFormsHost({0}): BuildWindowCore (parent=0x{1:x8})", this.Name, hwndParent.Handle.ToInt32()));
if (_activateWindowListener != null)
{
_activateWindowListener.Dispose();
}
_activateWindowListener = new ActivateWindowListener(this);
_activateWindowListener.AssignHandle(hwndParent.Handle);
_hwndParent = hwndParent;
//For Keyboard interop
ApplicationInterop.ThreadWindowsFormsHostList.Add(this); //Keep track of this control, so it can get forwarded windows messages
EnableWindowsFormsInterop(); //Start the forwarding of windows messages to all WFH controls on active windows
UnsafeNativeMethods.SetParent(/* child = */ HostContainerInternal.Handle, /* parent = */ _hwndParent.Handle);
return new HandleRef(HostContainerInternal, HostContainerInternal.Handle);
}
///
/// Overrides the base class implementation of DestroyWindowCore to delete the
/// window containing this object.
///
protected override void DestroyWindowCore(HandleRef hwnd)
{
//For keyboard interop (remove this control from the list)
//This line shouldn't be necessary since the list cleans itself, but it's good to be tidy.
ApplicationInterop.ThreadWindowsFormsHostList.Remove(this);
if (HostContainerInternal != null)
{
HostContainerInternal.Dispose();
}
}
void ApplyAllProperties(object sender, RoutedEventArgs e)
{
_propertyMap.ApplyAll();
}
///
/// Releases all resources used by the WindowsFormsHost element.
///
protected override void Dispose(bool disposing)
{
try
{
base.Dispose(disposing);
}
finally
{
if (disposing)
{
if (_hostContainerInternal != null)
{
try
{
if (_activateWindowListener != null)
{
_activateWindowListener.Dispose();
}
_hostContainerInternal.Dispose();
this.Loaded -= new RoutedEventHandler(ApplyAllProperties);
}
finally
{
if (Child != null)
{
Child.Dispose();
}
}
}
}
}
}
#endregion Window Handling & Misc
#region Automation
///
/// Creates AutomationPeer ( )
///
protected override AutomationPeer OnCreateAutomationPeer()
{
return new WindowsFormsHostAutomationPeer(this);
}
#endregion Automation
#region Property Mapping
//Some of the properties that we would like to map don't exist on HwndHost,
//so we add them here: TabIndex, Font (4x), Foreground, Background, Padding.
///
/// Identifies the Padding dependency property.
///
public static readonly DependencyProperty PaddingProperty =
SWC.Control.PaddingProperty.AddOwner(typeof(WindowsFormsHost));
///
/// Specifies the size of the desired padding within the hosted Windows Forms control.
///
[Bindable(true), Category("Behavior")]
public Thickness Padding
{
get { return (Thickness)GetValue(PaddingProperty); }
set { SetValue(PaddingProperty, value); }
}
///
/// Identifies the TabIndex dependency property.
///
public static readonly DependencyProperty TabIndexProperty =
SWC.Control.TabIndexProperty.AddOwner(typeof(WindowsFormsHost));
///
/// Gets or sets the hosted control's tab index.
///
[Bindable(true), Category("Behavior")]
public int TabIndex
{
get { return (int)GetValue(TabIndexProperty); }
set { SetValue(TabIndexProperty, value); }
}
///
/// Identifies the FontFamily dependency property.
///
public static readonly DependencyProperty FontFamilyProperty =
SWC.Control.FontFamilyProperty.AddOwner(typeof(WindowsFormsHost));
///
/// Gets or sets the hosted control's font family as an ambient property.
///
public SWM.FontFamily FontFamily
{
get { return (SWM.FontFamily)GetValue(FontFamilyProperty); }
set { SetValue(FontFamilyProperty, value); }
}
///
/// Identifies the FontSize dependency property.
///
public static readonly DependencyProperty FontSizeProperty =
SWC.Control.FontSizeProperty.AddOwner(typeof(WindowsFormsHost));
///
/// Gets or sets the hosted control's font size as an ambient property.
///
public double FontSize
{
get { return (double)GetValue(FontSizeProperty); }
set { SetValue(FontSizeProperty, value); }
}
///
/// Identifies the FontStyle dependency property.
///
public static readonly DependencyProperty FontStyleProperty =
SWC.Control.FontStyleProperty.AddOwner(typeof(WindowsFormsHost));
///
/// Gets or sets the hosted control's font style as an ambient proeprty.
///
public SW.FontStyle FontStyle
{
get { return (FontStyle)GetValue(FontStyleProperty); }
set { SetValue(FontStyleProperty, value); }
}
///
/// Identifies the FontWeight dependency property.
///
public static readonly DependencyProperty FontWeightProperty =
SWC.Control.FontWeightProperty.AddOwner(typeof(WindowsFormsHost));
///
/// Gets or sets the hosted control's font weight as an ambient property.
///
public SW.FontWeight FontWeight
{
get { return (FontWeight)GetValue(FontWeightProperty); }
set { SetValue(FontWeightProperty, value); }
}
///
/// Identifies the Foreground dependency property.
///
public static readonly DependencyProperty ForegroundProperty =
SWC.Control.ForegroundProperty.AddOwner(typeof(WindowsFormsHost));
///
/// Gets or sets the hosted control's foreground color as an ambient property.
///
public Brush Foreground
{
get { return (Brush)GetValue(ForegroundProperty); }
set { SetValue(ForegroundProperty, value); }
}
///
/// Identifies the Background dependency property.
///
public static readonly DependencyProperty BackgroundProperty =
SWC.Control.BackgroundProperty.AddOwner(typeof(WindowsFormsHost));
///
/// Gets or sets the hosted control's background as an ambient property.
///
public Brush Background
{
get { return (Brush)GetValue(BackgroundProperty); }
set { SetValue(BackgroundProperty, value); }
}
///
/// Forces the translation of a mapped property.
///
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
// Invoke method currently set to handle this event
if (_propertyMap != null)
{
_propertyMap.OnPropertyChanged(this, e.Property.Name, e.NewValue);
}
}
///
/// Gets the property map that determines how setting properties on the
/// WindowsFormsHost element affects the hosted Windows Forms control.
///
public PropertyMap PropertyMap
{
get { return _propertyMap; }
}
private PropertyMap _propertyMap;
#endregion Property Mapping
#region DEBUG
#if DEBUG
internal static readonly TraceSwitch _traceHandle = new TraceSwitch("WindowsFormsHostHandle", "Tracks WindowsFormsHost handle information.");
internal static readonly TraceSwitch _traceLayout = new TraceSwitch("WindowsFormsHostLayout", "Tracks WindowsFormsHost layout information.");
#else
internal static readonly TraceSwitch _traceHandle = null;
internal static readonly TraceSwitch _traceLayout = null;
#endif
#endregion DEBUG
}
#region WinFormsAdapter
[System.ComponentModel.DesignerCategory("code")]
internal class WinFormsAdapter : SWF.ContainerControl
{
private WindowsFormsHost _host;
private FocusTargetControl _focusTarget;
private IntPtr _prevFocusHwnd = IntPtr.Zero;
private Control _child;
public Control Child
{
get { return _child; }
set
{
if (null != Child)
{ Controls.Remove(Child); }
if (null != value)
{ Controls.Add(value); }
_child = value;
}
}
private bool IsParked
{
get { return ActiveControl == _focusTarget; }
}
Control _controlBeforePark;
public void HandleChildActivate()
{
IntPtr focusHwnd = UnsafeNativeMethods.GetFocus();
try
{
if (IntPtr.Zero == _prevFocusHwnd ) { return; }
//If nothing's focused, but Avalon thinks we should have focus, give us focus.
if (IntPtr.Zero == focusHwnd && _host.IsFocused)
{
this.BeginInvoke(new MethodInvoker(RestoreFocus));
return;
}
//If focus is changing from a child of the WinFormsAdapter to something outside
//we will activate the a temporary control to cause leave and validation events
if (
_focusTarget.Handle != _prevFocusHwnd &&
UnsafeNativeMethods.IsChild(Handle, _prevFocusHwnd) &&
!UnsafeNativeMethods.IsChild(Handle, focusHwnd))
{
_controlBeforePark = this.ActiveControl;
this.ActiveControl = _focusTarget;
}
}
finally
{ _prevFocusHwnd = focusHwnd; }
}
private void RestoreFocus()
{
this.Focus();
if (IsParked)
{ ActiveControl = _controlBeforePark; }
}
//Note: there's no notification when the ambient cursor changes, so we
//can't do a normal mapping for this and have it work. We work around
//this by overriding WinFormsAdapter.Cursor and walking the visual tree
//to find the cursor IF the Cursor translator has not been changed.
//host.PropertyMap["Cursor"] += delegate {MessageBox.Show("?");};
//will cause the mapping to no longer happen.
public override Cursor Cursor
{
get
{
if (_host == null) { return base.Cursor; }
if (!_host.PropertyMap.PropertyMappedToEmptyTranslator("Cursor"))
{ return base.Cursor; }
bool forceCursorMapped = _host.PropertyMap.PropertyMappedToEmptyTranslator("ForceCursor");
FrameworkElement cursorSource = HostUtils.GetCursorSource(_host, forceCursorMapped);
if (cursorSource == null) { return base.Cursor; }
return Convert.ToSystemWindowsFormsCursor(cursorSource.Cursor);
}
set
{
base.Cursor = value;
}
}
private class FocusTargetControl : Control
{
public FocusTargetControl()
{
this.Size = SD.Size.Empty;
//Hide it as far away as possible
this.Location = new SD.Point(short.MinValue, short.MinValue);
this.TabStop = false;
#if DEBUG
this.Name = "Focus target";
#endif //DEBUG
}
}
public WinFormsAdapter(WindowsFormsHost host)
{
_host = host;
_focusTarget = new FocusTargetControl();
Controls.Add(_focusTarget);
this.HandleCreated += WinFormsAdapter_HandleCreated;
//Keyboard interop: We listen to this event to refresh the visual cues (workaround)
SWI.InputManager.Current.PostProcessInput += InputManager_PostProcessInput;
}
protected override void Dispose(bool disposing)
{
try
{
if (disposing)
{
SWI.InputManager.Current.PostProcessInput -= InputManager_PostProcessInput;
}
}
finally
{
base.Dispose(disposing);
}
}
#region Keyboard Interop
///
/// Forwards focus from Avalon and into the WinForms "sink".
/// The request is often First and Last, which isn't really mapped the
/// same way, but it seems to work, probably because we only host one control.
///
///
///
internal bool FocusNext(SWI.TraversalRequest request)
{
UpdateUIState(NativeMethods.UIS_INITIALIZE);
bool forward = true;
bool tabStopOnly = true;
switch (request.FocusNavigationDirection)
{
case System.Windows.Input.FocusNavigationDirection.Down:
case System.Windows.Input.FocusNavigationDirection.Right:
forward = true;
tabStopOnly = false;
break;
case System.Windows.Input.FocusNavigationDirection.Next:
case System.Windows.Input.FocusNavigationDirection.First:
forward = true;
tabStopOnly = true;
break;
case System.Windows.Input.FocusNavigationDirection.Up:
case System.Windows.Input.FocusNavigationDirection.Left:
forward = false;
tabStopOnly = false;
break;
case System.Windows.Input.FocusNavigationDirection.Previous:
case System.Windows.Input.FocusNavigationDirection.Last:
forward = false;
tabStopOnly = true;
break;
default:
Debug.Assert(false, "Unknown FocusNavigationDirection");
break;
}
_focusTarget.Enabled = false;
try
{
if (this.SelectNextControl(null, forward, tabStopOnly, true, false))
{
// find the inner most active control
ContainerControl ret = this;
while (ret.ActiveControl is ContainerControl)
{
ret = (ContainerControl)ret.ActiveControl;
}
if (!ret.ContainsFocus)
{ ret.Focus(); }
return true;
}
return false;
}
finally
{ _focusTarget.Enabled = true; }
}
// CSS added for keyboard interop
protected override bool ProcessDialogKey(Keys keyData)
{
_focusTarget.Enabled = false;
try
{
if ((keyData & (Keys.Alt | Keys.Control)) == Keys.None)
{
Keys keyCode = (Keys)keyData & Keys.KeyCode;
if (keyCode == Keys.Tab || keyCode == Keys.Left ||
keyCode == Keys.Right || keyCode == Keys.Up ||
keyCode == Keys.Down)
{
if (this.Focused || this.ContainsFocus)
{
// CSS: In WF apps, by default, arrow keys always wrap within a container
// However, we don't want them to wrap in the Adapter, which always has only
// one immediate child
if ((keyCode == Keys.Left || keyCode == Keys.Right || keyCode == Keys.Down || keyCode == Keys.Up)
&& (this.ActiveControl != null && this.ActiveControl.Parent == this))
{
SWF.Control c = this.ActiveControl.Parent;
return c.SelectNextControl(this.ActiveControl, keyCode == Keys.Right || keyCode == Keys.Down, false, false, false);
}
else
return base.ProcessDialogKey(keyData);
}
}
}
return false;
}
finally { _focusTarget.Enabled = true; }
}
// CSS added for keyboard interop
internal bool PreProcessMessage(ref Message msg, bool hasFocus)
{
// Don't steal WM_CHAR messages from Avalon, Catch them later in InputManager_PostProcessInput
if (!hasFocus && msg.Msg == NativeMethods.WM_CHAR)
{
return false;
}
return PreProcessMessage(ref msg);
}
///
/// For keyboard interop, when this handle is recreated, the current state of the
/// visual shortcut key cues (AKA underlining the hotkey) is lost, so it needs
/// to be refreshed.
///
///
///
private void WinFormsAdapter_HandleCreated(object sender, EventArgs e)
{
//CSS - Workaround OS bug. The initial UI state was being set erratically
// (sometimes cues were shown, sometimes not. This forces it to a known state.
UpdateUIState(NativeMethods.UIS_SET);
}
///
/// For keyboard interop
/// Ensure the visual shortcut key cues on controls are in the same visual
/// state that we expect. This is a workaround for odd Windows API.
///
internal void UpdateUIState(int uiAction)
{
Debug.Assert(uiAction == NativeMethods.UIS_INITIALIZE || uiAction == NativeMethods.UIS_SET, "Unexpected uiAction");
int toSet = NativeMethods.UISF_HIDEACCEL | NativeMethods.UISF_HIDEFOCUS;
if (UnsafeNativeMethods.SendMessage(new HandleRef(this, this.Handle),
NativeMethods.WM_UPDATEUISTATE,
(IntPtr)(uiAction | (toSet << 16)),
IntPtr.Zero) != IntPtr.Zero)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
// CSS Added for keyboard interop
// Catch WM_CHAR messages which weren't handled by Avalon
// (including mnemonics which were typed without the "Alt" key)
private void InputManager_PostProcessInput(object sender, SWI.ProcessInputEventArgs e)
{
// Should return immediately if this WFH is not in the active Window
PresentationSource presentationSource = PresentationSource.FromVisual(this._host);
if (presentationSource == null)
{
return;
}
Window presentationSourceWindow = presentationSource.RootVisual as Window;
//CSS This active window check may not work for multiple levels of nesting...
// RootVisual isn't top level window. Should we traverse upward through nested levels?
if (presentationSourceWindow == null || !presentationSourceWindow.IsActive)
return;
// Now check for unhandled WM_CHAR messages and process them as mnemonics
if (!e.StagingItem.Input.Handled && e.StagingItem.Input.RoutedEvent == SWI.TextCompositionManager.TextInputEvent)
{
SWI.TextCompositionEventArgs te = (SWI.TextCompositionEventArgs)e.StagingItem.Input;
string text = te.Text;
if (string.IsNullOrEmpty(text))
{
text = te.SystemText;
}
if (!string.IsNullOrEmpty(text))
{
e.StagingItem.Input.Handled = this.ProcessDialogChar(text[0]);
}
}
}
#endregion Keyboard Interop
///
/// Overridden to invalidate host layout when our layout changes.
///
protected override void OnLayout(SWF.LayoutEventArgs e)
{
base.OnLayout(e);
_host.InvalidateMeasure();
#if DEBUG
string compName = "";
if (e.AffectedControl != null)
{
compName = e.AffectedControl.Name;
}
else if (e.AffectedComponent != null)
{
compName = e.AffectedComponent.ToString();
}
Debug.WriteLineIf(WindowsFormsHost._traceLayout.TraceInfo, String.Format(CultureInfo.CurrentCulture, "WindowsFormsHost({0}): Layout invalidated (control='{1}',property='{2}')", _host.Name, compName, e.AffectedProperty));
#endif
}
///
/// Forward the Host Containers paint events to the WFH, so that it can either
/// use a bitmap to do "fake" transparency or set the BackColor correctly.
///
protected override void OnPaintBackground(SWF.PaintEventArgs e)
{
_host.PaintBackground();
base.OnPaintBackground(e);
}
//Changing RightToLeft on the WinFormsAdapter recreates the handle. Since our
//handle is being cached, this causes problems. The handle gets recreated when
//RightToLeft changes. To avoid changing our handle, we can override the
//RightToLeft property, and notify our child when the property changes.
private RightToLeft _rightToLeft = RightToLeft.Inherit;
///
/// Gets or sets a value indicating whether control's elements are aligned
/// to support locales using right-to-left fonts.
///
public override RightToLeft RightToLeft
{
get
{
//Return the same default value as Control does (No)
return _rightToLeft == RightToLeft.Inherit ?
RightToLeft.No : _rightToLeft;
}
set
{
if (_rightToLeft != value)
{
//If RightToLeft is Inherit and we're setting to the "default" value, don't call OnRTLChanged.
bool fireRightToLeftChanged = _rightToLeft != RightToLeft.Inherit || base.RightToLeft != value;
_rightToLeft = value;
if (fireRightToLeftChanged)
{
OnRightToLeftChanged(EventArgs.Empty);
}
}
}
}
///
/// Override OnRightToLeftChanged as noted above
///
///
protected override void OnRightToLeftChanged(EventArgs e)
{
if (null != Child)
{
CallOnParentRightToLeftChanged(Child);
}
}
//Use reflection to call protected OnParentRightToLeftChanged
private void CallOnParentRightToLeftChanged(Control control)
{
MethodInfo methodInfo = typeof(SWF.Control).GetMethod("OnParentRightToLeftChanged", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(EventArgs) }, null);
Debug.Assert(methodInfo != null, "Couldn't find OnParentRightToLeftChanged method!");
if (methodInfo != null)
{
methodInfo.Invoke(control, new object[] { EventArgs.Empty });
}
}
}
#endregion WinFormsAdapter
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- NetworkInformationException.cs
- UshortList2.cs
- ExtensibleClassFactory.cs
- WebServiceParameterData.cs
- MenuCommand.cs
- PieceDirectory.cs
- TextEffect.cs
- LineSegment.cs
- NameValueCollection.cs
- WindowsAuthenticationEventArgs.cs
- CalendarDay.cs
- SourceFileBuildProvider.cs
- DetailsViewDeleteEventArgs.cs
- XPathNavigatorReader.cs
- BuildProvider.cs
- PositiveTimeSpanValidatorAttribute.cs
- SapiRecognizer.cs
- GroupQuery.cs
- Int16Converter.cs
- ListItemViewAttribute.cs
- DataGridViewRowErrorTextNeededEventArgs.cs
- ProtocolsConfigurationEntry.cs
- coordinatorfactory.cs
- DataGridRelationshipRow.cs
- Avt.cs
- loginstatus.cs
- CustomAssemblyResolver.cs
- HijriCalendar.cs
- SqlException.cs
- HasCopySemanticsAttribute.cs
- IDispatchConstantAttribute.cs
- SystemDiagnosticsSection.cs
- OdbcDataAdapter.cs
- DbMetaDataCollectionNames.cs
- SectionRecord.cs
- ItemCheckedEvent.cs
- WorkflowIdleBehavior.cs
- DataSourceView.cs
- ContextMenuStrip.cs
- GroupLabel.cs
- RSAPKCS1SignatureFormatter.cs
- Statements.cs
- HyperLinkColumn.cs
- DateTimeOffset.cs
- GcSettings.cs
- Pkcs7Signer.cs
- BamlBinaryReader.cs
- RequestStatusBarUpdateEventArgs.cs
- ValidationEventArgs.cs
- LogExtent.cs
- PathTooLongException.cs
- Automation.cs
- OptimalBreakSession.cs
- CompositeClientFormatter.cs
- OleDbFactory.cs
- WCFServiceClientProxyGenerator.cs
- handlecollector.cs
- GlobalProxySelection.cs
- DesignerAutoFormatCollection.cs
- MimeMapping.cs
- AnnotationAuthorChangedEventArgs.cs
- TabControlCancelEvent.cs
- ReflectTypeDescriptionProvider.cs
- BoundPropertyEntry.cs
- TypeTypeConverter.cs
- CryptoApi.cs
- Marshal.cs
- IssuanceLicense.cs
- SendSecurityHeaderElement.cs
- TreeNodeClickEventArgs.cs
- BorderGapMaskConverter.cs
- UnmanagedMemoryStreamWrapper.cs
- Keywords.cs
- PathFigure.cs
- UpdateException.cs
- AutoResetEvent.cs
- OrderedDictionaryStateHelper.cs
- RecordManager.cs
- DynamicPropertyReader.cs
- Ticks.cs
- OracleMonthSpan.cs
- RoutedEvent.cs
- InitializationEventAttribute.cs
- RowSpanVector.cs
- UIElementCollection.cs
- TextDpi.cs
- _RequestCacheProtocol.cs
- DataError.cs
- KernelTypeValidation.cs
- ToolStripDropDownMenu.cs
- SafeRightsManagementPubHandle.cs
- TypeInfo.cs
- ModelMemberCollection.cs
- ObjectComplexPropertyMapping.cs
- RuleSet.cs
- ResXResourceWriter.cs
- FontClient.cs
- EncryptedPackage.cs
- Rotation3D.cs
- Vector3D.cs