Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / 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 WeakReferenceListwhere 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 ListSnapshotListOfTargets { 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 WeakReferenceListwhere 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 ListSnapshotListOfTargets { 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
- WebPartRestoreVerb.cs
- ToolStripRenderer.cs
- DbConnectionStringCommon.cs
- ByteAnimationBase.cs
- SqlXmlStorage.cs
- RichTextBoxConstants.cs
- PackagingUtilities.cs
- DatePickerTextBox.cs
- DetailsViewCommandEventArgs.cs
- XmlCountingReader.cs
- PinnedBufferMemoryStream.cs
- CodeDefaultValueExpression.cs
- ApplicationContext.cs
- DoubleConverter.cs
- ToolboxItem.cs
- WCFServiceClientProxyGenerator.cs
- Matrix3DStack.cs
- SystemIcons.cs
- InertiaTranslationBehavior.cs
- QilReplaceVisitor.cs
- LogAppendAsyncResult.cs
- XmlMtomReader.cs
- ViewGenerator.cs
- FilterFactory.cs
- WebHttpSecurityModeHelper.cs
- counter.cs
- DataQuery.cs
- QilInvokeLateBound.cs
- ConfigurationLocationCollection.cs
- TraceContextRecord.cs
- TraceUtility.cs
- WindowsFormsDesignerOptionService.cs
- bidPrivateBase.cs
- SqlDataReader.cs
- SiteMapNodeItem.cs
- WebPartVerbsEventArgs.cs
- PageRanges.cs
- TableSectionStyle.cs
- ClassImporter.cs
- ThreadStartException.cs
- ZoomPercentageConverter.cs
- ComponentCommands.cs
- EntitySet.cs
- DuplicateWaitObjectException.cs
- XPathException.cs
- TransportConfigurationTypeElementCollection.cs
- ToolboxItemAttribute.cs
- IfAction.cs
- IntSecurity.cs
- AnnotationAdorner.cs
- NonClientArea.cs
- SamlDelegatingWriter.cs
- TextContainerHelper.cs
- TransformPatternIdentifiers.cs
- SharedConnectionInfo.cs
- ProtocolsConfigurationHandler.cs
- ResourceIDHelper.cs
- LabelEditEvent.cs
- SimpleMailWebEventProvider.cs
- ExpressionParser.cs
- OperationParameterInfoCollection.cs
- WarningException.cs
- _TLSstream.cs
- StatusStrip.cs
- EnumMember.cs
- DeploymentSection.cs
- TaiwanLunisolarCalendar.cs
- _ListenerResponseStream.cs
- SynchronizationContext.cs
- ServerIdentity.cs
- DrawTreeNodeEventArgs.cs
- BamlTreeMap.cs
- Wow64ConfigurationLoader.cs
- InstanceCreationEditor.cs
- ValuePattern.cs
- SrgsSubset.cs
- SerializationStore.cs
- EntityRecordInfo.cs
- SignedInfo.cs
- BamlResourceDeserializer.cs
- XamlBrushSerializer.cs
- XamlTemplateSerializer.cs
- SystemIPv4InterfaceProperties.cs
- SqlClientMetaDataCollectionNames.cs
- WebPartMinimizeVerb.cs
- EditorResources.cs
- IpcClientManager.cs
- NotifyCollectionChangedEventArgs.cs
- FamilyTypeface.cs
- IdentitySection.cs
- InputBindingCollection.cs
- DocumentPageView.cs
- EventProviderWriter.cs
- QuerySettings.cs
- FlowPosition.cs
- Int32CollectionValueSerializer.cs
- CharacterMetricsDictionary.cs
- IgnoreSectionHandler.cs
- ResourceCategoryAttribute.cs
- X509Chain.cs