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 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
- EditorResources.cs
- DtrList.cs
- SqlMethods.cs
- NetDispatcherFaultException.cs
- relpropertyhelper.cs
- Preprocessor.cs
- Sql8ExpressionRewriter.cs
- Certificate.cs
- InputLangChangeRequestEvent.cs
- EntityException.cs
- ColorConverter.cs
- TextAdaptor.cs
- Page.cs
- Constant.cs
- PriorityBindingExpression.cs
- AsymmetricSecurityProtocolFactory.cs
- InputProcessorProfiles.cs
- PackWebResponse.cs
- IIS7WorkerRequest.cs
- XmlSchemaImporter.cs
- Psha1DerivedKeyGenerator.cs
- ScriptHandlerFactory.cs
- GeometryCombineModeValidation.cs
- CodeRegionDirective.cs
- SqlSupersetValidator.cs
- ColumnWidthChangingEvent.cs
- EntityContainer.cs
- ListArgumentProvider.cs
- WindowsRichEditRange.cs
- WebPartCatalogCloseVerb.cs
- TableStyle.cs
- Win32SafeHandles.cs
- Base64Stream.cs
- RequestChannelBinder.cs
- AttachedAnnotationChangedEventArgs.cs
- DbProviderFactories.cs
- PointAnimation.cs
- ColorConvertedBitmap.cs
- recordstatescratchpad.cs
- ReadOnlyHierarchicalDataSource.cs
- XPathScanner.cs
- TrustManagerMoreInformation.cs
- CodeTypeDeclarationCollection.cs
- BooleanSwitch.cs
- CaretElement.cs
- SiteMapDataSource.cs
- DataGridLinkButton.cs
- HtmlTableRowCollection.cs
- VBIdentifierTrimConverter.cs
- XmlNodeComparer.cs
- WebBaseEventKeyComparer.cs
- SizeFConverter.cs
- RelationshipDetailsRow.cs
- ImagingCache.cs
- util.cs
- ProtectedConfiguration.cs
- TemplatedMailWebEventProvider.cs
- LogEntrySerializer.cs
- CodeDOMUtility.cs
- ErrorFormatterPage.cs
- ClientConvert.cs
- ImportCatalogPart.cs
- SQLResource.cs
- DynamicValueConverter.cs
- CookieHandler.cs
- SplitterEvent.cs
- HashSet.cs
- ToolStripDropDownClosedEventArgs.cs
- COSERVERINFO.cs
- SqlColumnizer.cs
- XmlDocument.cs
- TCPListener.cs
- QuerySelectOp.cs
- TransformerConfigurationWizardBase.cs
- PartitionResolver.cs
- MenuAutoFormat.cs
- UrlMappingCollection.cs
- ListControl.cs
- PropertyDescriptorCollection.cs
- CompositeControlDesigner.cs
- TextFormatterImp.cs
- BinaryParser.cs
- ImportOptions.cs
- StyleCollection.cs
- TextEditorTables.cs
- XmlSchemaSet.cs
- DynamicPhysicalDiscoSearcher.cs
- ExecutionEngineException.cs
- AsyncSerializedWorker.cs
- SourceElementsCollection.cs
- NetSectionGroup.cs
- DocumentScope.cs
- ProcessHostConfigUtils.cs
- ManagedIStream.cs
- ToolStripGripRenderEventArgs.cs
- Hex.cs
- RefreshInfo.cs
- AlternationConverter.cs
- DataGrid.cs
- DecimalConverter.cs