プロが教えるわが家の防犯対策術!

お世話になります、fujitomoです。
今回お聞きしたいのはマルチメディアタイマーのプログラムの使用方法についてです。現在下記のようなコードを作成して、マルチメディアタイマーを動作させたいと思っていますが、なぜか処理が固まってしまいます。
プログラムはVisual Studio2005のVisual C++のダイアログベースのプログラムで、CStatic派生クラスをメインダイアログクラスにてサブクラス化した際の動作を示しています。
//CStatic派生のクラスCSampleクラスのヘッダーファイル
//CSample.h
class CSample : public CStatic
{
static void CALLBACK TimerProc(UINT uTimerID,UINT uMsg,DWORD dwUser,DWORD dw1,DWORD dw2);
static UINT TimerID;
}
//CSample.cpp
void CSample::PreSubclassWindow()
{
TIMECAPS timercaps;
MMRESULT mmresult;
//分解能を取得
mmresult = timeGetDevCaps(&timercaps,sizeof(TIMECAPS));
if(mmresult != TIMERR_NOERROR){
AfxMessageBox(_T("分解能取得失敗"));
return;
}
else
period = timercaps.wPeriodMin;
//最小タイマー分解能の設定
mmresult = timeBeginPeriod(period);
if(mmresult != TIMERR_NOERROR){
AfxMessageBox(_T("分解能設定失敗"));
return;
}
//タイマー処理の呼び出しの設定と開始
mmresult = ::timeSetEvent(500,period,TimerProc,0,TIME_PERIODIC|TIME_CALLBACK_FUNCTION);

if(mmresult == NULL){
AfxMessageBox(_T("タイマー処理失敗"));
return;
}
else TimerID = (UINT)mmresult;

}

void CALLBACK CSample::TimeProc(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
if(uTimerID == TimerID){
;
}
}

というコードです。自分の予想ではTimerProcにブレークポイントを置いて、デバックを開始すると500msecでTimerProcにとぶと思っているのですが、実際はtimeSetEvent()を呼び出した後にプログラムの動作が止まってしまいます。
これは何が原因なのかわかりますでしょうか?
timesetEvent()を使用するのが初めてで、なかなか使い方が分からず初歩的な質問なのかもしれませんが、どうかご意見を宜しくお願い致します。

尚、開発環境は
Visual Studio 2005
Windows CE 6.0
です。宜しくお願い致します。

A 回答 (1件)

 こんにちは。


 試してみましたが、正常に動いています。サブクラスの掛け方に失敗しているのではないでしょうか。

//CTestDlg.cpp
//

BOOL CTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// "バージョン情報..." メニューをシステム メニューに追加します。

// IDM_ABOUTBOX は、システム コマンドの範囲内になければなりません。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// このダイアログのアイコンを設定します。アプリケーションのメイン ウィンドウがダイアログでない場合、
// Framework は、この設定を自動的に行います。
SetIcon(m_hIcon, TRUE);// 大きいアイコンの設定
SetIcon(m_hIcon, FALSE);// 小さいアイコンの設定

// TODO: 初期化をここに追加します。

//スタティックコントロールのサブクラス化
m_sample.SubclassDlgItem(IDC_STATIC1, this);

return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}


// Sample.cpp : 実装ファイル
//

#include "stdafx.h"
#include "listview.h"
#include "Sample.h"

#include<mmsystem.h>
#pragma comment(lib, "winmm.lib")

// CSample
IMPLEMENT_DYNAMIC(CSample, CStatic)

//staticメンバ変数
UINT CSample::TimerID = 0;

//staticメンバ関数
void CALLBACK CSample::TimerProc(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
//取り敢えずコールバック回数をスタティックテキストにカウント表示
static int sCount = 0;
CSample* pSample = reinterpret_cast<CSample*>(dwUser);
CWnd* pParent = pSample->GetParent();
pParent->SetDlgItemInt(IDC_STATIC1, sCount++);
}

CSample::CSample()
{

}

CSample::~CSample()
{

}

BEGIN_MESSAGE_MAP(CSample, CStatic)
END_MESSAGE_MAP()

// CSample メッセージ ハンドラ
void CSample::PreSubclassWindow()
{
// TODO: ここに特定なコードを追加するか、もしくは基本クラスを呼び出してください。

TIMECAPS timercaps;
MMRESULT mmresult;

//分解能を取得
mmresult = timeGetDevCaps(&timercaps,sizeof(TIMECAPS));
if(mmresult != TIMERR_NOERROR)
{
AfxMessageBox(_T("分解能取得失敗"));
return;
}

//最小タイマー分解能の設定
mmresult = timeBeginPeriod(timercaps.wPeriodMin);
if(mmresult != TIMERR_NOERROR)
{
AfxMessageBox(_T("分解能設定失敗"));
return;
}

//タイマー処理の呼び出しの設定と開始
mmresult = ::timeSetEvent(500, timercaps.wPeriodMin, TimerProc, reinterpret_cast<DWORD_PTR>(this), TIME_PERIODIC | TIME_CALLBACK_FUNCTION);

if(mmresult == NULL)
{
AfxMessageBox(_T("タイマー処理失敗"));
return;
}

//staticに代入
TimerID = (UINT)mmresult;

//スーパークラスに渡す
CStatic::PreSubclassWindow();
}
    • good
    • 0
この回答へのお礼

machongola様、御回答ありがとうございます。
どうやら、Widows CE環境ですと、動作が正常にいかないようです。
私もXPで同じコードで作成して、実行してみたところ動作しました。
確認不足だったようです。。
動作確認をしていただき、ありがとうございました。

お礼日時:2009/07/06 18:52

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