S-JIS[1998-01-11/2007-10-13]

タイマーの使い方

AppWizardで作成したMFCアプリケーションで APIのタイマー(マルチメディアタイマー)を使う例を示します。


  1. CMainFrameクラスに、タイマーで呼び出される関数を追加します。

    MainFrm.h:

    class CMainFrame : public CFrameWnd
    {
    〜
    public:
    	static void CALLBACK TimerProc(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2);
    	static UINT m_uiTimerID;
    〜
    };
    

    MainFrm.cpp:

    UINT CMainFrame::m_uiTimerID=0;
    
    void CALLBACK CMainFrame::TimerProc(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
    {
    	if(uTimerID==m_uiTimerID){
    		((CMainFrame*)dwUser)->TimerMain();	//メイン処理を行う
    	}
    }
    
    CMainFrame::TimerMain()は自分で作って下さい。
    タイマーで実際の処理を行う部分です。 自分のウィンドウがアクティブかどうかを判定し、アクティブでなければ何もせず、 アクティブなら さらにC〜ViewやC〜Doc等のクラスの関数を呼び出すことになるでしょう。

    ※VC++2005では、TimerProcの引数の型がDWORDでなくDWORD_PTRに変わっています。[2007-10-13]
    まぁVC++2005でMFCは使わないでしょうが…。


  2. CWinAppから派生したクラス(この例ではCTimerApp)に、タイマーを開始する部分を追加します。

    timer.cpp:

    〜
    #include "stdafx.h"
    #include "MMsystem.h"
    〜
    BOOL CTimerApp::InitInstance()
    {
    〜
    	((CMainFrame*)m_pMainWnd)->m_uiTimerID=::timeSetEvent(50,30,((CMainFrame*)m_pMainWnd)->TimerProc,(DWORD)m_pMainWnd,TIME_PERIODIC);
    
    	return TRUE;
    }
    

  3. CMainFrameクラスに、ClassWizardでWM_DESTROYの関数を追加し、 タイマー呼び出しを終了する部分を追加します。

    MainFrame.h:

    class CMainFrame : public CFrameWnd
    {
    〜
    // 生成されたメッセージ マップ関数
    protected:
    	//{{AFX_MSG(CMainFrame)
    	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    	afx_msg void OnDestroy();
    	//}}AFX_MSG
    	DECLARE_MESSAGE_MAP()
    };
    
    MainFrame.cpp:
    〜
    #include "stdafx.h"
    #include "MMsystem.h"
    〜
    BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
    	//{{AFX_MSG_MAP(CMainFrame)
    	ON_WM_CREATE()
    	ON_WM_DESTROY()
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    〜
    void CMainFrame::OnDestroy() 
    {
    	::timeKillEvent(m_uiTimerID);
    
    	CFrameWnd::OnDestroy();
    }
    

  4. リンクするライブラリに、WinMM.libを追加します。

    VC++4.0の場合、以下の方法で設定できます。
    [ビルド]→[設定]で「プロジェクト設定」ダイアログが出ます。
    「リンク」タブの中の「オブジェクト/ライブラリモジュール」に、WinMM.libを追加します。

    ただし裏技(?)として、ソースファイルに次のように書くことで代用できます。

    MainFrame.cpp:
    #include "MMsystem.h"
    #pragma comment(lib,"WinMM.lib")
    

::timeSetEventについて

UINT timeSetEvent(UINT wDelay,UINT wResolution,LPTIMECALLBACK lptc,DWORD dwUser,UINT fuCallbackType);

例: timeSetEvent(50,30,((CMainFrame*)m_pMainWnd)->TimerProc,(DWORD)m_pMainWnd,TIME_PERIODIC);
精度30ミリ秒で50ミリ秒間隔のタイマーを発行し、TimerProc関数を呼び出すようになります。
詳細はAPIのヘルプを参照して下さい。

なお、この割込みは別スレッドで行われるので要注意です。[2006-04-22]


VC++ページへ戻る / 技術メモへ戻る
メールの送信先:ひしだま