マクロの記録/再生をする簡単なフォーム
「1」〜「5」「クリア」「記録」「再生」の8個のボタン、1個のラベルをフォームに配置する。
- 数字ボタンを押すと、ラベル上にその数字が追加される。
- 「クリア」を押すとラベルがまっさらになる。
- 「記録」を押すと数字ボタンの押されたタイミング/履歴を保存する。
- 「再生」を押すとタイミング/履歴通りに数字ボタンを押したイベントを再生する。
というのを VB.NET で作ってみた。
こーゆーのは GoF の Command パターンとか使うべきなんだろうけど、まだ VB.NET に慣れてないので…
Imports System.Threading Public Structure CommandClass Public name As String Public arg As String Public Sub New(ByVal s1 As String, ByVal s2 As String) Me.name = s1 Me.arg = s2 End Sub End Structure Public Class Form1 Private status As Integer = 0 '0:定常状態 1:記録中 Private commands As Collection = New Collection() Private commandPreTime As Date Private timerDelegate As TimerCallback = New TimerCallback(AddressOf MyTimer) Private timer As Timer = New Timer(timerDelegate, Nothing, Timeout.Infinite, -1) Dim myCount As Integer = 0 Private Function func(ByVal code) Label1.Text = Label1.Text & code If status = 1 Then '記録中 If commands.Count > 0 Then Dim span As TimeSpan = Now() - commandPreTime commands.Add(New CommandClass("s", span.TotalSeconds)) End If commandPreTime = Now() commands.Add(New CommandClass("r", code)) End If func = code End Function Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles Button1.Click, Button2.Click, Button3.Click, Button4.Click, Button5.Click func(sender.Text) End Sub Private Sub Button100_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button100.Click If status = 0 Then commands.Clear() status = 1 Button100.Text = "保存する" Else status = 0 Dim sfd As New SaveFileDialog() sfd.FileName = "events.txt" 'sfd.InitialDirectory = "C:\" sfd.Filter = "TEXTファイル(*.txt)|*.txt|すべてのファイル(*.*)|*.*" sfd.FilterIndex = 1 '初期表示は*.txtだけ sfd.Title = "保存先のファイルを選択してください" If sfd.ShowDialog() = DialogResult.OK Then Dim stream As System.IO.Stream = sfd.OpenFile() If Not (stream Is Nothing) Then Dim sw As New System.IO.StreamWriter(stream) sw.WriteLine("# s:指定秒数SLEEPする / " & _ "p:指定されたキーのPressイベントを発行 /r:指定されたキーのReleaseイベントを発行") For Each com In commands sw.WriteLine(com.name & " " & com.arg.ToString) Next sw.Close() stream.Close() End If End If Button100.Text = "記録開始" End If End Sub Private Sub Button101_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button101.Click Dim ofd As New OpenFileDialog() ofd.FileName = "events.txt" 'ofd.InitialDirectory = "C:\" ofd.Filter = "TEXTファイル(*.txt)|*.txt|すべてのファイル(*.*)|*.*" ofd.FilterIndex = 1 ofd.Title = "開くファイルを選択してください" ofd.RestoreDirectory = True If ofd.ShowDialog() = DialogResult.OK Then Dim stream As System.IO.Stream = ofd.OpenFile() If Not (stream Is Nothing) Then Dim sr As New System.IO.StreamReader(stream) Dim sarray As String() commands.Clear() While sr.Peek() > -1 Dim s As String = sr.ReadLine() If s.Length < 3 Or s.StartsWith("#") Then ' Do nothing 'Next While 'break; とか next に該当するのって何? Else sarray = s.Split(" ") commands.Add(New CommandClass(sarray(0), sarray(1))) End If End While sr.Close() stream.Close() myCount = 1 timer.Change(10, Timeout.Infinite) End If End If End Sub Private Sub Button102_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button102.Click Label1.Text = "" End Sub Delegate Function FuncDelegate(ByVal arg) Public Sub MyTimer(ByVal o As Object) While myCount <= commands.Count Dim com As CommandClass = commands(myCount) myCount = myCount + 1 If com.name = "r" Then Invoke(New FuncDelegate(AddressOf func), com.arg) Else timer.Change(Convert.ToInt32(com.arg * 1000), Timeout.Infinite) Exit Sub End If End While timer.Change(Timeout.Infinite, Timeout.Infinite) MessageBox.Show("再生を終了しました") End Sub End Class