Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / WinFormsIntegration / System / Windows / Integration / ApplicationInterop.cs / 1 / ApplicationInterop.cs
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Windows.Interop;
using MS.Win32;
using SWF = System.Windows.Forms;
using SW = System.Windows;
using SWM = System.Windows.Media;
namespace System.Windows.Forms.Integration
{
internal static class ApplicationInterop
{
[ThreadStatic]
private static WindowsFormsHostList _threadWindowsFormsHostList;
///
/// Gets a list of all of the WindowsFormsHosts which were created on the current thread.
///
internal static WindowsFormsHostList ThreadWindowsFormsHostList
{
get
{
//No synchronization required (the field is ThreadStatic)
if (null == _threadWindowsFormsHostList)
{
_threadWindowsFormsHostList = new WindowsFormsHostList();
}
return _threadWindowsFormsHostList;
}
}
[ThreadStatic]
private static bool _messageFilterInstalledOnThread;
///
/// Enables a System.Windows.Window to receive necessary keyboard
/// messages when it is opened modelessly from a Windows.Forms.Application.
///
/// The System.Windows.Window which will be opened modelessly.
public static void EnableModelessKeyboardInterop(SW.Window window)
{
//Create and add IMessageFilter
ModelessWindowFilter filter = new ModelessWindowFilter(window);
WindowFilterList.FilterList.Add(filter);
SWF.Application.AddMessageFilter(filter);
//Hook window Close event to remove IMessageFilter
window.Closed += new EventHandler(WindowFilterList.ModelessWindowClosed);
}
public static void EnableWindowsFormsInterop()
{
if (!_messageFilterInstalledOnThread)
{
SW.Interop.ComponentDispatcher.ThreadFilterMessage += new ThreadMessageEventHandler(ThreadMessageFilter);
_messageFilterInstalledOnThread = true;
}
}
// CSS added for keyboard interop
//
//
internal static void ThreadMessageFilter(ref MSG msg, ref bool outHandled)
{
// Don’t do anything if already handled
if (outHandled)
{
return;
}
Message m = Convert.ToSystemWindowsFormsMessage(msg);
// Process Winforms MessageFilters
if (Application.FilterMessage(ref m))
{
// Set the return value correctly.
outHandled = true;
return;
}
bool handled = false;
SWF.Control control = SWF.Control.FromChildHandle(m.HWnd);
if (control != null)
{
//CSS The WM_SYSCHAR special case is a workaround for a bug VSWhidbey 575729, which
//makes IsInputChar not get called with WM_SYSCHAR messages.
if (m.Msg == NativeMethods.WM_SYSCHAR)
{
handled = control.PreProcessMessage(ref m);
}
else
{
SWF.PreProcessControlState processedState = control.PreProcessControlMessage(ref m);
if (processedState == SWF.PreProcessControlState.MessageNeeded)
{
// Control didn't process message but does want the message.
UnsafeNativeMethods.TranslateMessage(ref msg);
UnsafeNativeMethods.DispatchMessage(ref msg);
handled = true;
}
else if (processedState == SWF.PreProcessControlState.MessageProcessed)
{
// Control processed the mesage
handled = true;
}
else
{
// Control doesn't need message
Debug.Assert(processedState == SWF.PreProcessControlState.MessageNotNeeded, "invalid state");
handled = false;
}
}
}
else if (msg.message != 0xc2a3) /* ControlFromHWnd == null */
{
// We are only letting the hosted control do preprocess message when it
// isn't active. All other WF controls will get PreProcessMessage at
// normal time (when focused).
foreach (WindowsFormsHost wfh in ThreadWindowsFormsHostList.ActiveWindowList())
{
if (wfh.HostContainerInternal.PreProcessMessage(ref m, false))
{
handled = true;
break;
}
}
}
// Set the return value correctly.
outHandled = handled;
return;
}
}
///
/// This singleton is used to enable Avalon Modeless Windows when using
/// the WinForms application to handle events. It keeps track of all the Avalon windows.
/// See ElementHost.EnableModelessKeyboardInterop for more info.
///
/// Since the filter information cannot be stored in the Avalon window
/// class itself, keep a list of all the Avalon windows and their filters.
/// When an avalon window is closed, remove it from the list
///
internal class WindowFilterList : WeakReferenceList
{
//Singleton instance of the list
private static WindowFilterList _filterList = new WindowFilterList();
public static WindowFilterList FilterList
{
get
{
return _filterList;
}
}
///
/// Seaches the filter list for an entry pointing to the current
/// windows.
///
///
///
static ModelessWindowFilter FindFilter(SW.Window window)
{
ModelessWindowFilter windowFilter = null;
if (window == null)
{
return null;
}
foreach (ModelessWindowFilter filter in _filterList.SnapshotListOfTargets)
{
if (filter.Window == window)
{
windowFilter = filter;
break;
}
}
Debug.Assert(windowFilter != null);
return windowFilter;
}
///
/// This callback is added to the avalon window so that its filter is removed
/// when the window is closed.
///
///
///
public static void ModelessWindowClosed(object sender, EventArgs e)
{
ModelessWindowFilter windowFilter = WindowFilterList.FindFilter(sender as SW.Window);
if (windowFilter != null)
{
SWF.Application.RemoveMessageFilter(windowFilter);
WindowFilterList.FilterList.Remove(windowFilter);
}
}
}
///
/// This message filter forwards messages to registered Avalon windows.
/// Use ElementHost.EnableModelessKeyboardInterop to setup
///
internal class ModelessWindowFilter : SWF.IMessageFilter
{
private System.Windows.Window _window;
public SW.Window Window
{
get
{
return _window;
}
}
public ModelessWindowFilter(System.Windows.Window window)
{
_window = window;
}
//Need a recursion guard for PreFilterMessage: the same message can come back to us via the
//ComponentDispatcher.
bool _inPreFilterMessage;
public bool PreFilterMessage(ref SWF.Message msg)
{
if (_window == null || !_window.IsActive)
{
return false;
}
switch (msg.Msg)
{
case NativeMethods.WM_KEYDOWN: //0x100
case NativeMethods.WM_KEYUP: //0x101
case NativeMethods.WM_CHAR: //0x102
case NativeMethods.WM_DEADCHAR: //0x103
case NativeMethods.WM_SYSKEYDOWN: //0x104
case NativeMethods.WM_SYSKEYUP: //0x105
case NativeMethods.WM_SYSCHAR: //0x106
case NativeMethods.WM_SYSDEADCHAR: //0x107
if (!_inPreFilterMessage)
{
_inPreFilterMessage = true;
try
{
SW.Interop.MSG msg2 = Convert.ToSystemWindowsInteropMSG(msg);
bool fReturn = SW.Interop.ComponentDispatcher.RaiseThreadMessage(ref msg2);
return fReturn;
}
finally
{
_inPreFilterMessage = false;
}
}
return false;
default:
return false;
}
}
}
///
/// This class make a strongly typed weak reference collection. Its enumerator
/// only returns references to live objects.
/// By not keeping a reference count on the objects in this list, they can be
/// garbage collected normally.
///
internal class WeakReferenceList where T : class
{
List _internalList;
object _syncRoot = new object();
public WeakReferenceList()
: base()
{
_internalList = new List();
}
///
/// This prunes object reference that no longer point to valid objects
/// from the list. This is called often in the current implementation,
/// but can be phased back if there are perf concerns.
///
protected void RemoveDeadReferencesFromList()
{
for (int i = _internalList.Count - 1; i >= 0; i--)
{
if (!_internalList[i].IsAlive)
{
_internalList.RemoveAt(i);
}
}
}
public List SnapshotListOfTargets
{
get
{
List targets = new List();
lock (_syncRoot)
{
RemoveDeadReferencesFromList();
foreach (WeakReference obj in _internalList)
{
//tempValue will be null if it's not alive
T tempValue = obj.Target as T;
if (tempValue != null)
{
targets.Add(tempValue);
}
}
}
return targets;
}
}
public void Add(T obj)
{
lock (_syncRoot)
{
RemoveDeadReferencesFromList();
WeakReference newItem = new WeakReference(obj, false);
_internalList.Add(newItem);
}
}
internal int IndexOf(T obj)
{
{
RemoveDeadReferencesFromList();
for (int i = 0; i < _internalList.Count; i++)
{
if (_internalList[i].IsAlive)
{
if (_internalList[i].Target as T == obj)
{
return i;
}
}
}
return -1;
}
}
public bool Remove(T obj)
{
lock (_syncRoot)
{
int index = IndexOf(obj);
if (index >= 0)
{
_internalList.RemoveAt(index);
return true;
}
return false;
}
}
}
internal class WindowsFormsHostList : WeakReferenceList
{
public IEnumerable ActiveWindowList()
{
SW.Window rootWindow = null;
foreach (WindowsFormsHost wfh in this.SnapshotListOfTargets)
{
rootWindow = FindRootVisual(wfh) as SW.Window;
if (rootWindow != null)
{
if (rootWindow.IsActive)
{
yield return wfh;
}
}
}
}
private static SWM.Visual FindRootVisual(SWM.Visual x)
{
return (PresentationSource.FromVisual(x) != null) ? (PresentationSource.FromVisual(x)).RootVisual : null;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Windows.Interop;
using MS.Win32;
using SWF = System.Windows.Forms;
using SW = System.Windows;
using SWM = System.Windows.Media;
namespace System.Windows.Forms.Integration
{
internal static class ApplicationInterop
{
[ThreadStatic]
private static WindowsFormsHostList _threadWindowsFormsHostList;
///
/// Gets a list of all of the WindowsFormsHosts which were created on the current thread.
///
internal static WindowsFormsHostList ThreadWindowsFormsHostList
{
get
{
//No synchronization required (the field is ThreadStatic)
if (null == _threadWindowsFormsHostList)
{
_threadWindowsFormsHostList = new WindowsFormsHostList();
}
return _threadWindowsFormsHostList;
}
}
[ThreadStatic]
private static bool _messageFilterInstalledOnThread;
///
/// Enables a System.Windows.Window to receive necessary keyboard
/// messages when it is opened modelessly from a Windows.Forms.Application.
///
/// The System.Windows.Window which will be opened modelessly.
public static void EnableModelessKeyboardInterop(SW.Window window)
{
//Create and add IMessageFilter
ModelessWindowFilter filter = new ModelessWindowFilter(window);
WindowFilterList.FilterList.Add(filter);
SWF.Application.AddMessageFilter(filter);
//Hook window Close event to remove IMessageFilter
window.Closed += new EventHandler(WindowFilterList.ModelessWindowClosed);
}
public static void EnableWindowsFormsInterop()
{
if (!_messageFilterInstalledOnThread)
{
SW.Interop.ComponentDispatcher.ThreadFilterMessage += new ThreadMessageEventHandler(ThreadMessageFilter);
_messageFilterInstalledOnThread = true;
}
}
// CSS added for keyboard interop
//
//
internal static void ThreadMessageFilter(ref MSG msg, ref bool outHandled)
{
// Don’t do anything if already handled
if (outHandled)
{
return;
}
Message m = Convert.ToSystemWindowsFormsMessage(msg);
// Process Winforms MessageFilters
if (Application.FilterMessage(ref m))
{
// Set the return value correctly.
outHandled = true;
return;
}
bool handled = false;
SWF.Control control = SWF.Control.FromChildHandle(m.HWnd);
if (control != null)
{
//CSS The WM_SYSCHAR special case is a workaround for a bug VSWhidbey 575729, which
//makes IsInputChar not get called with WM_SYSCHAR messages.
if (m.Msg == NativeMethods.WM_SYSCHAR)
{
handled = control.PreProcessMessage(ref m);
}
else
{
SWF.PreProcessControlState processedState = control.PreProcessControlMessage(ref m);
if (processedState == SWF.PreProcessControlState.MessageNeeded)
{
// Control didn't process message but does want the message.
UnsafeNativeMethods.TranslateMessage(ref msg);
UnsafeNativeMethods.DispatchMessage(ref msg);
handled = true;
}
else if (processedState == SWF.PreProcessControlState.MessageProcessed)
{
// Control processed the mesage
handled = true;
}
else
{
// Control doesn't need message
Debug.Assert(processedState == SWF.PreProcessControlState.MessageNotNeeded, "invalid state");
handled = false;
}
}
}
else if (msg.message != 0xc2a3) /* ControlFromHWnd == null */
{
// We are only letting the hosted control do preprocess message when it
// isn't active. All other WF controls will get PreProcessMessage at
// normal time (when focused).
foreach (WindowsFormsHost wfh in ThreadWindowsFormsHostList.ActiveWindowList())
{
if (wfh.HostContainerInternal.PreProcessMessage(ref m, false))
{
handled = true;
break;
}
}
}
// Set the return value correctly.
outHandled = handled;
return;
}
}
///
/// This singleton is used to enable Avalon Modeless Windows when using
/// the WinForms application to handle events. It keeps track of all the Avalon windows.
/// See ElementHost.EnableModelessKeyboardInterop for more info.
///
/// Since the filter information cannot be stored in the Avalon window
/// class itself, keep a list of all the Avalon windows and their filters.
/// When an avalon window is closed, remove it from the list
///
internal class WindowFilterList : WeakReferenceList
{
//Singleton instance of the list
private static WindowFilterList _filterList = new WindowFilterList();
public static WindowFilterList FilterList
{
get
{
return _filterList;
}
}
///
/// Seaches the filter list for an entry pointing to the current
/// windows.
///
///
///
static ModelessWindowFilter FindFilter(SW.Window window)
{
ModelessWindowFilter windowFilter = null;
if (window == null)
{
return null;
}
foreach (ModelessWindowFilter filter in _filterList.SnapshotListOfTargets)
{
if (filter.Window == window)
{
windowFilter = filter;
break;
}
}
Debug.Assert(windowFilter != null);
return windowFilter;
}
///
/// This callback is added to the avalon window so that its filter is removed
/// when the window is closed.
///
///
///
public static void ModelessWindowClosed(object sender, EventArgs e)
{
ModelessWindowFilter windowFilter = WindowFilterList.FindFilter(sender as SW.Window);
if (windowFilter != null)
{
SWF.Application.RemoveMessageFilter(windowFilter);
WindowFilterList.FilterList.Remove(windowFilter);
}
}
}
///
/// This message filter forwards messages to registered Avalon windows.
/// Use ElementHost.EnableModelessKeyboardInterop to setup
///
internal class ModelessWindowFilter : SWF.IMessageFilter
{
private System.Windows.Window _window;
public SW.Window Window
{
get
{
return _window;
}
}
public ModelessWindowFilter(System.Windows.Window window)
{
_window = window;
}
//Need a recursion guard for PreFilterMessage: the same message can come back to us via the
//ComponentDispatcher.
bool _inPreFilterMessage;
public bool PreFilterMessage(ref SWF.Message msg)
{
if (_window == null || !_window.IsActive)
{
return false;
}
switch (msg.Msg)
{
case NativeMethods.WM_KEYDOWN: //0x100
case NativeMethods.WM_KEYUP: //0x101
case NativeMethods.WM_CHAR: //0x102
case NativeMethods.WM_DEADCHAR: //0x103
case NativeMethods.WM_SYSKEYDOWN: //0x104
case NativeMethods.WM_SYSKEYUP: //0x105
case NativeMethods.WM_SYSCHAR: //0x106
case NativeMethods.WM_SYSDEADCHAR: //0x107
if (!_inPreFilterMessage)
{
_inPreFilterMessage = true;
try
{
SW.Interop.MSG msg2 = Convert.ToSystemWindowsInteropMSG(msg);
bool fReturn = SW.Interop.ComponentDispatcher.RaiseThreadMessage(ref msg2);
return fReturn;
}
finally
{
_inPreFilterMessage = false;
}
}
return false;
default:
return false;
}
}
}
///
/// This class make a strongly typed weak reference collection. Its enumerator
/// only returns references to live objects.
/// By not keeping a reference count on the objects in this list, they can be
/// garbage collected normally.
///
internal class WeakReferenceList where T : class
{
List _internalList;
object _syncRoot = new object();
public WeakReferenceList()
: base()
{
_internalList = new List();
}
///
/// This prunes object reference that no longer point to valid objects
/// from the list. This is called often in the current implementation,
/// but can be phased back if there are perf concerns.
///
protected void RemoveDeadReferencesFromList()
{
for (int i = _internalList.Count - 1; i >= 0; i--)
{
if (!_internalList[i].IsAlive)
{
_internalList.RemoveAt(i);
}
}
}
public List SnapshotListOfTargets
{
get
{
List targets = new List();
lock (_syncRoot)
{
RemoveDeadReferencesFromList();
foreach (WeakReference obj in _internalList)
{
//tempValue will be null if it's not alive
T tempValue = obj.Target as T;
if (tempValue != null)
{
targets.Add(tempValue);
}
}
}
return targets;
}
}
public void Add(T obj)
{
lock (_syncRoot)
{
RemoveDeadReferencesFromList();
WeakReference newItem = new WeakReference(obj, false);
_internalList.Add(newItem);
}
}
internal int IndexOf(T obj)
{
{
RemoveDeadReferencesFromList();
for (int i = 0; i < _internalList.Count; i++)
{
if (_internalList[i].IsAlive)
{
if (_internalList[i].Target as T == obj)
{
return i;
}
}
}
return -1;
}
}
public bool Remove(T obj)
{
lock (_syncRoot)
{
int index = IndexOf(obj);
if (index >= 0)
{
_internalList.RemoveAt(index);
return true;
}
return false;
}
}
}
internal class WindowsFormsHostList : WeakReferenceList
{
public IEnumerable ActiveWindowList()
{
SW.Window rootWindow = null;
foreach (WindowsFormsHost wfh in this.SnapshotListOfTargets)
{
rootWindow = FindRootVisual(wfh) as SW.Window;
if (rootWindow != null)
{
if (rootWindow.IsActive)
{
yield return wfh;
}
}
}
}
private static SWM.Visual FindRootVisual(SWM.Visual x)
{
return (PresentationSource.FromVisual(x) != null) ? (PresentationSource.FromVisual(x)).RootVisual : null;
}
}
}
// 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
- Viewport3DVisual.cs
- CodeMemberMethod.cs
- OuterGlowBitmapEffect.cs
- TextBoxBase.cs
- ImageKeyConverter.cs
- CriticalHandle.cs
- MetafileHeader.cs
- StreamBodyWriter.cs
- DeflateEmulationStream.cs
- CmsInterop.cs
- BufferAllocator.cs
- FixedStringLookup.cs
- XmlCollation.cs
- ViewStateModeByIdAttribute.cs
- EventProxy.cs
- ParagraphVisual.cs
- WaitForChangedResult.cs
- ActiveXSite.cs
- ObjectStateEntryBaseUpdatableDataRecord.cs
- QilExpression.cs
- VirtualizedItemPattern.cs
- DoubleLink.cs
- ScrollEventArgs.cs
- ProfilePropertyNameValidator.cs
- CrossSiteScriptingValidation.cs
- XmlTextReaderImpl.cs
- EUCJPEncoding.cs
- XPathAncestorQuery.cs
- SerializeAbsoluteContext.cs
- XmlSchema.cs
- Util.cs
- ControlPropertyNameConverter.cs
- ExtenderControl.cs
- ContextStack.cs
- PointLight.cs
- XsdBuilder.cs
- StorageMappingItemLoader.cs
- BlurBitmapEffect.cs
- StateRuntime.cs
- WindowsTokenRoleProvider.cs
- MultiBindingExpression.cs
- TCPListener.cs
- DiscriminatorMap.cs
- NetMsmqSecurity.cs
- TrackBarRenderer.cs
- EntityClientCacheEntry.cs
- Page.cs
- DecodeHelper.cs
- RequestTimeoutManager.cs
- ReadOnlyPermissionSet.cs
- HtmlInputControl.cs
- AnnotationHelper.cs
- DictionarySectionHandler.cs
- TextDecorationCollectionConverter.cs
- TextEditorTables.cs
- FlowLayoutPanelDesigner.cs
- RewritingProcessor.cs
- PasswordBox.cs
- LogRestartAreaEnumerator.cs
- DirectoryNotFoundException.cs
- Subtract.cs
- TimeSpanMinutesConverter.cs
- PerformanceCountersElement.cs
- UserInitiatedNavigationPermission.cs
- FtpWebResponse.cs
- PasswordTextContainer.cs
- AnimatedTypeHelpers.cs
- FieldNameLookup.cs
- IdentityHolder.cs
- SourceLineInfo.cs
- HtmlSelect.cs
- PrintPreviewGraphics.cs
- StringPropertyBuilder.cs
- DBParameter.cs
- WindowsGraphics.cs
- MimeBasePart.cs
- DateTimeUtil.cs
- ZipPackage.cs
- GenericIdentity.cs
- EntityAdapter.cs
- RTLAwareMessageBox.cs
- SchemaTypeEmitter.cs
- ColorPalette.cs
- SynchronizedInputHelper.cs
- OrderByQueryOptionExpression.cs
- MarkupCompilePass2.cs
- UnsafeNativeMethods.cs
- XmlFormatReaderGenerator.cs
- DynamicDocumentPaginator.cs
- DataGridViewRowCancelEventArgs.cs
- CanonicalFontFamilyReference.cs
- PixelShader.cs
- ToolStripOverflow.cs
- BrowserCapabilitiesCompiler.cs
- XhtmlTextWriter.cs
- Form.cs
- ClaimSet.cs
- AlternateViewCollection.cs
- Registry.cs
- EncodingDataItem.cs