質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.23%

タイマーの割り込み処理が正しく行われない。

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,620

TRON1216.

score 29

  • やりたいこと
    タイマー関数を用いて丸(円)が大きくなったり小さくなったりアニメーションのようなプログラムの作成。
  • 理想のプログラムの大まかな流れ
  1. ファイル(円の直径のデータが一行ずつ5000個入っている)を選択して、データを読み込み、一行ずつs[0]~s[4999]の配列に入れる。
  2. タイマー関数を用い、一定時間ごとにk++(初期値k=0)を施し、WM_PAINT内でellipse関数を用い、そこにs[k]のデータを入れて、s[0]からs[4999]で順に描画していく。
  3. マウスの左ボタンを押すと、タイマーが停止し、メッセージボックスが表示される。そこには、現在のデータが何番目かを表示(kの値)させる。
  4. マウスの右ボタンを押すと、再びタイマーが作動し、続きから描画されていく。
  • 問題点
    プログラムはビルドでき、実行したところ、パッと見た感じでは円が大きくなったり小さくなったりして成功したように見える。左クリックで現在のデータの番号が表示されて、右クリックで再び続きのデータを描画が開始された。しかし、タイマーの間隔を1sや2sにして、データ一つひとつに対して見てみると、一個目の円が描画されたときのkの値が25、二個目の円のときは50など、kが0から1ずつ増えていかず、とびとびの値になる。
  • 試してみたこと
    WM_PAINT内で、ellipse()を書いたあとにメッセージボックスを加えて、kの値を表示するようにした。すると、実行した瞬間(ファイルを選択し、データを読み込む前から)画面に次々にメッセージボックスが出てきてkの値が大きくなっていった。データの読み込みが完了してからタイマーを作動さればよい、、、、?けどどうしたらよいかわからない。

以下は、ウィンドウプロシージャのswitch内のコードです。ファイルの選択、読み込みなどは別のソースファイルで行っています。
 

switch (msg) {


    case WM_CREATE:
        SetTimer(hWnd_2, ID_MYTIMER, 1000, NULL);        
        break;

     case WM_PAINT:
        hdc = BeginPaint(hWnd2, &ps);
        hPen_MOON = CreatePen(PS_DOT, 0, RGB(255, 255, 0));
        h01dPen_MOON = (HPEN)SelectObject(hdc, hPen_MOON);
        hBrush_MOON = CreateSolidBrush(RGB(255, 255, 0));
        h01dBrush_MOON = (HBRUSH)SelectObject(hdc, hBrush_MOON);

        Ellipse(hdc, 329.5-(s[k]*1000000/4*329.5+0.5), 247-(s[k]*1000000/4*329.5+0.5), 329.5+(s[k]*1000000/4*329.5+0.5), 247+(s[k]*1000000/4*329.5+0.5)); //円をEllipse()を用いて描画




        DeleteObject(hPen_MOON);
        SelectObject(hdc, h01dPen_MOON);
        SelectObject(hdc, hBrush_MOON);
        SelectObject(hdc, h01dBrush_MOON);
        DeleteObject(hBrush_MOON);


        EndPaint(hWnd2, &ps);

        break;

     case WM_TIMER:
        if (wp != ID_MYTIMER)
            return (DefWindowProc(hWnd_bitmap, msg, wp, lp));
        ++k;
        if (++k > total_n)
            k = total_n - 1;
        InvalidateRect(hWnd_bitmap, NULL, FALSE);
        break;    

    case WM_LBUTTONDOWN:
            KillTimer(hWnd2, 1);
            sprintf_s(szBuf, 256, "%d番目のデータ",k);
            MessageBox(NULL, szBuf, "データの番号", MB_OK);
            break;    

    case WM_RBUTTONDOWN:
            SendMessage(hWnd2, WM_CREATE, 0,0);
            break;


    case WM_DESTROY:
        if( k = NULL){
        KillTimer(hWnd2, ID_MYTIMER);
        }
        PostQuitMessage(0);
        break;


    default:
        return (DefWindowProc(hWnd2, msg, wp, lp));



    }
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • unz.hori

    2018/02/24 09:19

    ソースが見にくいです。コード(</>)を使って貼ってください。また質問もだらだら文章で書いてあってわかりずらいです。ポイントを箇条書きで書くなどシンプルに書いてください。回答する人達の事を考えないと見ただけで萎えますよ。

    キャンセル

  • TRON1216.

    2018/02/24 16:34

    ありがとうございます。質問を修正してみました。またアドバイスあればよろしくお願いいたします。

    キャンセル

  • unz.hori

    2018/02/24 17:15

    ソースの部分ですが、```ここにソースを貼る```とやればインデントが正しく反映されます

    キャンセル

  • TRON1216.

    2018/02/24 17:20

    正しく反映されるよう修正しました。誠にありがとうございます。

    キャンセル

回答 3

+2

++k; if (++k > total_n)の部分ですが、++kとやる時点でkが加算されますがダブルカウントになってませんか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/24 18:11

    ソースが多分一部しか公開されていないのでkがどこで初期化されているのかどこで定義されているのかさっぱりわからないので回答不能です。

    キャンセル

  • 2018/02/24 18:15

    kはグローバル変数として別のソースファイルで初期化しています。
    kの初期化をウィンドウプロシージャ内で行うと、一定時間ごとにkが0から再スタートになってしまうまたはずっと0になってしまうので、ほかの場所で初期化したところ、いちおうアニメーションのように描画できました、、

    キャンセル

  • 2018/02/24 18:22

    プログラムの構成がよく分からないのでなんとも言えませんが、グローバル変数はバグの元なのであまり使うことをお勧めしません。クラスのメンバ変数とすればいいのではと思います。

    キャンセル

+1

一部分のソースなのであてずっぽうの指摘になります。

hWnd2、hWnd_bitmapは何ですか?
通常、ウィンドウプロシージャで渡されるHWND型の変数を使って各メッセージの処理を行います。
WindowProc - Microsoft
特にDefWindowProc関数に渡している第一引数が統一されていない時点でおかしいです。

WM_PAINTメッセージでBeginPaintの戻り値hdcをわざわざReleaseDCに渡していますが、渡さなくてよいです。ReleaseDCに渡すHDC変数はGetDC関数で取得したものだけです。

WM_RBUTTONDOWNメッセージでWM_CREATEを送信してますが、WM_CREATEはウィンドウが生成されたときに送られるメッセージです。つまり、自分で送るメッセージではありません

あなたは、一度猫でもわかるプログラミングの、Windows SDK編を順にやって正しいやり方を理解する必要があると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/24 17:39

    hWnd_bitmapはコピペみすです。

    三つ目の指摘ですが、タイマーを止めた後、再び途中からタイマーを再開するにはどうしたらよいのでしょうか、?はい、猫でもわかるウィンドウズプログラミングという本を使ってやっています、、まだまだ未熟ですが、よければ教えていただきたいです、、。

    キャンセル

  • 2018/02/24 17:51 編集

    SetTimer呼べばいいだけじゃん。

    猫でもわかるに大抵あるので探してください。
    今回でいえば以下が参考になりますかね。

    第9章 タイマーを使う
    http://www.kumei.ne.jp/c_lang/sdk/sdk_09.htm

    キャンセル

  • 2018/02/24 17:54

    ありがとうございます。

    キャンセル

check解決した方法

0

kをグローバル変数としてほかのソースファイルにも利用していたので、kではなく別の変数に置き換えたところ、無事s[o]か順に描画されました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.23%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる