timeSetEventの第3引数が変換できないというエラー – プログラミング – Home

timeSetEventの第3引数が変...
 
通知
すべてクリア

[解決済] timeSetEventの第3引数が変換できないというエラー


縞々
 縞々
(@縞々)
ゲスト
結合: 18年前
投稿: 3
Topic starter  

はじめまして、縞々と申します。

環境
(OS)WindowsXP Home
(ソフト)VC++6.0

timeSetEventなどの関数を用いたマルチメディアタイマを使ってSetTimerよりも精度の高
いストップウォッチ(カウンタ)を作ろうとしているのですが、timeSetEventの関数でエ
ラーがでてしまいプログラムが実行できませんでした。

以下エラーのコピペ
--------------------構成: 04 - Win32 Debug--------------------
コンパイル中...
04View.cpp
D:\Visual C++\練習\リアルタイム制御\ストップウォッチ\04\04View.cpp(138) : error
C2664: 'timeSetEvent' : 3 番目の引数を 'void (unsigned int,unsigned int,unsigned
long,unsigned long,unsigned long)' から 'void (__stdcall *)(
unsigned int,unsigned int,unsigned long,unsigned long,unsigned long)' に変換でき
ません。 (新しい機能 ; ヘルプを参照)
スコープ内でこの名前を持つ関数でターゲット型に一致するものはありません。
コードを生成中...
コンパイル中...
04.cpp
コードを生成中...
cl.exe の実行エラー

04.exe - エラー 1、警告 0

以下プログラムの作成手順です。
(1) MFCをSDIでつくる。(その際ステップ6で基本クラスを”CFormView”に)
(2) プロジェクト→設定 より リンクタブからすべての構成にwinmm.libをリンク
(3) ボタンを2つ、スタティックテキストを1つ追加
(4) ボタン1:IDC_START スタート ボタン2:IDC_STOP ストップ
スタティック:IDC_COUNT 秒 にそれぞれ変更
(5) スタートボタンをダブルクリックしてOnStart関数を追加、同様にストップも追加
(6) ClassViewよりViewクラスにメンバ変数 “int m_count;”を追加
(7) View.cppに#include MMsystem.hをインクルード
(8) View.hのインプリメンテーションのところに(int m_count;の下に)
void CALLBACK TimerProc(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1,
DWORD dw2); を追加(
(9) ソースコード 04View.cppに以下を追加しました。
// CMy04View クラスのメッセージ ハンドラ
//
void CALLBACK CMy04View::TimerProc(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD
dw1, DWORD dw2)
{
m_count++;
CWnd *wnd=GetDlgItem(IDC_COUNT);
CString str;
str.Format(%d秒,m_count);
wnd->SetWindowText(str);
}
void CMy04View::OnStart()
{
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
m_count=0;
CWnd *wnd=GetDlgItem(IDC_COUNT);
wnd->SetWindowText(0秒);
timeBeginPeriod(1);
timeSetEvent(10,0,TimerProc,NULL,TIME_PERIODIC);
}
void CMy04View::OnStop()
{
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
timeKillEvent(1);
timeEndPeriod(1);
}

私は、TimeSetEventの3つ目の引数が「この関数を使うよ」っていう感じで10msおきに
TimerProc関数を実行するようになっていると思っているのですが・・・。

プログラミングの経験としてはC言語は入門書をざっと読んだ程度、VC++は入門書のサン
プルをコピペしながら大まかに進んでいった程度です。
一度、SetTimer()を使ったストップウォッチのサンプルをコピペして、その中に追加処理
を書き込むようなことをしたことがあったので、timeSetEvent()も、インターネットで調
べたやつをちょこっと変えるだけだと思ったのですが・・・。

どなたか解決方法をよろしくおねがいします。


引用未解決
トピックタグ
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

> (8) View.hのインプリメンテーションのところに(int m_count;の下に)
> void CALLBACK TimerProc(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1,
> DWORD dw2); を追加(
staticなメンバ関数として宣言していないですよね?
staticなメンバ関数でないとTimerProcを呼ぶときに、インスタンスが必要になります。

staticなメンバ関数にすると、
> m_count++;
> CWnd *wnd=GetDlgItem(IDC_COUNT);
のようにメンバ変数やメンバ関数を使うことができなくなるので注意が必要です。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

staticな関数 TimerProcEntryを用意し:

void CALLBACK CMy04View::TimerProcEntry(UINT uTimerID, UINT uMsg, DWORD dwUser,
DWORD dw1, DWORD dw2) {
CMy04View* instance = (CMy04View*)dwUser;
return instance->TimerProc(utimerID, uMsg, dwUser, dw1, dw2);
}

ほんでもって:

void CMy04View::OnStart() {
...
timeSetEvent(10,0,TimerProc,(DWORD)this,TIME_PERIODIC);
}

…ってとこか。

# 「なんでこれでいいのか」はお勉強してください。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

追記です。

> timeKillEvent(1);
ではタイマーはとめれません。(たまたまとまることがあるかもしれないけど。。。)
timeSetEventの戻り値をどこかで保持しておいて、その値を指定しないといけません。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

ごめんチョンボ orz

> void CMy04View::OnStart() {
> ...
> timeSetEvent(10,0,TimerProc,(DWORD)this,TIME_PERIODIC);
> }

timeSetEvent(10,0,TimerProcEntry,(DWORD)this,TIME_PERIODIC);

が正解です。すんません。


返信引用
縞々
 縞々
(@縞々)
ゲスト
結合: 18年前
投稿: 3
Topic starter  

すばやい返答ありがとうございます。

御二方のご指摘を受けプログラムを自分の知識の限りで変更したのですが、やはりエラー
がでてしまいました。
それと、Blueさんのご指摘で「TimerProc()をstaticにすると、メンバ変数が使えなくな
る」とありましたが、私の場合「10msごとにm_countを1増やす」ようにしたいので、
m_count++をTimerProc()関数の中に入れられないことになる、というのはわかったのです
が、そうなると、どこで(どのように)10ms毎にカウントを1増やしたらいいのかがわか
りません。

以下エラーのコピペです(TimerProc関数を修正していないためエラーが多いですが
D:\Visual C++\練習\リアルタイム制御\ストップウォッチ\04\04View.cpp(130) : error
C2562: 'TimerProcEntry' : 関数は 'void' 型として宣言されていますが、値を返しました。
d:\visual c++\練習\リアルタイム制御\ストップウォッチ\04\04view.h(49) :
'TimerProcEntry' の宣言を確認してください。
D:\Visual C++\練習\リアルタイム制御\ストップウォッチ\04\04View.cpp(134) : error
C2597: 'CMy04View::m_count' : スタティック メンバ関数内の不正なデータ メンバへの参照です
D:\Visual C++\練習\リアルタイム制御\ストップウォッチ\04\04View.cpp(134) : error
C2105: '++' には左辺値が必要です。
D:\Visual C++\練習\リアルタイム制御\ストップウォッチ\04\04View.cpp(135) : error
C2352: 'CWnd::GetDlgItem' : 静的でないメンバ関数の中で呼び出しが正しくありません。
c:\program files\microsoft visual studio\vc98\mfc\include\afxwin.h(1992)
: 'GetDlgItem' の宣言を確認してください。
D:\Visual C++\練習\リアルタイム制御\ストップウォッチ\04\04View.cpp(137) : error
C2597: 'CMy04View::m_count' : スタティック メンバ関数内の不正なデータ メンバへの参照です
cl.exe の実行エラー

以下修正したソースです。
(1)View.hを修正
int m_count;
static void CALLBACK TimerProcEntry(UINT uTimerID, UINT uMsg, DWORD dwUser,
DWORD dw1, DWORD dw2);
static void CALLBACK TimerProc(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD
dw1, DWORD dw2);

(2)04View.cppを修正
// CMy04View クラスのメッセージ ハンドラ

MMRESULT uTimerID;

void CALLBACK CMy04View::TimerProcEntry(UINT uTimerID, UINT uMsg, DWORD dwUser,
DWORD dw1, DWORD dw2)
{
CMy04View* instance = (CMy04View*)dwUser;
return instance->TimerProc(uTimerID, uMsg, dwUser, dw1, dw2);
}

TimerProc()関数は修正していません
void CALLBACK CMy04View::TimerProc(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD
dw1, DWORD dw2)
{
m_count++;
CWnd *wnd=GetDlgItem(IDC_COUNT);
CString str;
str.Format(%d秒,m_count);
wnd->SetWindowText(str);
}
void CMy04View::OnStart()
{
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
    m_count=0;
    CWnd *wnd=GetDlgItem(IDC_COUNT);
  wnd->SetWindowText(0秒);
    timeBeginPeriod(1);
  uTimerID = timeSetEvent(10,0,TimerProcEntry,(DWORD)this,TIME_PERIODIC);
}
void CMy04View::OnStop()
{
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
timeKillEvent(uTimerID);
timeEndPeriod(1);
}

すみませんが再びご教授お願いします。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

επιστημη さんのとおり修正するならば、TimerProcの関数宣言にstatic をつけなくて
よいです。

> return instance->TimerProc(uTimerID, uMsg, dwUser, dw1, dw2);
は、void 型の関数ですので、戻り値は必要ないので、return はいりません。


返信引用
縞々
 縞々
(@縞々)
ゲスト
結合: 18年前
投稿: 3
Topic starter  

解決です。ありがとうございます。
御二方の助言のおかげで一週間悩んでいたものが解決しました。

今の状態では、とりあえずコピペしてやってみたのと同レベルなので、
これからがんばって完成したプログラムを理解していきたいと思います。

重ねて、すばやい返答・わかりやすい回答ありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました