Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Framework / System / Windows / Controls / SoundPlayerAction.cs / 1 / SoundPlayerAction.cs
/****************************************************************************\ * * File: SoundPlayerAction.cs * * A SoundPlayerAction causes a sound to be played in response to a trigger. * * Copyright (C) by Microsoft Corporation. All rights reserved. * \***************************************************************************/ using MS.Internal; using MS.Internal.PresentationFramework; using MS.Utility; using System; using System.Collections; using System.ComponentModel; // DefaultValueAttribute using System.IO; using System.IO.Packaging; using System.Media; using System.Net; using System.Windows; using System.Windows.Documents; using System.Windows.Markup; using System.Windows.Media; using System.Windows.Navigation; using System.Windows.Threading; using System.Diagnostics; using System.Runtime.InteropServices; using System.Runtime.Remoting; using System.Security; using System.Security.Permissions; namespace System.Windows.Controls { ////// A class that describes a sound playback action to perform for a trigger /// [RuntimeNameProperty("Name")] // Enables INameScope.FindName to find SoundPlayerAction objects. public class SoundPlayerAction : TriggerAction, IDisposable { ////// Creates an instance of the SoundPlayerAction object. /// public SoundPlayerAction() : base() { } ////// Dispose. /// public void Dispose() { if (m_player != null) { m_player.Dispose(); } } ////// DependencyProperty for Source /// public static readonly DependencyProperty SourceProperty = DependencyProperty.Register( "Source", typeof(Uri), typeof(SoundPlayerAction), new FrameworkPropertyMetadata( new PropertyChangedCallback(OnSourceChanged))); ////// A class that describes a sound playback action to perform for a trigger /// public Uri Source { get { return (Uri)GetValue(SourceProperty); } set { SetValue(SourceProperty, value); } } private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { SoundPlayerAction soundPlayerAction = (SoundPlayerAction)d; soundPlayerAction.OnSourceChangedHelper((Uri)e.NewValue); } // To avoid blocking the UI thread, SoundPlayerAction performs an asynchronous // download of the WebResponse and later, the response Stream. However, // PackWebRequest does not support the asynchonous Begin/EndGetResponse pattern. // To work around this, we use our own asynchronous worker pool thread, // and then use the regular synchronous WebRequest.GetResponse() method. // Once we obtain the WebResponse, we will use SoundPlayer's async API // to download the content of the stream. private void OnSourceChangedHelper(Uri newValue) { if (newValue == null || newValue.IsAbsoluteUri) { m_lastRequestedAbsoluteUri = newValue; } else { // When we are given a relative Uri path, expand to an absolute Uri by resolving // it against the Application's base Uri. This would typically return a Pack Uri. m_lastRequestedAbsoluteUri = BaseUriHelper.GetResolvedUri(BaseUriHelper.BaseUri, newValue); } // Invalidate items that depend on the Source uri m_player = null; m_playRequested = false; // Suppress earlier requests to Play the sound if (m_streamLoadInProgress) { // There is already a worker thread downloading the previous URI stream, // or the SoundPlayer is copying the stream into its buffer. Make a note // that the URI has been changed and we will have to reload everything. m_uriChangedWhileLoadingStream = true; } else { BeginLoadStream(); } } ////// Invoke the SoundPlayer action. /// internal sealed override void Invoke(FrameworkElement el, FrameworkContentElement ctntEl, Style targetStyle, FrameworkTemplate targetTemplate, Int64 layer) { PlayWhenLoaded(); } ////// invoke the SoundPlayer action. /// internal sealed override void Invoke(FrameworkElement el) { PlayWhenLoaded(); } ////// Plays the /// private void PlayWhenLoaded() { if (m_streamLoadInProgress) { m_playRequested = true; } else if (m_player != null) { // If the Player has not yet loaded, m_streamLoadInProgress must be true Debug.Assert(m_player.IsLoadCompleted); m_player.Play(); } } private void BeginLoadStream() { if (m_lastRequestedAbsoluteUri != null) // Only reload if the new source is non-null { m_streamLoadInProgress = true; // Step 1: Perform an asynchronous load of the WebResponse and its associated Stream LoadStreamCaller downloadStreamCaller = new LoadStreamCaller(LoadStreamAsync); IAsyncResult asyncResult = downloadStreamCaller.BeginInvoke(m_lastRequestedAbsoluteUri, new AsyncCallback(LoadStreamCallback), downloadStreamCaller); } } private delegate Stream LoadStreamCaller(Uri uri); ////// This is the actual code that runs in our worker thread. /// private Stream LoadStreamAsync(Uri uri) { return WpfWebRequestHelper.CreateRequestAndGetResponseStream(uri); } ////// This code runs in the worker thread when LoadStreamAsync() finishes. /// /// private void LoadStreamCallback(IAsyncResult asyncResult) { // Now have the UI thread regain control and initialize the SoundPlayer DispatcherOperationCallback loadStreamCompletedCaller = new DispatcherOperationCallback(OnLoadStreamCompleted); Dispatcher.BeginInvoke(DispatcherPriority.Normal, loadStreamCompletedCaller, asyncResult); } ////// Called on the UI thread when the Stream object is initialized. /// Begins asynchronous download of the Stream content into SoundPlayer's local buffer. /// private Object OnLoadStreamCompleted(Object asyncResultArg) { // Necessary for proper cleanup of async resources IAsyncResult asyncResult = (IAsyncResult)asyncResultArg; LoadStreamCaller caller = (LoadStreamCaller)asyncResult.AsyncState; Stream newStream = caller.EndInvoke(asyncResult); if (m_uriChangedWhileLoadingStream) // The source URI was changed, redo Stream loading { m_uriChangedWhileLoadingStream = false; if (newStream != null) // Don't hold on to the new stream - it's not needed anymore { newStream.Dispose(); } BeginLoadStream(); } else if (newStream != null) // We loaded the Stream, begin buffering it { if (m_player == null) { m_player = new SoundPlayer((Stream)newStream); } else { m_player.Stream = (Stream)newStream; } m_player.LoadCompleted += new AsyncCompletedEventHandler(OnSoundPlayerLoadCompleted); m_player.LoadAsync(); // Begin preloading the stream into SoundPlayer's local buffer } return null; } private void OnSoundPlayerLoadCompleted(Object sender, AsyncCompletedEventArgs e) { Debug.Assert(Object.ReferenceEquals(m_player, sender)); Debug.Assert(m_player.IsLoadCompleted); if (m_uriChangedWhileLoadingStream) // The source URI was changed, redo Stream loading again { m_player = null; m_uriChangedWhileLoadingStream = false; BeginLoadStream(); } else { m_streamLoadInProgress = false; if (m_playRequested) // URI is correct, m_player is ready, play it if requested { m_playRequested = false; m_player.Play(); } } } private SoundPlayer m_player; private Uri m_lastRequestedAbsoluteUri; private bool m_streamLoadInProgress; private bool m_playRequested; private bool m_uriChangedWhileLoadingStream; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. /****************************************************************************\ * * File: SoundPlayerAction.cs * * A SoundPlayerAction causes a sound to be played in response to a trigger. * * Copyright (C) by Microsoft Corporation. All rights reserved. * \***************************************************************************/ using MS.Internal; using MS.Internal.PresentationFramework; using MS.Utility; using System; using System.Collections; using System.ComponentModel; // DefaultValueAttribute using System.IO; using System.IO.Packaging; using System.Media; using System.Net; using System.Windows; using System.Windows.Documents; using System.Windows.Markup; using System.Windows.Media; using System.Windows.Navigation; using System.Windows.Threading; using System.Diagnostics; using System.Runtime.InteropServices; using System.Runtime.Remoting; using System.Security; using System.Security.Permissions; namespace System.Windows.Controls { ////// A class that describes a sound playback action to perform for a trigger /// [RuntimeNameProperty("Name")] // Enables INameScope.FindName to find SoundPlayerAction objects. public class SoundPlayerAction : TriggerAction, IDisposable { ////// Creates an instance of the SoundPlayerAction object. /// public SoundPlayerAction() : base() { } ////// Dispose. /// public void Dispose() { if (m_player != null) { m_player.Dispose(); } } ////// DependencyProperty for Source /// public static readonly DependencyProperty SourceProperty = DependencyProperty.Register( "Source", typeof(Uri), typeof(SoundPlayerAction), new FrameworkPropertyMetadata( new PropertyChangedCallback(OnSourceChanged))); ////// A class that describes a sound playback action to perform for a trigger /// public Uri Source { get { return (Uri)GetValue(SourceProperty); } set { SetValue(SourceProperty, value); } } private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { SoundPlayerAction soundPlayerAction = (SoundPlayerAction)d; soundPlayerAction.OnSourceChangedHelper((Uri)e.NewValue); } // To avoid blocking the UI thread, SoundPlayerAction performs an asynchronous // download of the WebResponse and later, the response Stream. However, // PackWebRequest does not support the asynchonous Begin/EndGetResponse pattern. // To work around this, we use our own asynchronous worker pool thread, // and then use the regular synchronous WebRequest.GetResponse() method. // Once we obtain the WebResponse, we will use SoundPlayer's async API // to download the content of the stream. private void OnSourceChangedHelper(Uri newValue) { if (newValue == null || newValue.IsAbsoluteUri) { m_lastRequestedAbsoluteUri = newValue; } else { // When we are given a relative Uri path, expand to an absolute Uri by resolving // it against the Application's base Uri. This would typically return a Pack Uri. m_lastRequestedAbsoluteUri = BaseUriHelper.GetResolvedUri(BaseUriHelper.BaseUri, newValue); } // Invalidate items that depend on the Source uri m_player = null; m_playRequested = false; // Suppress earlier requests to Play the sound if (m_streamLoadInProgress) { // There is already a worker thread downloading the previous URI stream, // or the SoundPlayer is copying the stream into its buffer. Make a note // that the URI has been changed and we will have to reload everything. m_uriChangedWhileLoadingStream = true; } else { BeginLoadStream(); } } ////// Invoke the SoundPlayer action. /// internal sealed override void Invoke(FrameworkElement el, FrameworkContentElement ctntEl, Style targetStyle, FrameworkTemplate targetTemplate, Int64 layer) { PlayWhenLoaded(); } ////// invoke the SoundPlayer action. /// internal sealed override void Invoke(FrameworkElement el) { PlayWhenLoaded(); } ////// Plays the /// private void PlayWhenLoaded() { if (m_streamLoadInProgress) { m_playRequested = true; } else if (m_player != null) { // If the Player has not yet loaded, m_streamLoadInProgress must be true Debug.Assert(m_player.IsLoadCompleted); m_player.Play(); } } private void BeginLoadStream() { if (m_lastRequestedAbsoluteUri != null) // Only reload if the new source is non-null { m_streamLoadInProgress = true; // Step 1: Perform an asynchronous load of the WebResponse and its associated Stream LoadStreamCaller downloadStreamCaller = new LoadStreamCaller(LoadStreamAsync); IAsyncResult asyncResult = downloadStreamCaller.BeginInvoke(m_lastRequestedAbsoluteUri, new AsyncCallback(LoadStreamCallback), downloadStreamCaller); } } private delegate Stream LoadStreamCaller(Uri uri); ////// This is the actual code that runs in our worker thread. /// private Stream LoadStreamAsync(Uri uri) { return WpfWebRequestHelper.CreateRequestAndGetResponseStream(uri); } ////// This code runs in the worker thread when LoadStreamAsync() finishes. /// /// private void LoadStreamCallback(IAsyncResult asyncResult) { // Now have the UI thread regain control and initialize the SoundPlayer DispatcherOperationCallback loadStreamCompletedCaller = new DispatcherOperationCallback(OnLoadStreamCompleted); Dispatcher.BeginInvoke(DispatcherPriority.Normal, loadStreamCompletedCaller, asyncResult); } ////// Called on the UI thread when the Stream object is initialized. /// Begins asynchronous download of the Stream content into SoundPlayer's local buffer. /// private Object OnLoadStreamCompleted(Object asyncResultArg) { // Necessary for proper cleanup of async resources IAsyncResult asyncResult = (IAsyncResult)asyncResultArg; LoadStreamCaller caller = (LoadStreamCaller)asyncResult.AsyncState; Stream newStream = caller.EndInvoke(asyncResult); if (m_uriChangedWhileLoadingStream) // The source URI was changed, redo Stream loading { m_uriChangedWhileLoadingStream = false; if (newStream != null) // Don't hold on to the new stream - it's not needed anymore { newStream.Dispose(); } BeginLoadStream(); } else if (newStream != null) // We loaded the Stream, begin buffering it { if (m_player == null) { m_player = new SoundPlayer((Stream)newStream); } else { m_player.Stream = (Stream)newStream; } m_player.LoadCompleted += new AsyncCompletedEventHandler(OnSoundPlayerLoadCompleted); m_player.LoadAsync(); // Begin preloading the stream into SoundPlayer's local buffer } return null; } private void OnSoundPlayerLoadCompleted(Object sender, AsyncCompletedEventArgs e) { Debug.Assert(Object.ReferenceEquals(m_player, sender)); Debug.Assert(m_player.IsLoadCompleted); if (m_uriChangedWhileLoadingStream) // The source URI was changed, redo Stream loading again { m_player = null; m_uriChangedWhileLoadingStream = false; BeginLoadStream(); } else { m_streamLoadInProgress = false; if (m_playRequested) // URI is correct, m_player is ready, play it if requested { m_playRequested = false; m_player.Play(); } } } private SoundPlayer m_player; private Uri m_lastRequestedAbsoluteUri; private bool m_streamLoadInProgress; private bool m_playRequested; private bool m_uriChangedWhileLoadingStream; } } // 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
- MultitargetUtil.cs
- DoubleCollection.cs
- ArrayEditor.cs
- TransformPattern.cs
- DeploymentExceptionMapper.cs
- LightweightCodeGenerator.cs
- QueryCursorEventArgs.cs
- FindRequestContext.cs
- EventLog.cs
- METAHEADER.cs
- Visual3D.cs
- ControlPersister.cs
- StructuralCache.cs
- MessageBox.cs
- ShapeTypeface.cs
- PingReply.cs
- WebPartDisplayModeCancelEventArgs.cs
- DerivedKeySecurityToken.cs
- IdentityElement.cs
- DataObjectEventArgs.cs
- ReadOnlyCollectionBase.cs
- CalendarDay.cs
- TemplateBindingExtension.cs
- BaseTemplateParser.cs
- PeerNearMe.cs
- EventWaitHandleSecurity.cs
- WebPartCatalogCloseVerb.cs
- BasePattern.cs
- PrimitiveDataContract.cs
- InputLanguageCollection.cs
- LayoutManager.cs
- RecognizerInfo.cs
- PlanCompiler.cs
- WebServiceResponse.cs
- StrokeDescriptor.cs
- GroupBox.cs
- XmlSchemaAppInfo.cs
- DataTemplateKey.cs
- Assert.cs
- ProbeDuplexAsyncResult.cs
- _KerberosClient.cs
- FormatConvertedBitmap.cs
- SspiNegotiationTokenAuthenticator.cs
- DbDataReader.cs
- Int32Converter.cs
- DataGrid.cs
- SoundPlayer.cs
- WindowsRebar.cs
- RunWorkerCompletedEventArgs.cs
- RootProfilePropertySettingsCollection.cs
- BevelBitmapEffect.cs
- StrokeNodeData.cs
- OlePropertyStructs.cs
- Int32CAMarshaler.cs
- Matrix.cs
- XmlSchemaValidator.cs
- PrivilegedConfigurationManager.cs
- SystemEvents.cs
- Win32PrintDialog.cs
- MailBnfHelper.cs
- WebCodeGenerator.cs
- TextAutomationPeer.cs
- WorkflowInstanceContextProvider.cs
- XpsInterleavingPolicy.cs
- LingerOption.cs
- WizardStepCollectionEditor.cs
- NonClientArea.cs
- DataControlLinkButton.cs
- Transform3DGroup.cs
- ObjectQuery.cs
- SelectorItemAutomationPeer.cs
- SafeNativeMethods.cs
- PingOptions.cs
- VScrollBar.cs
- IProducerConsumerCollection.cs
- SafeArrayRankMismatchException.cs
- ItemCheckEvent.cs
- DataGridAutoFormat.cs
- ReadOnlyAttribute.cs
- WSHttpTransportSecurityElement.cs
- QueryResponse.cs
- ColumnBinding.cs
- ITreeGenerator.cs
- UserMapPath.cs
- serverconfig.cs
- CodeValidator.cs
- ProfileSettings.cs
- InkCollectionBehavior.cs
- DataServiceRequestException.cs
- XMLSyntaxException.cs
- ClientSettingsProvider.cs
- CustomErrorCollection.cs
- GetPolicyDetailsRequest.cs
- HostingPreferredMapPath.cs
- EdmFunctionAttribute.cs
- ConvertTextFrag.cs
- TraceSwitch.cs
- SizeAnimationClockResource.cs
- CollectionViewSource.cs
- FocusChangedEventArgs.cs