tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトルクラス内のタイマーイベントについて
記事No15137
投稿日: 2011/03/10(Thu) 19:04
投稿者いまぷ

クラス内のタイマーイベント発行について教えてください。

クラス内であるメソッドが呼ばれると定期的にタイマーイベントがクラス内で発行され、
結果によってはRaiseEventで外部にイベントを発行する処理を作っています。
現在調べた内容としては
  ・クラス内でタイマーオブジェクトを作成することは出来ない。但し宣言は可能
  ・フォームを作り、タイマーコントロールを貼ってクラス内に連動する方法があるらしい
というところまでわかっていますが、このフォームのタイマーをクラス側で使用する方法
を教えて頂けないでしょうか?

具体的には下記サイトで見つけた方法なのですが、
http://hpcgi1.nifty.com/MADIA/VBBBS/wwwlng.cgi?print+200501/05010058.txt
実際に同じものを作ったところ

'TimerがNew で生成できないのでフォームに張り付いた物を流用させてもらう
Public Sub setTimer(newTimer As Timer)
    Set myTimer = newTimer
End Sub

の関数でコンパイルエラーが発生します。
試しに
Public Sub setTimer(newTimer As Object)
とすればコンパイルエラーは解消するのですが、実行時エラーが発生します。
もしわかる方いらっしゃいましたら教えてください。
よろしくお願い致します。

Windows 2000 Professional(SP3)
VB6.0(SP3)
VB6.0でのプログラマ歴5年程度

[ツリー表示へ]
タイトルRe: クラス内のタイマーイベントについて
記事No15138
投稿日: 2011/03/10(Thu) 22:03
投稿者花ちゃん
>   ・クラス内でタイマーオブジェクトを作成することは出来ない。但し宣言は可能
タイマーオブジェクト とは、タイマーコントロールのことをいっておられるのでしょうか?

Win32 API の SetTimer 関数 や マルチメディアタイマーを使ったのではだめですか?

[ツリー表示へ]
タイトルRe^2: クラス内のタイマーイベントについて
記事No15139
投稿日: 2011/03/10(Thu) 23:54
投稿者いまぷ

> Win32 API の SetTimer 関数を使ったのではだめですか?
ご回答ありがとうございます。
SetTimerでも問題無いのですが、実はSetTimerも使ってみたところ、
4つめの引数(lpTimerFunc)でAddressOfを使用し、コンパイルすると、
コンパイルエラーが発生してしまいました。

Private Declare Function SetTimer Lib "user32" ( _
    ByVal hWnd As Long, _
    ByVal nIDEvent As Long, _
    ByVal uElapse As Long, _
    ByVal lpTimerFunc As Long _ ←この引数です。
) As Long

いろいろなサイトを回って調べたのですが、AddressOfで指定するメソッドは
クラスではなく、Basファイルに登録するとの事だったのでSetTimerは諦めていました。
(参照サイトは下記を見たのですが。。。)
http://www.gizcollabo.jp/vbtomo/log/archive/vbqanda_5795_1.html

機能的にはSetTimerでも全く問題ないのですが、SetTimerでクラス側のメソッドを
呼ぶことは可能なのでしょうか?

[ツリー表示へ]
タイトルRe^3: クラス内のタイマーイベントについて
記事No15140
投稿日: 2011/03/11(Fri) 01:33
投稿者花ちゃん
> いろいろなサイトを回って調べたのですが、AddressOfで指定するメソッドは
> クラスではなく、Basファイルに登録するとの事だったのでSetTimerは諦めていました。

標準モジュールに書いてクラスからよぶとか、AddressOf の部分をForm に書くとかは
だめなのですか?

[ツリー表示へ]
タイトルRe^3: クラス内のタイマーイベントについて
記事No15141
投稿日: 2011/03/11(Fri) 05:27
投稿者魔界の仮面弁士
> 機能的にはSetTimerでも全く問題ないのですが、SetTimerでクラス側のメソッドを
> 呼ぶことは可能なのでしょうか?

AddressOf には Module が必要です。
一応、下記のような手法もありますが…Form の Timer の方が楽ですね。


'------ 標準モジュール Module1 ------
Option Explicit
Public Sub TimerProc(ByVal hWnd As OLE_HANDLE, ByVal uMsg As Long, ByVal idEvent As ITimer, ByVal dwTime As Long)
    If Not idEvent Is Nothing Then
        idEvent.OnTick dwTime
    End If
End Sub

'------ クラス ITimer ------
Option Explicit
Public Sub OnTick(ByVal uElapse As Long)
End Sub
Private Sub Class_Initialize()
    Err.Raise 419
End Sub

'------ クラス CTimer ------
Option Explicit
Implements ITimer
Public Event Tick(ByVal uElapse As Long)
Private Declare Function SetTimer Lib "user32" (ByVal hWnd As OLE_HANDLE, ByVal nIDEvent As ITimer, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Private Declare Function KillTimer Lib "user32" (ByVal hWnd As OLE_HANDLE, ByVal nIDEvent As ITimer) As Long
Private m_owner As OLE_HANDLE
Public Function StartTimer(ByVal owner As OLE_HANDLE, ByVal elapse As Long) As Boolean
    If m_owner = 0 And owner <> 0 Then
        m_owner = owner
        SetTimer owner, Me, elapse, AddressOf Module1.TimerProc
        StartTimer = True
    Else
        StartTimer = False
    End If
End Function
Public Sub StopTimer()
    If m_owner <> 0 Then
        KillTimer m_owner, Me
        m_owner = 0
    End If
End Sub
Private Sub ITimer_OnTick(ByVal uElapse As Long)
    RaiseEvent Tick(uElapse)
End Sub

'------ フォーム Form1 ------
Option Explicit
Private WithEvents tm As CTimer
Private Sub Form_Load()
    Set tm = New CTimer
    Command1.Enabled = True
    Command2.Enabled = False
    Command1.Caption = "開始"
    Command2.Caption = "停止"
End Sub
Private Sub Command1_Click()
    Command1.Enabled = False
    Command2.Enabled = True
    tm.StartTimer Me.hWnd, 100
End Sub
Private Sub Command2_Click()
    Command1.Enabled = True
    Command2.Enabled = False
    tm.StopTimer
End Sub
Private Sub tm_Tick(ByVal uElapse As Long)
    Debug.Print uElapse
End Sub

[ツリー表示へ]
タイトルクラス内のタイマーイベントについて【解決】
記事No15142
投稿日: 2011/03/11(Fri) 13:01
投稿者いまぷ
花ちゃん様、魔界の仮面弁士様
ご回答ありがとうございました。
お陰さまで機能実現できました。非常に助かりました。

FormのTimerについてですが、機能はSetTimerで実現できたため問題ないのですが、
後学のため提示頂いたプログラムを参考にしてFormのTimerで作ってみます。
(「参考に」が良くないことは認識しているのですが、今悩みながら試しているので
  少し時間がかかりそうです…すみません…。)

どちらにせよ本当に助かりました。
ありがとうございました。

[ツリー表示へ]