• ベストアンサー

別のクラスからのタイマの起動方法

CXXXDlg ダイアログクラスに // ---------- タイムカウントタイマ起動 ---------- UINT CXXXDlg::StartTimeCount(UINT Interval) {   return SetTimer(1, Interval, NULL); } と言うメンバ関数を作り、別のクラスCTestで、下記の様な 感じでタイマ起動をしてOnTimerにて、ある変数のインクリ メント行おうとしているのですが、エラーが発生してしまいます。(コンパイルはOKです。OnTimerはもちろんCXXXDlgクラスに宣言) void CTest::TestTest() { CXXXDlg CXDlg; //100msタイマ起動 CXDlg.StartTimeCount(100); <- ここでエラー . . . (処理) . . . } WM_TIMERメッセージはウインドウが無いといけないことは 知っているのですが、上記の様な起動の仕方でも、やはり 駄目なのでしょうか?理由を教えて頂けるとありがたいで す。また、ダイアログクラスとは別のクラスでタイマの 起動・停止が可能でしたら、その方法もご存じの方 教えて下さい。 環境はWin2000 VC++ 6.0 SP6 MFC ダイアログベース です。よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.3

>WM_TIMERメッセージはウインドウが無いといけないことは 知っているのですが、 >上記の様な起動の仕方でも、やはり 駄目なのでしょうか? >CXXXDlg CXDlg; > >//100msタイマ起動 >CXDlg.StartTimeCount(100); <- ここでエラー CXDlg.Create()を呼ばないとウィンドウが存在しないんですけど。 外から呼びたいんでしたら、まずウィンドウなりモードレスのダイアログなり先に作ってください。 >また、ダイアログクラスとは別のクラスでタイマの 起動・停止が可能でしたら、その方法もご存じの方 教えて下さい。 SetTimerでコールバック関数を指定。 もしくはtimeSetEvent等のマルチメディアタイマーを使うとか。

tamajun
質問者

お礼

マルチメディアタイマにて実現出来ました。 ありがとうございました。

その他の回答 (3)

  • hope10
  • ベストアンサー率48% (17/35)
回答No.4

>return SetTimer(1, Interval, NULL); これは CWnd::SetTimer を呼んでいるからです。 タイマだけでなく、ダイアログの基底のCWndはウィンドウが無いと殆ど使えません。これは基本ですね。 対処方法は他の方が言われてる通りです。

tamajun
質問者

お礼

ありがとうございました。 >これは CWnd::SetTimer を呼んでいるからです。 その通りですね。認識はしていたのですが、対処方法が 分かりませんでした。

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.2

>WM_TIMERメッセージはウインドウが無いといけないことは 知っているのですが、 >上記の様な起動の仕方でも、やはり 駄目なのでしょうか? >CXXXDlg CXDlg; > >//100msタイマ起動 >CXDlg.StartTimeCount(100); <- ここでエラー CXDlg.Create()を呼ばないとウィンドウが存在しないんですけど。 外から呼びたいんでしたら、まずウィンドウなりモードレスのダイアログなり先に作ってください。 >また、ダイアログクラスとは別のクラスでタイマの 起動・停止が可能でしたら、その方法もご存じの方 教えて下さい。 SetTimerでコールバック関数を指定。 もしくはtimeSetEvent等のマルチメディアタイマーを使うとか。

  • keroro001
  • ベストアンサー率23% (71/304)
回答No.1

まったく自信なし。 ダイアログを生成してないからでは? Create後にやっても同じですかね? モーダルダイアログだと・・・うーん・・・

tamajun
質問者

お礼

ありがとうございました。マルチメディアタイマで 思っていた作業が出来ました。

関連するQ&A

  • TimerProc コールバック関数を利用する方法

    タイマを使いたくてメッセージマップでOnTimerを追加しましたが、 CWnd::SetTimerの第3パラメタに何を設定したらよいかわかりません。 lpfnTimer WM_TIMER メッセージを処理するためのアプリケーションが用意した、 TimerProc コールバック関数のアドレスを指定します。 このパラメータが NULL の場合は、WM_TIMER メッセージはアプリケーションの メッセージ キューに置かれ、CWnd オブジェクトによって処理されます。 とあり、NULL指定のサンプルはあるのですが、 「TimerProcコールバック関数のアドレスを指定する法」を試したいのです。 関数のアドレスというのが何をいっているのか理解できないのですが 試しに void CXXXCtrl::method1() { SetTimer(timerID, 10000, &OnTimer); } void CXXXCtrl::OnTimer(UINT nIDEvent) { // 処理 COleControl::OnTimer(nIDEvent); } としたところ error C2276: '&' : 仮想関数のアドレスを取ろうとしました。 のエラーになってしまいます。

  • SetTimerの行でアサートエラーが出てしまう

    MFCで、実行中 SetTimer(10, 1000, NULL); を記述しているコードでアサートエラーが出てしまいます。 クラスはCWnd継承クラスで作成し、afxwin.hをインクルード、 OnTimer関数を追加したのですが、この関数に飛びません。 MESSAGE_MAPにはON_WM_TIMER()の記述を確認しています。 何がいけないのか教えてください。お願いします。

  • 1秒で動くインターバルタイマ

    こんにちは。私のプログラミング能力が無いために困ってます。 timer_settimeを使って、インターバルが1sのタイマで100s後に終了させたいのですが、できません。環境はRedHatLinux7.1Jです。 下記のプログラムを実行するとtimer_createとtimer_settimerのところで、errno=38 "function not implemented"とでます。原因、どうしたらよいかわかりません。どのように修正したらうごくんでしょうか? 教えてください。 #include <signal.h> #include <time.h> #include <error.h> #include <errno.h> extern int errno; timer_t timerid; struct itimerspec one_minute = { {60, 0}, {0, 0} } ; struct sigaction sigact; struct sigevent sigev; int i,end; void handler() { i++; if (i == 100) end = 1; printf("きてます\n"); } int main() { i=0; end=0; sigact.sa_handler = handler; sigact.sa_flags = 0; if (sigaction(SIGUSR1, &sigact, (struct sigaction *)NULL)== -1) { printf("%d:%s\n",errno,strerror(errno)); exit(1); } sigev.sigev_notify = SIGEV_SIGNAL; sigev.sigev_signo = SIGUSR1; if (timer_create(CLOCK_REALTIME, &sigev, &timerid) == -1) { printf("%d:%s\n",errno,strerror(errno)); exit(1); } if (timer_settime(timerid, 0, &one_minute, (struct itimerspec == -1) { printf("%d:%s\n",errno,strerror(errno)); exit(1); } while (!end){ pause(); } if (timer_delete(timerid) == -1) { perror("timer_delete"); exit(1); } return 0; } 宜しくお願いします。

  • MFC Timerについて

    MFCのTimerの利用方法をいろいろ調べたのですが。 理解できずに困っています。 MFCのダイアログベースで作成し、ボタンを押したら Timer(1秒ごと)でエディットボックスに表示させるというものです。 ・ベースのウィンドウにボタンとエディットボックスを作成しました。 ・次に ボタンをダブルクリックし以下のように書きました。 void CtestDlg::OnBnClickedButton() {     int x=0; char buf[10000]; x++; sprintf(buf,"%d",x); (labelの変数名)_edit.SetWindowText(buf); } ・SetTimer(1, 1000, NULL);を用いて ボタンがクリックされたら1秒ごとにxの値をエディットボックスに表示させるようにしたいのですが。 OnTimer(UINT nIDEvent) Close()やKillTimer(1);をもちいらなければならないことはわかったのですが。 作業手順がわかりません。 詳しい 作業手順をおしえてください。 プログラム完成まで 教えていただけるととてもうれしいです。 プログラマーの方よろしくお願いします。

  • Visual Studioのタイマ処理を使って描画を行うプログラムを

    Visual Studioのタイマ処理を使って描画を行うプログラムを 作成したのですがうまくいきません. プログラムの開発環境はWindows XP SP2でVC++6.0 外部に接続したセンサからのデータを50Hzで サンプリングして そのデータを元に描画を行う予定なのですが計測時間が100秒を超えると 異常終了してしまいます. 原因がよく分かりません. どうしたらよいのでしょうか? void CMyDlg::OnSamplingStart() { i=0; // サンプリング用タイマ開始 //なぜか12にするとちょうど50Hzでサンプリングする SetTimer(1,12,NULL); // 0.02秒毎タイマ割り込み,50Hz } void CMyDlg::OnTimer(UINT nIDEvent) { /* ここで,センサからのデータをサンプリングし,いろいろな計算をする. */ CDC* pDC=m_pict.GetDC(); CRect myRECT; m_pict.GetClientRect(myRECT); pDC->FillSolidRect(myRECT, RGB(255,255,255)); CPen BlueBoldPen,*OldBlueBoldPen; BlueBoldPen.CreatePen(PS_SOLID,5,RGB(0,0,255)); OldBlueBoldPen=pDC->SelectObject(&BlueBoldPen); pDC->MoveTo((int)(X0/10),(int)(Y0/10)); pDC->LineTo((int)(L3_x[i]/10),(int)(L3_y[i]/10)); pDC->LineTo((int)(C7_x[i]/10),(int)(C7_y[i]/10)); // ペンを元に戻す pDC->SelectObject(OldBlueBoldPen); BlueBoldPen.DeleteObject(); m_time=(double)i/50; UpdateData(FALSE); i=i+1; CDialog::OnTimer(nIDEvent); } 計測終了はボタンを押して終了します. どうが具体的な解決策を教えてください.

  • [MFC] SetTimer関数の扱い方について

    [MFC] SetTimer関数の扱い方について MFCを扱い始めた初心者です。Settimerを用いて1秒間隔でOnTimer関数を呼び出そうと思い試行錯誤していたのですが、どのように記述してよいのかを教えてください。 実装したい機能は、ボタン1によりタイマを開始し、OnTimer関数を1秒間隔で呼び出し、ボタン2によりその動作を停止させたいのです。以下のコードを記述しますので、ご説明をよろしくお願いします。 NForm(){  btnの定義; btn2の定義; Picutureboxのpboxの定義; } int __stdcall WinMain(HINSTANCE,HINSTANCE,LPSTR,int) { Application::Run(new NForm()); return 0; } void NForm::btn_Click(Object *sender, System::EventArgs *e) { if(sender->Equals(btn)){ setTimer(1, 1000, NULL); } else if(sender->Equals(btn2)){ setTimer(1, 1000, NULL); } } void NForm::onTimer(UINT nIDEvent) { if(nIDEvent == 1){ HDC hDC; hDC = GetDC(NULL);//Full screen capture HDC hMemDC = CreateCompatibleDC(hDC); RECT r; SIZE size; size.cx = GetSystemMetrics(SM_CXSCREEN); size.cy = GetSystemMetrics(SM_CYSCREEN); HBITMAP hBitmap = CreateCompatibleBitmap(hDC, size.cx, size.cy); if (hBitmap) { HBITMAP hOld = (HBITMAP) SelectObject(hMemDC, hBitmap); BitBlt(hMemDC, 0, 0, size.cx, size.cy, hDC, 0, 0, SRCCOPY); SelectObject(hMemDC, hOld); DeleteDC(hMemDC); ReleaseDC(NULL, hDC); pbox->Image = Image::FromHbitmap(hBitmap); DeleteObject(hBitmap); } capture_cnt++; char name[80]; sprintf(name, "capture_%d.jpg", capture_cnt); pbox->Image->Save(name,Drawing::Imaging::ImageFormat::Jpeg); NForm::onTimer(1); } else if(nIDEvent == 0){ NForm::onTimer(0); } } 上記のコードにおいて、Ontimer関数を単体で動作させた場合はきちんと動作します。 どうか、よろしくお願いします。

  • VC++のシンボルブラウザについて

    VC++の勉強をはじめた初心者です。 時計を表示させる機能を学習しているのですが、 コールバック関数を使わず、WM_TIMERメッセージのみで 作成しています。 そのときにシンボルブラウザで タイマーIDを追加する意味がわかりません。 もともと、シンボルブラウザとは??? っというところから疑問なのですが、 その後、 SetTimer(○○○,1000,NULL); とし、時計用タイマーをスタートさせているのですが、 WM_TIMERの関数OnTimerで CTimeクラスのインスタンスを生成して、 GetCurrentTimeを使っています。 なんだか、わかりづらい説明で申し訳ないのですが、 時計用タイマーをスタートさせておいて、 なぜ、GetCurrentTimeで現在の時間を取得するのか 同じことを2回やっているような~ なにをやっているんだろう?? っと、混乱気味です。 すいません。長くなってしまいましたが、 うまく説明できないこの意味を理解してもらえたら 教えてください。(シンボルブラウザの意味も、、、)

  • DrawTextでの描画

    お世話になります。 現在開発中のアプリケーションにて行き詰ってしまった箇所が あったためご質問させていただきました。 Visual Studio2005にてダイアログベースのアプリケーションを作成しており、オリジナルのCStatic派生のクラスCSampleStaticクラスを作成します。 このCSampleStaticクラスはメインダイアログでのサブクラスにした際に PreSubclassWindow() ないでタイマーイベントを発生させます。タイマーイベントの内容は1秒ごとにタイマーを呼び、ランダムの値をそのCStaticの値に代入し、ダイアログ上に表示させる動作をします。 その際の処理のプログラムは以下のように作成しています CString str;//メンバー変数 //メインダイアログにてサブクラス化した際に呼ばれる CSampleStatic::PreSubclassWindow() { SetTimer(1,1000,NULL);//1秒毎に } CSampleStatic::OnTimer(UINT_PTR nIDEvent) { str.Format(_T("%d"),rand()%200); //1~199の乱数をstrに代入  Invalidate();           //OnPaint()を呼ぶ  CStatic::OnTimer(nIDEvent); } CSampleStatic::OnPaint() { CPaintDC dc(this); CFont MyFont; MyFont.CreateFont(-----); //フォント設定 CDC* myDC = GetDC(); CRect Myrect; GetClientRect(&Myrect); myDC->SelectObject(&Myrect); myDC->DrawText(str,-1,&Myrect,DT_CENTER); //strを表示 ReleaseDC(myDC); MyFont.DeleteObject(); } というプログラムを作成しているのですが、この方法でのダイアログへの文字の表示では、たとえば90が表示され、次に100が表示されるのであればいいのですが、100のあとに90が表示された時に100の上にそのまま90が表示されてしまい、うまく表示できません。 再描画のときに、上書きではなく、前回の数値を消去してから新たな数値を表示できればいいとは思うのですが、やり方がわからず、ご意見をいただければと思い質問させていただきました。 どうか宜しくお願いいたします。 開発環境は Windows CE 6.0 Visual Studio 2005 です。

  •    ダイアログのクラス化で仮想関数を用いて派生クラスにしているんです

       ダイアログのクラス化で仮想関数を用いて派生クラスにしているんですが・・・ ダイアログを基本クラスで静的プロシージャと派生クラスでオーバーライドしてプロシージャを使いたい のですが、どうしても自身のポインタが取得できません。 以下にソースを載せておきます。  class CBaseWnd  {  public:    // ポインタの設定    void SetPointer( HWND hWnd );    // ウィンドウプロシージャの呼び出し    static LRESULT CALLBACK CallProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );    // ウィンドウプロシージャの実装    virtual LRESULT MainProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );  }; [クラスの実装]  //===== ポインタの設定 =====//  void CBaseWnd::SetPointer( HWND hWnd )  {    SetWindowLong( hWnd, GWL_USERDATA, (LONG)this );  }  //===== ウィンドウプロシージャの呼び出し =====//  LRESULT CALLBACK CBaseWnd::CallProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )  {    //_プロパティリストからthisポインタを取得 //ここでポインタを取得することができないでいます。値が0です。 //先にSetWindowlongをやっても値が0のままです。    CBaseWnd* thisPtr = (CBaseWnd*)GetWindowLong( hWnd, GWL_USERDATA );    //_thisポインタが取得できなかった場合...    if( ! thisPtr )    {      //_ウィンドウの作成時の場合... //ここでアクセス違反というエラーが起きる      if( message == WM_INITDIALOG )        thisPtr = (CBaseWnd*)((LPCREATESTRUCT)lParam)->lpCreateParams;      //_thisポインタが取得できた場合...      if( thisPtr )      {        //_プロパティリストにオブジェクトハンドル(thisポインタ)を設定する        thisPtr->SetPointer( hWnd );      }    }    //_thisポインタが取得できた場合...    if( thisPtr )    {      LRESULT lResult = thisPtr->MainProc( hWnd, message, wParam, lParam );      return lResult;    }    return DefWindowProc( hWnd, message, wParam, lParam );  }  //===== ウィンドウプロシージャの実装(継承可能) =====//  // ここでの記述はデフォルトの処理  //  LRESULT CBaseWnd::MainProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )  {    switch( message )    {      //_ウィンドウが破棄された場合      case WM_DESTROY:        PostQuitMessage(0);        return 0;        //_デフォルトの場合      default:        return DefWindowProc( hWnd, message, wParam, lParam );    }  } WM_INITDIALOGでダイアログの初期化中にポインタを取得しようとしますが、アクセス違反が起こり失敗します。 どなたか分かる方がいらっしゃったらご指摘お願いします。

  • ローカル関数についてお願いします

    VC++プログラムです ボタン1,2は正常に動いたので割愛させていただきます この文をビルドしたらエラーがでました void CparaparaDlg::OnBnClickedButton3(){ { CPaintDC dc (this); CRect sikaku; GetClientRect (sikaku); int n; CBitmap gazou[2]; int CparaparaDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) { gazou[0].LoadBitmap(IDB_BITMAP1); gazou[1].LoadBitmap(IDB_BITMAP2); n = 1; SetTimer(1, 200, NULL); return 0; } void CparaparaDlg::OnTimer(UINT nIDEvent) { n = n + 1; if(n >= 3){ n = 1; } Invalidate(); if(n == 1){ OnBnClickedButton1(); } else if (n == 2){ OnBnClickedButton2(); } } } error C2601: 'CWnd::OnCreate' : ローカル関数の定義が正しくありません。 c:\Documents and Settings\mizuno\My Documents\Visual Studio error C2601: 'CWnd::OnTimer' : ローカル関数の定義が正しくありません。 というエラーが出ました・・・ どこをどう手直しすればよいのか教えていただける方、お願いします 関数についても教えていただけると幸いです

専門家に質問してみよう