If you want your AutoCAD .NET plug-in to perform some tasks at regular intervals, then it is important to ensure that the timer runs in the AutoCAD’s main UI thread. Implementing the timer in a separate thread does not work because AutoCAD (atleast until 2013 release) does not support multithreaded applications.
To setup a timer to work properly, one possible way is to use a hidden modeless window that in-turn instantiates a timer (use the System.Windows.Forms.Timer). The System.Windows.Forms.Timer differs from the other timers provided by the .Net framework and is guranteed to run in the same UI thread which started it. For a comparison of the various timers available in the .Net framework, you may refer to this MSDN magazine article.
Here is the sample code that displays a tray bubble at a specified time interval :
First lets look at the commands class
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Windows
Public Class AdskMyTimerClass
Implements IExtensionApplication
'System.Threading.Timer is a simple, lightweight timer that
'uses callback methods and is served by thread pool threads.
'It is not recommended for use with Windows Forms, because
'its callbacks do not occur on the user interface thread.
'System.Windows.Forms.Timer is a better choice for use with
'Windows Forms and its callbacks occur on the same UI thread.
Private _timerForm As MyForm
Public Sub Initialize() _
Implements IExtensionApplication.Initialize
_timerForm = Nothing
End Sub
Public Sub Terminate() _
Implements IExtensionApplication.Terminate
StopTimerMethod()
End Sub
_
Public Sub StartTimerMethod()
If _timerForm Is Nothing Then
_timerForm = New MyForm
_timerForm.Show()
_timerForm.Hide()
End If
End Sub
_
Public Sub StopTimerMethod()
If _timerForm IsNot Nothing Then
_timerForm.Close()
_timerForm.Dispose()
_timerForm = Nothing
End If
End Sub
End Class
Now for the Form class that creates the timer :
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Windows
Public Class MyForm
Private _myTimer As System.Windows.Forms.Timer
Private _ti As TrayItem
Private _icon As System.Drawing.Icon
Private _cnt As Int32
Private Sub MyForm_Load( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles MyBase.Load
_myTimer = New System.Windows.Forms.Timer()
_myTimer.Enabled = True
_myTimer.Interval = 5000
AddHandler _myTimer.Tick, AddressOf MyBubbleTimer_Tick
_myTimer.Start()
End Sub
Private Sub MyBubbleTimer_Tick( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs
)
_cnt = _cnt + 1
Dim sb As StatusBar = Application.StatusBar
Dim tis As TrayItemCollection = sb.TrayItems
If _ti Is Nothing Then
_cnt = 1
_ti = New TrayItem()
_ti.Visible = True
_icon = New System.Drawing.Icon("C:\Temp\spintest.ico")
_ti.Icon = Icon
_ti.ToolTipText = "My Timer trigerred bubble !"
tis.Add(_ti)
sb.Update()
End If
_ti.CloseBubbleWindows()
Dim bubble As New TrayItemBubbleWindow()
bubble.Text = "Hello !"
bubble.Title = String.Format("{0}", _cnt)
bubble.HyperLink = "http://www.autodesk.com"
bubble.HyperText = "Autodesk"
_ti.ShowBubbleWindow(bubble)
End Sub
Private Sub MyForm_FormClosed( _
ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.FormClosedEventArgs _
) Handles MyBase.FormClosed
' Stop the timer
_myTimer.Stop()
_myTimer.Dispose()
' Remove the tray item
If _ti IsNot Nothing Then
Dim sb As StatusBar = Application.StatusBar
Dim tis As TrayItemCollection = sb.TrayItems
tis.Remove(_ti)
sb.Update()
End If
End Sub
End Class

Leave a Reply to MaxenceCancel reply