Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / 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
- SqlDuplicator.cs
- ActivityExecutorDelegateInfo.cs
- CounterCreationData.cs
- GridViewRow.cs
- PasswordRecovery.cs
- QilGenerator.cs
- XmlChoiceIdentifierAttribute.cs
- HttpListenerException.cs
- ProfileSettingsCollection.cs
- ChannelSinkStacks.cs
- CheckableControlBaseAdapter.cs
- HostProtectionPermission.cs
- XmlILStorageConverter.cs
- FlowDocumentView.cs
- FramingEncoders.cs
- Timer.cs
- ResourceDisplayNameAttribute.cs
- Base64Encoding.cs
- LabelLiteral.cs
- TextMarkerSource.cs
- WebEventTraceProvider.cs
- BaseParser.cs
- StylusPointPropertyInfoDefaults.cs
- TypeBuilder.cs
- ResXResourceWriter.cs
- MatrixConverter.cs
- RowUpdatedEventArgs.cs
- EntityFrameworkVersions.cs
- COM2IManagedPerPropertyBrowsingHandler.cs
- HeaderedContentControl.cs
- TraceEventCache.cs
- ParameterReplacerVisitor.cs
- ViewValidator.cs
- Int16KeyFrameCollection.cs
- DbConnectionPoolGroup.cs
- DefaultValueTypeConverter.cs
- IfElseDesigner.xaml.cs
- UnitySerializationHolder.cs
- ObjectDataSourceStatusEventArgs.cs
- TemplateInstanceAttribute.cs
- LoginName.cs
- ConfigXmlElement.cs
- NextPreviousPagerField.cs
- EventMappingSettings.cs
- SafeFindHandle.cs
- WebPartHelpVerb.cs
- QueryRewriter.cs
- PackageFilter.cs
- TypeValidationEventArgs.cs
- SystemTcpStatistics.cs
- WindowClosedEventArgs.cs
- CacheVirtualItemsEvent.cs
- SqlClientWrapperSmiStream.cs
- CallSiteBinder.cs
- PropertyPath.cs
- TextStore.cs
- __TransparentProxy.cs
- CompModSwitches.cs
- XPathLexer.cs
- SplineKeyFrames.cs
- ReceiveMessageAndVerifySecurityAsyncResultBase.cs
- LeafCellTreeNode.cs
- KnownBoxes.cs
- ExpressionPrefixAttribute.cs
- TabControlCancelEvent.cs
- filewebresponse.cs
- TreeChangeInfo.cs
- ConfigurationFileMap.cs
- MessageDecoder.cs
- TextInfo.cs
- InstanceStoreQueryResult.cs
- DataKey.cs
- OneWayBindingElementImporter.cs
- ToolStripTextBox.cs
- DoubleAnimationClockResource.cs
- ByteAnimationUsingKeyFrames.cs
- WindowsGraphicsWrapper.cs
- x509store.cs
- InfoCardRSAOAEPKeyExchangeDeformatter.cs
- DataFormats.cs
- Blend.cs
- TypeInfo.cs
- DataGridViewCell.cs
- SingleStorage.cs
- ProgressBarBrushConverter.cs
- XmlSerializerVersionAttribute.cs
- Span.cs
- HostAdapter.cs
- XmlTextReaderImplHelpers.cs
- LayoutExceptionEventArgs.cs
- WindowPattern.cs
- FunctionNode.cs
- GridViewColumnHeader.cs
- XmlLangPropertyAttribute.cs
- _ShellExpression.cs
- TabItem.cs
- _Rfc2616CacheValidators.cs
- InputScope.cs
- TextTreeInsertElementUndoUnit.cs
- ActivityTypeCodeDomSerializer.cs