Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Integration / System / Windows / Integration / ApplicationInterop.cs / 2 / 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.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- GenericEnumerator.cs
- EnumValidator.cs
- RowToParametersTransformer.cs
- ModulesEntry.cs
- DrawListViewSubItemEventArgs.cs
- SizeChangedEventArgs.cs
- MultiBindingExpression.cs
- DynamicVirtualDiscoSearcher.cs
- DataGridViewComboBoxCell.cs
- ControlCachePolicy.cs
- FacetEnabledSchemaElement.cs
- SqlFunctionAttribute.cs
- TokenBasedSetEnumerator.cs
- HttpHostedTransportConfiguration.cs
- CachedCompositeFamily.cs
- MsmqBindingBase.cs
- ExpressionDumper.cs
- SymmetricAlgorithm.cs
- FrugalMap.cs
- Viewport3DVisual.cs
- XmlSiteMapProvider.cs
- ResourcesChangeInfo.cs
- Span.cs
- ButtonFlatAdapter.cs
- TableLayoutPanelResizeGlyph.cs
- BaseResourcesBuildProvider.cs
- CreatingCookieEventArgs.cs
- QueryMath.cs
- BitmapFrameDecode.cs
- brushes.cs
- GridPatternIdentifiers.cs
- HttpClientCertificate.cs
- TemplateParser.cs
- OciHandle.cs
- AspProxy.cs
- followingsibling.cs
- RoutedCommand.cs
- GridEntry.cs
- HierarchicalDataBoundControl.cs
- Transform.cs
- GroupBoxDesigner.cs
- ContractHandle.cs
- RequestCacheValidator.cs
- XmlSchemaSimpleType.cs
- GroupBox.cs
- ResourcePool.cs
- ScrollEvent.cs
- ParameterElementCollection.cs
- WindowsStatusBar.cs
- ViewCellSlot.cs
- SafeNativeMethods.cs
- XmlSchemaImporter.cs
- EdmRelationshipRoleAttribute.cs
- EventListenerClientSide.cs
- ReadOnlyDictionary.cs
- EncryptedData.cs
- MissingSatelliteAssemblyException.cs
- EntityConnection.cs
- StringBuilder.cs
- IntSecurity.cs
- TransformerInfoCollection.cs
- CompositeFontInfo.cs
- TableStyle.cs
- OdbcCommandBuilder.cs
- HttpResponse.cs
- EncoderFallback.cs
- EntityAdapter.cs
- CompilerScopeManager.cs
- OptimalBreakSession.cs
- AuthorizationContext.cs
- Figure.cs
- FlowDocumentReaderAutomationPeer.cs
- Group.cs
- QueryConverter.cs
- SoapMessage.cs
- WindowsTreeView.cs
- SystemWebExtensionsSectionGroup.cs
- LinqDataSourceDeleteEventArgs.cs
- CustomLineCap.cs
- ListChangedEventArgs.cs
- PropertyGeneratedEventArgs.cs
- documentation.cs
- EventToken.cs
- FolderBrowserDialog.cs
- TreeWalker.cs
- SeverityFilter.cs
- TreeNodeCollection.cs
- MappingMetadataHelper.cs
- ReachPageContentCollectionSerializer.cs
- Opcode.cs
- SystemIPGlobalProperties.cs
- DrawingDrawingContext.cs
- SystemWebSectionGroup.cs
- WebServiceFault.cs
- UnsafeNativeMethodsMilCoreApi.cs
- EntryIndex.cs
- securestring.cs
- DispatcherExceptionEventArgs.cs
- TextOutput.cs
- DataTableNameHandler.cs