電子書籍の厳選無料作品が豊富!

よろしくお願いします!

ある常駐プログラムを作成し、操作者があらかじめ指定した時間ごとに
画像を保存するという設定にしています。

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分)で
あったり様々です。
その場合の方法がよく分からないので、最初に書いた方法でコードを
書いています。

よろしくお願いします!!!

A 回答 (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は、時には「\」がいらないなどの、しょーもない反論は却下!
あくまでこれは考え方のサンプルです。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

詳細なコードまで書いていただきまして、ありがとうございます。
こちらのサンプルを2つのEXEファイルにして起動してみましたが、
表示は23:59:59くらいで止まってしまいます。
やはり日付が変わる時間は何か表示ができない要因があるようです。

お礼日時:2003/01/15 20:29

DateAdd("s",120,TimeValue("23:59:59"))


が期待した値でないのでは?

>Label2.caption=time
timeではなくnowにすれば動くと思います。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

DateAddでも一応ちゃんと動作はするのですが、何故か日付がかわる
あたりで止まってしまうのです。
Interval=1000で表示している方はちゃんと時計が表示されているのですが、
もう一方が止まります。
Nowで試してみましたが、やはり同じでした。

お礼日時:2003/01/15 20:32

まちがいでした


Timerイベントは発生しました。
さっきのレスを気にしないでください。
でも、何らかのタイミングでタイマーイベントが発生しなくなる場合があるのは本当です。
そのために、私が時間間隔を使用するときは、いつも割り込みで発生させています。
どういうときにそうなるかをわすれちゃったけど。。。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!