SetTimerの処理が終わるまで待ちたい

[戻る]
こり 2009/10/22(木) 18:15:55
SetTimerで呼び出した関数の処理が終わるまで、次の処理に進みたくないのですがどうす
ればいいでしょうか?

[具体的なコード]
void CPA10_base_01Dlg::OnBnClickedTimeTest()
{
    for(k=1;k<4;k++){
        cpa.PA_MOVE(k);
        SetTimer(13,100,NULL);    //タイマー13をセット(100msecごとに更新)
    }
}
・PA_MOVEでは、モノを動かす処理を行っています
・SetTimerでは、動かしたモノを初期位置に戻す処理を行っています

ざわざわ 2009/10/23(金) 00:56:34
一番簡単そうなのが、Timerの処理が終わるのをフラグで監視して

void CPA10_base_01Dlg::OnBnClickedTimeTest()
{
    for(k=1;k<4;k++){
        cpa.PA_MOVE(k);
        m_flg = FALSE;
        SetTimer(13,100,NULL);    //タイマー13をセット(100msecごとに更新)
        for(;;){
             DoEvents();
            if(m_flg == TRUE) break;
        }
    }
}

void CPA10_base_01Dlg::OnTimer()
{
   //処理
   m_flg = TRUE;
}

だと思われます。DoEventsについては
void CPA10_base_01Dlg::DoEvents()
{
    MSG    msg;
    if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
        ::TranslateMessage(&msg);
        ::DispatchMessage(&msg);
    }
}

こんなの書いておけば大丈夫かも。

bun 2009/10/23(金) 09:40:06
いまいち意図が理解できない。

> SetTimerで呼び出した関数の処理が終わるまで、次の処理に進みたくないのですがど
うす
という問いかけと、

以下のコードからすると、
>    for(k=1;k<4;k++){
>        cpa.PA_MOVE(k);
>        SetTimer(13,100,NULL);    //タイマー13をセット(100msecごとに更新)
>    }

例えば、k=1 のとき   cpa.PA_MOVE(1); を処理して、
次の    k=2 における cpa.PA_MOVE(2); を処理するまでに、
100ms待ちたいと言う風に読めるのですが、

それなら、以下のコードでOK
    for(k=1;k<4;k++){
        cpa.PA_MOVE(k);
        Sleep(100);
    }

でも、きっとそういう意味じゃないですよね?

ryo 2009/10/23(金) 12:15:08
>      SetTimer(13,100,NULL);    //タイマー13をセット(100msecごとに更新)
この「ごとに更新」が、
OnBnClickedTimeTest()にかかわらず、今後もずっと「ごとに更新」させていきたいのか

それとも
「動作したあと、100msecまってから、初期値に戻す処理」を4回やりたいが
Sleep(100)では、Sleep中に固まってるような動作になってしまうので
いったんタイマーを使うことでメッセージループを受け取れるようにしたかった

のか

後者であると仮定して、ざわざわさんとbunさんのを合わせ技してみる

void CPA10_base_01Dlg::OnBnClickedTimeTest()
{
    for(k=1;k<4;k++){
        cpa.PA_MOVE(k);

//  forとSleepの組み合わせで100msec待つ間、メッセージがあったら処理する(始)
    MSG    msg;
        for (int i = 0 ; i < 10 ; i++ ){
        while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
         ::TranslateMessage(&msg);
            ::DispatchMessage(&msg);
          }
      Sleep(10);
        }
//  forとSleepの組み合わせで100msec待つ間、メッセージがあったら処理する(終)
    
    cpa.(初期値に戻す処理);    

   }
}

WM_TIMERタイマーは使ってません

こり 2009/10/23(金) 12:43:02
[[解決]]
説明不足で申し訳ございません。

k=1 のとき   cpa.PA_MOVE(1); を処理して、
次のk=2 における cpa.PA_MOVE(2); を処理するまでに、
SetTimerの処理?
   if(nIDEvent ==13){
         ・・・
            }
を何度か(一定回数ではない)行いたかったのですが、
cpa.PA_MOVE(1)の処理の後、おそらく「1回だけ」if(nIDEvent ==13){}の処理を行って次
のcpa.PA_MOVE(2)の処理を行ってしまうという状態でした。

フラグの方法も自分なりのやってみたのですがうまくいかず、最終的に以下の方法で解決
できました。

SetTimerで呼び出す処理内容をwhile(1)の中に記述
→処理終了条件をフラグで監視して、フラグが発行されたらif文でbreak

分かりづらかったら申し訳ございません。
回答ありがとうございました。

ITO 2009/10/24(土) 10:00:22
> SetTimerで呼び出す処理内容をwhile(1)の中に記述
> →処理終了条件をフラグで監視して、フラグが発行されたらif文でbreak
うーーん、
皆さんご指摘ないのですが、
 void CPA10_base_01Dlg::OnBnClickedTimeTest()
であまり多くの処理をするのはよくないと思います。
メインの処理はスレッドで行い、
  OnBnClickedTimeTest()でスレッドを読み出すようにしたほうがいいと思います。

っていうより、WM_TIMERにこだわるのなら、
  ・K相当のメンバー変数を用意する。
  
    ・OnBnClickedTimeTest()でフラグをセットする。
  ・Ontimer()でフラグをチェックする。
  ・メンバー変数をインクルメントしながら
    「for(k=1;k<4;k++){」内の処理を行なう
  ・メンバー変数が4になったら、
     メンバー変数リセット、フラグリセット
  ・でまたフラグ待ち
ではだめですか?

正確な時間がほしいのならマルチメディアタイマーにするといいですね。



      

ITO 2009/10/24(土) 10:02:16
あっと、

>  ・K相当のメンバー変数を用意する。
この下に
   ・SetTimer(13,100,NULL);    
これですね

古いスレッドには追加発言できません。