- ベストアンサー
Timerコントロールによる動作の時間間隔設定について
よろしくお願いします! ある常駐プログラムを作成し、操作者があらかじめ指定した時間ごとに 画像を保存するという設定にしています。 Timerコントロールで直接時間間隔を指定するとIntervalが最大60000くらい らしいので、まずLabel1にInterval1000で時計を表示して、次にLabel2に もLabel2.caption=timeで時刻を表示します。 操作者が仮に2分ごとに画像を取ると指定した場合は、 Label2の時刻にDateAddで("s",120,TimeValue(label2.caption))した時刻と Label1の時刻が同じになったら画像を取るというコードにしてます。 で、画像を取ると同時にLabel2.caption=timeでLabel2の値を現在時刻に し、また繰り返し2分足したものとLabel1.captionが同じになるのを 待って画像を取ります。 これを繰り返して指定した時間間隔で画像を取るようにしていまして、 ちゃんと動作するのですが、なぜか時計が23:59:57くらいで Label2の方の表示が止まってしまうのです。 Label1の方はTimerで1秒ごとにちゃんと時計を表示し続けている のですが、Label2だけ0時直前で必ず止まってしまいます。 何か日付が変わると表示ができなくなるような決まりがあるのでしょうか。 色々と試したのですが、ここだけが分かりません。 ご教授お願いいたします! また、私のやり方以外に何か時間間隔を指定する良いコードが ございましたら教えていただけますでしょうか? 例えばTimerコントロールを1分ごとに起動して、3分なら3回カウント させるような方法もどこかで目にしたのですが、操作者が指定する 時間間隔は秒単位にしているので、3秒であったり、120秒(2分)で あったり様々です。 その場合の方法がよく分からないので、最初に書いた方法でコードを 書いています。 よろしくお願いします!!!
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
できるだけ正確な2分を取得したいなら、別プロセスにすることが望ましいと思います。 VBは(基本的に)シングルスレッドのみ対応しています。 2分後のタイミングで、フォームをドラッグされたりしたら、その間はタイマーコントロールのイベントは発生しません。ですので、2分間隔でタイマーイベントが発生するとも限りません。 他プロセスにして、割り込みの様に発生させると、これらの症状を回避することができます。 別EXEがいやなら、同様なロジックのActiveXにするとよいと思います。 サンプルは二つのプロジェクトです。 ※割り込みタイマープロジェクト Project1.exe └Module1 ※メインのEXE Project2.exe └Form1 ├Command1 └Text1 ソースを、各プロジェクトの適した場所に貼り付けてEXEにしてください。 それで同じフォルダにおいて、Project2.exeを起動してみてください。 ------Project1.exe Option Explicit '秒間隔 Private Const DEF_INTERVAL As Single = 2 '←ここを120にしたら2分 Private Declare Function IsWindow Lib "user32" (ByVal hwnd As Long) As Long Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long Private Const WM_COMMAND = &H111 Private Const BN_CLICKED = &H0& Private Const API_FALSE = &H0& Sub Main() Dim sngStart As Single Dim sngWork As Single Dim cmdPara As String Dim lngWinWnd As Long Dim lngBtnWnd As Long 'タスク一覧に追加しない App.TaskVisible = False '引数を受け取る cmdPara = Command$() If Not IsNumeric(cmdPara) Then GoTo PGMEND End If 'ハンドルを保持 lngBtnWnd = CLng(cmdPara) lngWinWnd = GetParent(lngBtnWnd) 'タイマー開始時間の設定 sngStart = Timer Do Until IsWindow(lngBtnWnd) = API_FALSE '経過時間を取得 sngWork = Timer - sngStart 'インターバル時間を超えるようなら If sngWork >= DEF_INTERVAL Then 'ボタンを押す処理をする Call PostMessage(lngWinWnd, WM_COMMAND, BN_CLICKED, ByVal lngBtnWnd) 'タイマー開始時間の再設定 sngStart = sngStart + DEF_INTERVAL End If DoEvents Loop PGMEND: End Sub ------Project2.exe Option Explicit Private Sub Command1_Click() Text1.Text = Now() End Sub Private Sub Form_Load() Me.Command1.Visible = False Call Shell(App.Path & "\Project1.exe " & Me.Command1.hWnd) Call Command1_Click End Sub 突っ込み野郎が現れる前に一言! App.Pathは、時には「\」がいらないなどの、しょーもない反論は却下! あくまでこれは考え方のサンプルです。
その他の回答 (2)
- todo36
- ベストアンサー率58% (728/1234)
DateAdd("s",120,TimeValue("23:59:59")) が期待した値でないのでは? >Label2.caption=time timeではなくnowにすれば動くと思います。
お礼
ご回答ありがとうございます。 DateAddでも一応ちゃんと動作はするのですが、何故か日付がかわる あたりで止まってしまうのです。 Interval=1000で表示している方はちゃんと時計が表示されているのですが、 もう一方が止まります。 Nowで試してみましたが、やはり同じでした。
- TAGOSAKU7
- ベストアンサー率65% (276/422)
まちがいでした Timerイベントは発生しました。 さっきのレスを気にしないでください。 でも、何らかのタイミングでタイマーイベントが発生しなくなる場合があるのは本当です。 そのために、私が時間間隔を使用するときは、いつも割り込みで発生させています。 どういうときにそうなるかをわすれちゃったけど。。。
お礼
ご回答ありがとうございます。 詳細なコードまで書いていただきまして、ありがとうございます。 こちらのサンプルを2つのEXEファイルにして起動してみましたが、 表示は23:59:59くらいで止まってしまいます。 やはり日付が変わる時間は何か表示ができない要因があるようです。