タイマーのつかい方が今ひとつ分かりません。
MFCでタイピングのゲームを作成しているのですが、
25問を解き、正解だった場合もしくは制限時間を超えてしまった場合、次の問題を表示したいと思っております。
下記がプログラム内容です。
void CProgramView::Loop1(CDC* pDC)
{
CProgramDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if((m_nRight<26)|(0<m_nRight))
{
m_nRight=0;//正解数
m_nQuestion=1;//問題数
}
Haikei(pDC);//問題表示領域の枠表示
Tokei(pDC);//時計の秒針が表示される枠表示
Moji(pDC);//問題文表示
OnChar(ch, count,flags);//入力
if(m_fTimer==FALSE)
{
SetTimer(123,250,NULL);//タイマーをセット
if(m_nQuestion<26)//25問以上問題を解いていないケース
{
m_fTimer = FALSE;
}
else m_fTimer = TRUE;//全問解いた場合
}
Loop0(pDC);//秒針の描画クラス
if(m_nx==715)//タイムアウトだった場合
{
KillTimer(123);
NGPaper(pDC);
m_nQuestion++;//問題をカウント
m_sAnser.Empty();//回答文字列をクリア
pDoc->GetNextSet();//次の問題を取得する
InvalidateRect(NULL);
}
if(m_nQuestion<m_nCount)//正解だった場合
{
KillTimer(123);//タイマーを切る
Tokei(pDC);//秒針の画像を消すために時計の画面を再描画
Right(pDC);//正解した場合の画像を描画
Haikei(pDC);//問題文・回答を消すために問題表示領域の枠を再描画
PartsPaper1(pDC);//正解した場合の壁紙を表示
m_nQuestion++;//問題数をカウント
m_sAnser.Empty();//回答文字列をクリアする
pDoc->GetNextSet();//次の問題を取得する
InvalidateRect(NULL);
}
}
そして、この動作を25問、解くまでループさせる関数として以下の関数を作成しました。
void CProgramView::Loop2(CDC* pDC)
{
if(m_fTimer==FALSE)
{
Loop1(pDC);
}
}
//タイマーの内容
void CProgramView::OnTimer(UINT nIDEvent)
{
// TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォルトの処理を呼び出してください
if(nIDEvent == 123)
{
InvalidateRect(NULL);
}
CView::OnTimer(nIDEvent);
}
しかし、実際にこのプログラムを実行すると入力し、正解する間は次の問題が表示されるのですが、タイマーが切れません。
そして、制限時間になるとそこまで解いていた問題から凄い勢いで描画が始まり、止まりません。
おそらくタイマーが正常に使えていないという可能性が考えられるのですが・・・。
希望としては、25問を順次解き、解き終わった後は画像を描画し、次の問題を表示したいのですが、どうしたら良いか教えてください。
No.3ベストアンサー
- 回答日時:
Windowsアプリの場合 WM_何とかといったメッセージをWindowsから受け取って動作する仕組みになっています
ボタンを押したのであれば WM_COMMANDとどのボタンかのパラメータ
再描画なら WM_PAINTといった具合です
このメッセージポンプは CWinAppの派生クラスに実装されています
ですからボタンを押した際の処理を OnButton1 などのイベントハンドラと メッセージ振り分けようのメッセージマップでといった具合でMFCは構成されています
このポンプは1つ(または複数)の関数から抜け出た後に戻ることになっています
関数内ではポンプ機能は働きません
void OnButton1()
{
CString ss;
for( int n = 0; n <= 100; n++ ) {
ss.Format( "%d", n );
m_Static1.SetWindowText( ss );
}
}
といった関数があった場合 作者は ラベルの表示を 0から100まで変化させたかったとしても 実際には 100しか表示されないということになります
なぜなら コントロールの再描画がこの関数の中では一切そのチャンスがないからです
// ボタンの押した時は カウンタをリセット、フラグをセット、タイマーをセットするだけ
void OnButton1()
{
if ( m_bflag == FALSE ) {
m_myCnt = 0;
SetTimer( 100, 500, NULL );
}
m_myFlag = TRUE;
}
//ここでメッセージポンプへ返る
// 500msごとに呼び出されるタイマーイベントでラベルへの設定を変更する
void OnTimer( UINT nIDEvent )
{
if ( nIDEvent == 100 ) {
CSTring ss;
ss.Format( "%d" , m_myCnt );
// ラベルへデータを設定
m_Static1.SetWindowText( ss );
myCnt++;
if ( myCnt == 100 ) {
// カウンタが終了値になったなので タイマーを止め
// フラグをリセット
KillTimer( 100 );
m_bFlag = FALSE;
}
}
}
//次のイベント発生のためここでメッセージポンプへ返る
といった具合に作成します
No.2
- 回答日時:
Windowsのタイマーを使うのであれば メッセージポンプを動作させないといけないと思います
メッセージポンプとはウィンドウズの基本システムです
GetMessageやPeekMessage、DiapatchMessage/TranslateMessage
などで構成します
MFCを使うなら
AfxGetApp()->PumpMessage();
でいいようです
流れとしては
1) 問題文の選定
1-2) タイマーを設定 SetTimer
2) 入力値のチェック
2-1) 正解/不正解時のカウント
2-2) タイマーの停止
2-3) 25問未満の場合 1)へ戻って処理続行
3) タイマーイベントで時間切れの処理
3-1) 25問未満の場合 1)へ戻って処理続行
といった関数を用意して、それぞれの処理後関数から抜けるようにしましょう
この回答への補足
ご解答ありがとうございます。
メッセージポンプ・・・!?根本的な問題が解決していないのだと気付かされました。
そこで大変、申し訳ないのですが、具体的なメッセージポンプの利用方法を教えていただけないでしょうか。
No.1
- 回答日時:
★よく読んでいませんが…。
・単純に経過時間を計測したいのなら GetTickCount() 関数を使います。
(他にもGetTickCount64、timeGetTime、QueryPerformanceCounterなど)
サンプル:
DWORD m_dwStart; ←メンバ変数に加える
// 問題の出題開始時
m_dwStart = GetTickCount();
// 問題の出題終了時
DWORD dwDiff = (GetTickCount() - m_dwStart);
if ( dwDiff < (3 * 60 * 1000) ){
3分以内ならこちらで処理
}
else{
3分以上ならこちらで処理
}
このような感じで分岐すれば良いでしょう。
ご解答ありがとうございます。
言葉が足りなく申し訳ございません。
時間計測がしたいというよりも、時間経過後の再度、最初の動作に戻り、ループさせたいのです。
お手数をおかけし申し訳ございません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) VBAで早押しゲームを作りたい 4 2022/05/12 13:46
- Excel(エクセル) エクセルの数式で教えてください。 2 2023/03/10 13:21
- Java 問題作成のWebアプリの作り方を教えてください 1 2022/11/26 22:01
- その他(プログラミング・Web制作) Pythonを用いたフラッシュ暗算ソフトの開発に必要なもの 2 2023/01/29 02:22
- 英語 "consider doing something"において"doing"の要否の判断方法について 2 2023/07/04 04:36
- Visual Basic(VBA) 【VBA】写真の貼り付けコードがうまく機能しません。 5 2022/09/01 18:43
- WordPress(ワードプレス) WordpressでYouTubeの埋め込みができない。 1 2022/10/26 01:08
- Excel(エクセル) <スプレッドシート>IF関数の複数条件について 5 2022/10/27 14:38
- Excel(エクセル) エクセル VBA For Next 繰り返しの書き方を教えてください 6 2022/09/01 14:11
- C言語・C++・C# このプログラミングの問題を教えて欲しいです。 キーボードから整数kを入力し、kが配列aの中に何個存在 2 2022/12/19 22:50
このQ&Aを見た人はこんなQ&Aも見ています
-
カンパ〜イ!←最初の1杯目、なに頼む?
飲み会で最初に頼む1杯、自由に頼むとしたら何を頼みますか? 最初はビールという縛りは無しにして、好きなものを飲むとしたら何を飲みたいですか。
-
一回も披露したことのない豆知識
あなたの「一回も披露したことのない豆知識」を教えてください。 「そうなんだね」と「確かに披露する場所ないね」で評価します。
-
これ何て呼びますか Part2
あなたのお住いの地域で、これ、何て呼びますか?
-
プリン+醤油=ウニみたいな組み合わせメニューを教えて!
プリンと醤油を一緒に食べると「ウニ」の味がする! というような意外な組み合わせから、新しい味になる食べ物って色々ありますよね。 あなたがこれまでに試した「組み合わせメニュー」を教えてください。
-
好きな和訳タイトルを教えてください
洋書・洋画の素敵な和訳タイトルをたくさん知りたいです!【例】 『Wuthering Heights』→『嵐が丘』
-
CStringのFindで文字列検索を行いたいのですが
C言語・C++・C#
-
画面を強制的に再描画させる方法
C言語・C++・C#
-
ボタンの表示の色、フォントを変更したい
C言語・C++・C#
-
-
4
ダイアログ内コントロールの位置取得について
C言語・C++・C#
-
5
エディットボックスのフォントを変えたい
C言語・C++・C#
-
6
VC++スレッドの正しい終了のさせかた
C言語・C++・C#
-
7
エディットボックスの入力制限について
C言語・C++・C#
-
8
CWnd::OnTimerのスレッドの取得
C言語・C++・C#
-
9
DWORDの実際の型は何でしょうか
C言語・C++・C#
-
10
CStaticコントロールの静的イメージ描画
C言語・C++・C#
-
11
CStringをwchar_tに変換したい
C言語・C++・C#
-
12
MFCのワーカースレッドとUIスレッドの使い分け
C言語・C++・C#
-
13
【C++】関数ポインタの使い方
C言語・C++・C#
-
14
静的でないメンバ関数の呼び出しが正しくありません
C言語・C++・C#
-
15
MFC Timerについて
C言語・C++・C#
-
16
MFCでOnPaintのタイミング
C言語・C++・C#
-
17
MFC通信プログラムマルチスレッドで例外スロー
C言語・C++・C#
-
18
スレッドの終了はどうやるんですか?
C言語・C++・C#
-
19
ダイアログ表示時にチェックボックスにチェックされている状態にするには?
C言語・C++・C#
-
20
SetWindowText関数について
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/22】このサンタクロースは偽物だと気付いた理由とは?
- ・お風呂の温度、何℃にしてますか?
- ・とっておきの「まかない飯」を教えて下さい!
- ・2024年のうちにやっておきたいこと、ここで宣言しませんか?
- ・いけず言葉しりとり
- ・土曜の昼、学校帰りの昼メシの思い出
- ・忘れられない激○○料理
- ・あなたにとってのゴールデンタイムはいつですか?
- ・とっておきの「夜食」教えて下さい
- ・これまでで一番「情けなかったとき」はいつですか?
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
[VB.net] DataGridViewの列ヘッ...
-
word
-
PCで「使用可能な場合はグラフ...
-
OneNote 2010 文字と描画がずれる
-
TextBoxに文字を書いても表示さ...
-
MFCでOnPaintのタイミング
-
VB6,リストボックスの特定行の...
-
NVIDIAのシェーダーキャッシュ
-
VBAにGDI+を参照させる方法
-
ビットマップを表示させる(MFC)
-
UpdateData( FALSE); による文...
-
フォームにビットマップを表示
-
エクセルでガンチャートを作成...
-
C#のタブコントロールについて...
-
コンボボックスの高さを変えたい
-
c++ ダブルバッファリング、以...
-
CDC(LineTo)で描画した線を透過...
-
MFC FormViewの背景色
-
(C# .Net) ToolStripのボタンの...
-
MFCタブコントロールのグラデー...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Minecraft 統合版(PC)の描画距...
-
word
-
TextBoxに文字を書いても表示さ...
-
VB6,リストボックスの特定行の...
-
[VB.net] DataGridViewの列ヘッ...
-
MFCでOnPaintのタイミング
-
NVIDIAのシェーダーキャッシュ
-
C++にて、塗りつぶされた円を描...
-
UpdateData( FALSE); による文...
-
VC++プログラムをつかったBMP画...
-
MFCのタイマーのつかい方を教え...
-
CStaticコントロールの静的イメ...
-
画面全体を再描画させたい
-
OneNote 2010 文字と描画がずれる
-
VBAにGDI+を参照させる方法
-
Labelの文字をスクロールする際...
-
Form1 Load で実行されない。
-
InvalidateRectの使い方について
-
テクスチャに半透明ポリゴンを...
-
Windowのちらつき防止
おすすめ情報