Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / WinForms / Managed / System / WinForms / Timer.cs / 1 / Timer.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- /* */ namespace System.Windows.Forms { using System.Threading; using System.Runtime.InteropServices; using System.ComponentModel; using System.ComponentModel.Design; using System.Diagnostics; using System.Windows.Forms.Design; using System; using System.Globalization; ////// /// [ DefaultProperty("Interval"), DefaultEvent("Tick"), ToolboxItemFilter("System.Windows.Forms"), SRDescription(SR.DescriptionTimer) ] public class Timer : Component { ///Implements a Windows-based timer that raises an event at user-defined intervals. This timer is optimized for /// use in Win Forms /// applications and must be used in a window. ////// /// private int interval; ////// /// private bool enabled; ////// /// private EventHandler onTimer; ////// /// private GCHandle timerRoot; // our holder for the HWND that handles our Timer messages. // private TimerNativeWindow timerWindow; ////// /// private object userData; private object syncObj = new object(); ////// /// public Timer() : base() { interval = 100; } ///Initializes a new instance of the ////// class. /// /// public Timer(IContainer container) : this() { container.Add(this); } ///Initializes a new instance of the ///class with the specified container. [ SRCategory(SR.CatData), Localizable(false), Bindable(true), SRDescription(SR.ControlTagDescr), DefaultValue(null), TypeConverter(typeof(StringConverter)), ] public object Tag { get { return userData; } set { userData = value; } } /// /// /// [SRCategory(SR.CatBehavior), SRDescription(SR.TimerTimerDescr)] public event EventHandler Tick { add { onTimer += value; } remove { onTimer -= value; } } ///Occurs when the specified timer /// interval has elapsed and the timer is enabled. ////// /// protected override void Dispose(bool disposing) { if (disposing) { if (timerWindow != null) { timerWindow.StopTimer(); } Enabled = false; } timerWindow = null; base.Dispose(disposing); } ////// Disposes of the resources (other than memory) used by the timer. /// ////// /// [ SRCategory(SR.CatBehavior), DefaultValue(false), SRDescription(SR.TimerEnabledDescr) ] public virtual bool Enabled { get { if (timerWindow == null) { return enabled; } return timerWindow.IsTimerRunning; } set { lock(syncObj) { if (enabled != value) { enabled = value; // At runtime, enable or disable the corresponding Windows timer // if (!DesignMode) { if (value) { // create the timer window if needed. // if (timerWindow == null) { timerWindow = new TimerNativeWindow(this); } timerRoot = GCHandle.Alloc(this); timerWindow.StartTimer(interval); } else{ if (timerWindow != null){ timerWindow.StopTimer(); } if (timerRoot.IsAllocated) { timerRoot.Free(); } } } } } } } ///Indicates whether the timer is /// running. ////// /// [ SRCategory(SR.CatBehavior), DefaultValue(100), SRDescription(SR.TimerIntervalDescr) ] public int Interval { get { return interval; } set { lock(syncObj) { if (value < 1) throw new ArgumentOutOfRangeException("Interval", SR.GetString(SR.TimerInvalidInterval, value, (0).ToString(CultureInfo.CurrentCulture))); if (interval != value) { interval = value; if (Enabled) { Debug.Assert(DesignMode || timerWindow != null, "Why don't we have a timer HWND?"); // just change the timer value, don't tear down the timer // itself. // if (!DesignMode && timerWindow != null) { timerWindow.RestartTimer(value); } } } } } } ////// Indicates the time, in milliseconds, between timer ticks. ////// /// protected virtual void OnTick(EventArgs e) { if (onTimer != null) onTimer(this, e); } ///Raises the ////// event. /// /// public void Start() { Enabled = true; } ///Starts the /// timer. ////// /// public void Stop() { Enabled = false; } ///Stops the /// timer. ////// /// returns us as a string. /// ///public override string ToString() { string s = base.ToString(); return s + ", Interval: " + Interval.ToString(CultureInfo.CurrentCulture); } private class TimerNativeWindow : NativeWindow { // the timer that owns us // private Timer _owner; // our current id -- this is usally the same as TimerID but we also // use it as a flag of when our timer is running. // private int _timerID; // arbitrary timer ID. // private static int TimerID = 1; // setting this when we are stopping the timer so someone can't restart it in the process. // private bool _stoppingTimer; internal TimerNativeWindow(Timer owner) { this._owner = owner; } ~TimerNativeWindow() { // note this call will work form the finalizer thread. // StopTimer(); } public bool IsTimerRunning { get { return _timerID != 0 && Handle != IntPtr.Zero; } } // Ensures that our HWND has been created. // private bool EnsureHandle() { if (Handle == IntPtr.Zero) { // we create a totally vanilla invisible window just for WM_TIMER messages. // CreateParams cp = new CreateParams(); cp.Style = 0; cp.ExStyle = 0; cp.ClassStyle = 0; cp.Caption = GetType().Name; // Message only windows are cheaper and have fewer issues than // full blown invisible windows. But, they are only supported // on NT. if (Environment.OSVersion.Platform == PlatformID.Win32NT) { cp.Parent = (IntPtr)NativeMethods.HWND_MESSAGE; } CreateHandle(cp); } Debug.Assert(Handle != IntPtr.Zero, "Timer HWND creation failed!"); return Handle != IntPtr.Zero; } // Returns true if we need to marshal across threads to access this timer's HWND. // private bool GetInvokeRequired(IntPtr hWnd) { if (hWnd != IntPtr.Zero) { int pid; int hwndThread = SafeNativeMethods.GetWindowThreadProcessId(new HandleRef(this, hWnd), out pid); int currentThread = SafeNativeMethods.GetCurrentThreadId(); return(hwndThread != currentThread); } return false; } // change the interval of the timer without destroying the HWND. // public void RestartTimer(int newInterval) { StopTimer(false, IntPtr.Zero); StartTimer(newInterval); } // Start the timer with the specified interval. // public void StartTimer(int interval) { if (_timerID == 0 && !_stoppingTimer) { if (EnsureHandle()) { _timerID = (int) SafeNativeMethods.SetTimer(new HandleRef(this, Handle), TimerID++, interval, IntPtr.Zero); } } } // stop the timer. // public void StopTimer() { StopTimer(true, IntPtr.Zero); } // stop the timer and optionally destroy the HWND. // public void StopTimer(bool destroyHwnd, IntPtr hWnd) { if (hWnd == IntPtr.Zero) { hWnd = Handle; } // Fire a message across threads to destroy the timer and HWND on the thread that created it. // if (GetInvokeRequired(hWnd)) { UnsafeNativeMethods.PostMessage(new HandleRef(this, hWnd), NativeMethods.WM_CLOSE, 0, 0); return; } // Locking 'this' here is ok since this is an internal class. See VSW#464499. lock(this) { if (_stoppingTimer || hWnd == IntPtr.Zero || !UnsafeNativeMethods.IsWindow(new HandleRef(this, hWnd))) { return; } if (_timerID != 0) { try { _stoppingTimer = true; SafeNativeMethods.KillTimer(new HandleRef(this, hWnd), _timerID); } finally { _timerID = 0; _stoppingTimer = false; } } if (destroyHwnd) { base.DestroyHandle(); } } } // Destroy the handle, stopping the timer first. // public override void DestroyHandle() { // don't recurse! // StopTimer(false, IntPtr.Zero); Debug.Assert(_timerID == 0, "Destroying handle with timerID still set."); base.DestroyHandle(); } protected override void OnThreadException(Exception e) { Application.OnThreadException(e); } public override void ReleaseHandle() { // don't recurse! // StopTimer(false, IntPtr.Zero); Debug.Assert(_timerID == 0, "Destroying handle with timerID still set."); base.ReleaseHandle(); } protected override void WndProc(ref Message m) { Debug.Assert(m.HWnd == Handle && Handle != IntPtr.Zero, "Timer getting messages for other windows?"); // for timer messages, make sure they're ours (it'll be wierd if they aren't) // and call the timer event. // if (m.Msg == NativeMethods.WM_TIMER) { //Debug.Assert((int)m.WParam == _timerID, "Why are we getting a timer message that isn't ours?"); if ((int)m.WParam == _timerID) { _owner.OnTick(EventArgs.Empty); return; } } else if (m.Msg == NativeMethods.WM_CLOSE) { // this is a posted method from another thread that tells us we need // to kill the timer. The handle may already be gone, so we specify it here. // StopTimer(true, m.HWnd); return; } base.WndProc(ref m); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- /* */ namespace System.Windows.Forms { using System.Threading; using System.Runtime.InteropServices; using System.ComponentModel; using System.ComponentModel.Design; using System.Diagnostics; using System.Windows.Forms.Design; using System; using System.Globalization; ////// /// [ DefaultProperty("Interval"), DefaultEvent("Tick"), ToolboxItemFilter("System.Windows.Forms"), SRDescription(SR.DescriptionTimer) ] public class Timer : Component { ///Implements a Windows-based timer that raises an event at user-defined intervals. This timer is optimized for /// use in Win Forms /// applications and must be used in a window. ////// /// private int interval; ////// /// private bool enabled; ////// /// private EventHandler onTimer; ////// /// private GCHandle timerRoot; // our holder for the HWND that handles our Timer messages. // private TimerNativeWindow timerWindow; ////// /// private object userData; private object syncObj = new object(); ////// /// public Timer() : base() { interval = 100; } ///Initializes a new instance of the ////// class. /// /// public Timer(IContainer container) : this() { container.Add(this); } ///Initializes a new instance of the ///class with the specified container. [ SRCategory(SR.CatData), Localizable(false), Bindable(true), SRDescription(SR.ControlTagDescr), DefaultValue(null), TypeConverter(typeof(StringConverter)), ] public object Tag { get { return userData; } set { userData = value; } } /// /// /// [SRCategory(SR.CatBehavior), SRDescription(SR.TimerTimerDescr)] public event EventHandler Tick { add { onTimer += value; } remove { onTimer -= value; } } ///Occurs when the specified timer /// interval has elapsed and the timer is enabled. ////// /// protected override void Dispose(bool disposing) { if (disposing) { if (timerWindow != null) { timerWindow.StopTimer(); } Enabled = false; } timerWindow = null; base.Dispose(disposing); } ////// Disposes of the resources (other than memory) used by the timer. /// ////// /// [ SRCategory(SR.CatBehavior), DefaultValue(false), SRDescription(SR.TimerEnabledDescr) ] public virtual bool Enabled { get { if (timerWindow == null) { return enabled; } return timerWindow.IsTimerRunning; } set { lock(syncObj) { if (enabled != value) { enabled = value; // At runtime, enable or disable the corresponding Windows timer // if (!DesignMode) { if (value) { // create the timer window if needed. // if (timerWindow == null) { timerWindow = new TimerNativeWindow(this); } timerRoot = GCHandle.Alloc(this); timerWindow.StartTimer(interval); } else{ if (timerWindow != null){ timerWindow.StopTimer(); } if (timerRoot.IsAllocated) { timerRoot.Free(); } } } } } } } ///Indicates whether the timer is /// running. ////// /// [ SRCategory(SR.CatBehavior), DefaultValue(100), SRDescription(SR.TimerIntervalDescr) ] public int Interval { get { return interval; } set { lock(syncObj) { if (value < 1) throw new ArgumentOutOfRangeException("Interval", SR.GetString(SR.TimerInvalidInterval, value, (0).ToString(CultureInfo.CurrentCulture))); if (interval != value) { interval = value; if (Enabled) { Debug.Assert(DesignMode || timerWindow != null, "Why don't we have a timer HWND?"); // just change the timer value, don't tear down the timer // itself. // if (!DesignMode && timerWindow != null) { timerWindow.RestartTimer(value); } } } } } } ////// Indicates the time, in milliseconds, between timer ticks. ////// /// protected virtual void OnTick(EventArgs e) { if (onTimer != null) onTimer(this, e); } ///Raises the ////// event. /// /// public void Start() { Enabled = true; } ///Starts the /// timer. ////// /// public void Stop() { Enabled = false; } ///Stops the /// timer. ////// /// returns us as a string. /// ///public override string ToString() { string s = base.ToString(); return s + ", Interval: " + Interval.ToString(CultureInfo.CurrentCulture); } private class TimerNativeWindow : NativeWindow { // the timer that owns us // private Timer _owner; // our current id -- this is usally the same as TimerID but we also // use it as a flag of when our timer is running. // private int _timerID; // arbitrary timer ID. // private static int TimerID = 1; // setting this when we are stopping the timer so someone can't restart it in the process. // private bool _stoppingTimer; internal TimerNativeWindow(Timer owner) { this._owner = owner; } ~TimerNativeWindow() { // note this call will work form the finalizer thread. // StopTimer(); } public bool IsTimerRunning { get { return _timerID != 0 && Handle != IntPtr.Zero; } } // Ensures that our HWND has been created. // private bool EnsureHandle() { if (Handle == IntPtr.Zero) { // we create a totally vanilla invisible window just for WM_TIMER messages. // CreateParams cp = new CreateParams(); cp.Style = 0; cp.ExStyle = 0; cp.ClassStyle = 0; cp.Caption = GetType().Name; // Message only windows are cheaper and have fewer issues than // full blown invisible windows. But, they are only supported // on NT. if (Environment.OSVersion.Platform == PlatformID.Win32NT) { cp.Parent = (IntPtr)NativeMethods.HWND_MESSAGE; } CreateHandle(cp); } Debug.Assert(Handle != IntPtr.Zero, "Timer HWND creation failed!"); return Handle != IntPtr.Zero; } // Returns true if we need to marshal across threads to access this timer's HWND. // private bool GetInvokeRequired(IntPtr hWnd) { if (hWnd != IntPtr.Zero) { int pid; int hwndThread = SafeNativeMethods.GetWindowThreadProcessId(new HandleRef(this, hWnd), out pid); int currentThread = SafeNativeMethods.GetCurrentThreadId(); return(hwndThread != currentThread); } return false; } // change the interval of the timer without destroying the HWND. // public void RestartTimer(int newInterval) { StopTimer(false, IntPtr.Zero); StartTimer(newInterval); } // Start the timer with the specified interval. // public void StartTimer(int interval) { if (_timerID == 0 && !_stoppingTimer) { if (EnsureHandle()) { _timerID = (int) SafeNativeMethods.SetTimer(new HandleRef(this, Handle), TimerID++, interval, IntPtr.Zero); } } } // stop the timer. // public void StopTimer() { StopTimer(true, IntPtr.Zero); } // stop the timer and optionally destroy the HWND. // public void StopTimer(bool destroyHwnd, IntPtr hWnd) { if (hWnd == IntPtr.Zero) { hWnd = Handle; } // Fire a message across threads to destroy the timer and HWND on the thread that created it. // if (GetInvokeRequired(hWnd)) { UnsafeNativeMethods.PostMessage(new HandleRef(this, hWnd), NativeMethods.WM_CLOSE, 0, 0); return; } // Locking 'this' here is ok since this is an internal class. See VSW#464499. lock(this) { if (_stoppingTimer || hWnd == IntPtr.Zero || !UnsafeNativeMethods.IsWindow(new HandleRef(this, hWnd))) { return; } if (_timerID != 0) { try { _stoppingTimer = true; SafeNativeMethods.KillTimer(new HandleRef(this, hWnd), _timerID); } finally { _timerID = 0; _stoppingTimer = false; } } if (destroyHwnd) { base.DestroyHandle(); } } } // Destroy the handle, stopping the timer first. // public override void DestroyHandle() { // don't recurse! // StopTimer(false, IntPtr.Zero); Debug.Assert(_timerID == 0, "Destroying handle with timerID still set."); base.DestroyHandle(); } protected override void OnThreadException(Exception e) { Application.OnThreadException(e); } public override void ReleaseHandle() { // don't recurse! // StopTimer(false, IntPtr.Zero); Debug.Assert(_timerID == 0, "Destroying handle with timerID still set."); base.ReleaseHandle(); } protected override void WndProc(ref Message m) { Debug.Assert(m.HWnd == Handle && Handle != IntPtr.Zero, "Timer getting messages for other windows?"); // for timer messages, make sure they're ours (it'll be wierd if they aren't) // and call the timer event. // if (m.Msg == NativeMethods.WM_TIMER) { //Debug.Assert((int)m.WParam == _timerID, "Why are we getting a timer message that isn't ours?"); if ((int)m.WParam == _timerID) { _owner.OnTick(EventArgs.Empty); return; } } else if (m.Msg == NativeMethods.WM_CLOSE) { // this is a posted method from another thread that tells us we need // to kill the timer. The handle may already be gone, so we specify it here. // StopTimer(true, m.HWnd); return; } base.WndProc(ref m); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XmlEntity.cs
- DecoderFallback.cs
- WeakReferenceEnumerator.cs
- FilteredSchemaElementLookUpTable.cs
- ExpressionNormalizer.cs
- DataTableNameHandler.cs
- AnnotationAuthorChangedEventArgs.cs
- AuthorizationRuleCollection.cs
- XmlILAnnotation.cs
- Point3DCollection.cs
- PenCursorManager.cs
- SortQuery.cs
- DataFormats.cs
- ActivityWithResultConverter.cs
- ModelUIElement3D.cs
- LayoutTable.cs
- ListManagerBindingsCollection.cs
- ResourcePool.cs
- propertytag.cs
- DockPattern.cs
- RoleService.cs
- SimpleBitVector32.cs
- WsatServiceAddress.cs
- CornerRadius.cs
- GeometryModel3D.cs
- TypeTypeConverter.cs
- SchemaExporter.cs
- VectorAnimation.cs
- PrimitiveType.cs
- TextClipboardData.cs
- DoubleLinkListEnumerator.cs
- _ScatterGatherBuffers.cs
- Pair.cs
- MemberAccessException.cs
- SimpleHandlerBuildProvider.cs
- XmlSchemaSet.cs
- XmlUtil.cs
- EventOpcode.cs
- DynamicRouteExpression.cs
- XmlCountingReader.cs
- DataAdapter.cs
- SqlConnectionHelper.cs
- XmlAttributes.cs
- BaseValidator.cs
- FontInfo.cs
- TextCompositionEventArgs.cs
- DesignerMetadata.cs
- ApplicationDirectory.cs
- NavigateEvent.cs
- Int16.cs
- SoapFault.cs
- TypedTableBaseExtensions.cs
- StaticFileHandler.cs
- CurrentChangingEventArgs.cs
- WindowsScroll.cs
- TextFormatterImp.cs
- ProcessInputEventArgs.cs
- LassoHelper.cs
- Quaternion.cs
- LineServices.cs
- IntSecurity.cs
- HttpsChannelListener.cs
- StateMachineHelpers.cs
- XpsDocumentEvent.cs
- PasswordTextContainer.cs
- ConsoleTraceListener.cs
- SafeNativeMethods.cs
- DesignerActionMethodItem.cs
- WindowsListViewItem.cs
- HttpCacheVary.cs
- TextMarkerSource.cs
- ListViewDataItem.cs
- ImportedPolicyConversionContext.cs
- WebContext.cs
- XmlElementList.cs
- SystemThemeKey.cs
- Int32AnimationUsingKeyFrames.cs
- ServiceHttpModule.cs
- FileUtil.cs
- SwitchLevelAttribute.cs
- CodeMemberProperty.cs
- AdjustableArrowCap.cs
- datacache.cs
- DetailsViewPagerRow.cs
- DataGridViewButtonCell.cs
- PerformanceCounterLib.cs
- TableLayoutStyleCollection.cs
- RichTextBoxAutomationPeer.cs
- TextChangedEventArgs.cs
- FontFamilyValueSerializer.cs
- SQLUtility.cs
- EUCJPEncoding.cs
- EventRouteFactory.cs
- ListBox.cs
- WindowsToolbarItemAsMenuItem.cs
- IApplicationTrustManager.cs
- EqualityArray.cs
- BaseTemplatedMobileComponentEditor.cs
- PassportAuthenticationEventArgs.cs
- Properties.cs