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
- _ConnectionGroup.cs
- ExtensionQuery.cs
- DateTime.cs
- ipaddressinformationcollection.cs
- SecurityContextSecurityToken.cs
- ObjectDataSourceChooseTypePanel.cs
- Input.cs
- ResourceIDHelper.cs
- RolePrincipal.cs
- XmlSchemaRedefine.cs
- MbpInfo.cs
- arabicshape.cs
- XmlSerializer.cs
- SoapRpcServiceAttribute.cs
- DebugController.cs
- ThicknessAnimationUsingKeyFrames.cs
- NativeMethods.cs
- EffectiveValueEntry.cs
- FrameworkTextComposition.cs
- EntityStoreSchemaGenerator.cs
- UnsafeNativeMethods.cs
- EdmProviderManifest.cs
- Decoder.cs
- JoinCqlBlock.cs
- X509SubjectKeyIdentifierClause.cs
- DataControlField.cs
- DataGridRowHeaderAutomationPeer.cs
- HtmlWindow.cs
- NavigationPropertyEmitter.cs
- DeclarationUpdate.cs
- EmptyControlCollection.cs
- ConfigurationElement.cs
- XmlLinkedNode.cs
- SqlFlattener.cs
- Rules.cs
- SplashScreenNativeMethods.cs
- TypeElement.cs
- AliasGenerator.cs
- InvokeBase.cs
- RadioButton.cs
- SecondaryViewProvider.cs
- RequestCachePolicy.cs
- ConnectionsZone.cs
- BindingContext.cs
- Emitter.cs
- HttpVersion.cs
- UpdateCommand.cs
- COM2ColorConverter.cs
- SizeValueSerializer.cs
- ItemPager.cs
- SqlUnionizer.cs
- WebPart.cs
- CodeTypeReferenceExpression.cs
- SystemResourceKey.cs
- AssertSection.cs
- AnchorEditor.cs
- _ListenerAsyncResult.cs
- AspCompat.cs
- CodeTypeMemberCollection.cs
- EntityTypeEmitter.cs
- TreeViewDesigner.cs
- XamlFigureLengthSerializer.cs
- PaperSize.cs
- PaintEvent.cs
- ISO2022Encoding.cs
- ExpressionEditorSheet.cs
- PrefixHandle.cs
- GrammarBuilderPhrase.cs
- figurelengthconverter.cs
- codemethodreferenceexpression.cs
- URIFormatException.cs
- TrackingParticipant.cs
- ListControlBoundActionList.cs
- MessageBox.cs
- OracleBoolean.cs
- HeaderPanel.cs
- PropertyEmitterBase.cs
- DropSourceBehavior.cs
- ActivityCompletionCallbackWrapper.cs
- FrameDimension.cs
- DataListCommandEventArgs.cs
- XmlDigitalSignatureProcessor.cs
- AlternateViewCollection.cs
- CombinedGeometry.cs
- ControlCommandSet.cs
- MatrixKeyFrameCollection.cs
- KnownTypes.cs
- DrawingContext.cs
- CodePrimitiveExpression.cs
- ResourcePropertyMemberCodeDomSerializer.cs
- BroadcastEventHelper.cs
- WindowsFont.cs
- CodeAttributeArgument.cs
- Pen.cs
- ConfigurationElementProperty.cs
- PasswordBox.cs
- PagePropertiesChangingEventArgs.cs
- XpsThumbnail.cs
- Int32Storage.cs
- TextServicesManager.cs