OnTimerの使い方

このQ&Aのポイント
  • OnTimerを使用してメッセージボックスを表示する方法と、メッセージボックスが閉じない問題について
  • OnTimerを使用して3秒後にメッセージボックスを表示する方法と、メッセージボックスが閉じない問題の解決策について
  • Win98とVC++6.0でOnTimerを使ってメッセージボックスを表示し、メッセージボックスが閉じない問題が発生する原因と解決方法
回答を見る
  • ベストアンサー

OnTimerの使い方

<環境> WIN98 VC++6.0 MFC  こんな感じで3秒経過するとメッセージボックスを表示していますが、 メッセージボックスのOKボタンを何度も押さないとメッセージボックスが 閉じない時が有ります。 (どうやらメッセージボックスが何個も作られている) どうしてなのでしょうか? BOOL CAbcDlg::OnInitDialog() { // TODO: 特別な初期化を行う時はこの場所に追加してください。 SetTimer(1, 1000, NULL); m_cnttime = 0; 略 void CAbcDlg::OnTimer(UINT nIDEvent) { m_cnttime++; if ( m_cnttime >= 3 ) { AfxMessageBox(""); KillTimer(nIDEvent); } CDialog::OnTimer(nIDEvent); }

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

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

>(どうやらメッセージボックスが何個も作られている) そのとおりです。 >どうしてなのでしょうか? メッセージボックスが表示されていてもWM_TIMERメッセージは送られてくるから。

VitaminBB
質問者

お礼

回答ありがとう御座います。 こうすれば良いのですね。 KillTimer(nIDEvent); AfxMessageBox("");

その他の回答 (1)

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

>こうすれば良いのですね。 > >KillTimer(nIDEvent); >AfxMessageBox(""); そうです。 タイマーを使ったダブルクリックとシングルクリックの使い分けのときと一緒ですね。

VitaminBB
質問者

お礼

回答ありがとう御座います。 あの時はここまで意識していませんでした。

関連するQ&A

  • VC++のOnTimer()について

    超初歩的な話でお恥ずかしいのですが、 VC++6.0 MFC でアプリを作っていて、 //////////////// xxx::OnInitialUpdate(...) { m_nIDEntry = SetTimer(m_nIDEvent); } /////////////// xxx:OnTimer(UINT nIDEvent) { if (nIDEvent == ?) { なんかの処理 } } /////////////// xxx:OnDestroy(...) { KillTimer(?); } /////////////// このようなコードの際に、if (nIDEvent == ?) には SetTimer() の値を入れますが、? は 上で言うところの m_nIDEvent それとも m_nIDEntry を入れます? KillTimer() の ? も同様にです。 MSDN ライブラリを見ると ? は m_nIDEvent が入るように 読み取れます(今までもずーとそのようにしています)。 これが正しければ SetTimer() の戻値って何の意味が 有るのかが不明です。

  • OnTimer()時にクリックされたことを知るには?

    環境 WIN98 VC++6.0 MFC にて OnTimer()時にクリックされたことを知るにはどうすれば良いですか? void CAbcdView::OnTimer(UINT nIDEvent) { KillTimer( 1 ); if ( どのように記述すれば良いですか?) //左クリックされたことを知りたい MessageBox( "クリックされました。", "左", MB_OK ); CView::OnTimer(nIDEvent); }

  • if文の判定について

    <環境> WIN98 VC++6.0 MFC  ダイアログベースにて 以下コードにて、タイマーによる変数nの変化に伴い絵1と絵2が切り替わっています。 int n; void CxxxDlg::OnPaint() { 略 m_p9[0].LoadBitmap(IDB_BITMAP1); m_p9[1].LoadBitmap(IDB_BITMAP2); tempDC9.SelectObject(&m_p9[n]); 略 } void CxxxDlg::OnTimer(UINT nIDEvent) { n=n+1; if(n>=2){ n=0; } Invalidate();   CDialog::OnTimer(nIDEvent); } ところがコードの一部を以下のように変更すると、 if文で正しく判定できなくなります。 どうしてなのでしょうか? if (n=0){ m_p9[0].LoadBitmap(IDB_BITMAP1); } m_p9[1].LoadBitmap(IDB_BITMAP2);

  • 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: '&' : 仮想関数のアドレスを取ろうとしました。 のエラーになってしまいます。

  • 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);をもちいらなければならないことはわかったのですが。 作業手順がわかりません。 詳しい 作業手順をおしえてください。 プログラム完成まで 教えていただけるととてもうれしいです。 プログラマーの方よろしくお願いします。

  • リッチエディットのUPDATEメッセージ受け取り方

    ダイアログにリッチエディットボックスを貼り付けています。 文字が入力されるたびにUPDATEメッセージを受け取りたいのですが。 下記注釈の意味がわからず困っています。OnInitDialog()に何かを書くということは判るのですが。ヘルプでも見つけることが出来ませんでした。 どうかこの私でも判るよう教えてください。よろしくお願いいたします。m(_ _)m void CCtypeDlg::OnUpdateRichedit() { // TODO: これが RICHEDIT コントロールの場合、コントロールは、lParam マスク // 内での論理和の ENM_UPDATE フラグ付きで EM_SETEVENTMASK // メッセージをコントロールへ送るために CDialog::OnInitDialog() 関数をオーバー // ライドしない限りこの通知を送りません。 // TODO: この位置にコントロール通知ハンドラ・・・

  • スレッドの再開

    MFCでアプリケーションを開発しています。 メインのプログラムを走らせながら計算処理を行いたくて、本やネット等のサンプルプログラムを見ながら別スレッドを生成してみました。 OnInitDialog()でイベントとスレッドを生成し、スタートボタンのクリック押下をトリガーとして、計算処理(Run())を呼んでいます。 タイマー開始後は一定時間ごと(サンプルでは500msec)にスレッドを再開して計算処理を実行し、計算処理完了後はスレッドを一時停止状態にしたいと思っています。 (アプリケーション起動時にサスペンドモードで起動したスレッドをボタン押下でResumeThread(再開)し、あとはタイマーでイベントシグナルをセットして制御するつもりでした。) ですが、下記のコードで走らせると、初回のみ計算処理が呼び出され、その後はスレッドが再開されません(ThreadProc()がコールされない)。 理解不足から何か考え違いをしているのだと思うのですが、どこをなおすべきかわからず行き詰まっています。 どなたかご指摘頂けたらと思います。よろしくお願い致します。 ※実際に記述したコードの抜粋になりますので計算やリソースの解放処理等は省略しています。 OS:Win10 開発環境:VisualStudio2015 C++ ---------------------------------------------------------------- BOOL CMFCApplication1Dlg::OnInitDialog() { CDialog::OnInitDialog(); 中略 … m_hEvent = CreateEventA(NULL, FALSE, FALSE, "EVENT"); m_hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ThreadProc, (LPVOID)this, CREATE_SUSPENDED, NULL); return TRUE; } void CMFCApplication1Dlg::OnTimer(UINT_PTR nIDEvent) { switch(nIDEvent) { case 1: { BOOL blRet = SetEvent(m_hEvent); } break; default: { } break; } CDialog::OnTimer(nIDEvent); } UINT CMFCApplication1Dlg::ThreadProc(LPVOID pParam) { CMFCApplication1Dlg* pDlg = dynamic_cast<CMFCApplication1Dlg*>(reinterpret_cast<CWnd*>(pParam)); if(pDlg) { pDlg->ThreadProcCall(); } return 0; } // LineProfileスレッド処理呼び出し. void CMFCApplication1Dlg::ThreadProcCall(void) { // イベントオブジェクト取得. HANDLE h = OpenEventA(EVENT_ALL_ACCESS, FALSE, "EVENT"); // シグナル状態になるまで待機. WaitForSingleObject(h, INFINITE); // 非シグナル状態に. ResetEvent(h); // 計算処理呼び出し. Run(); this->SendMessage(WM_USER_COMPLETE_PROC); } void CMFCApplication1Dlg::Run(void) { // 計算処理. } // LineProfileスレッド終了後処理. afx_msg LRESULT CMFCApplication1Dlg::OnCompleteProc(WPARAM wParam, LPARAM lParam) { // スレッド停止. DWORD dwRet = SuspendThread(m_hThread); return 0; } void CMFCApplication1Dlg::OnBnClickedBtnStart() { // スレッド再開. DWORD dwRet = ResumeThread(m_hThread); // 計算処理呼び出し用タイマー設定. m_nUpdatePaintTimer = SetTimer(1, 500, NULL); }

  • visual C++ 2005 でのイベントの作成

    visual C++ 2005 でのイベントの作成で困っています。 ダイアログ ベースのプログラミング http://oshiete1.goo.ne.jp/oshiete_new.php3 上記のサイトをはじめから実行していったのですが、「イベントハンドラ の追加」の部分で void CButtonDlg::OnBnClickedButton1() { // TODO: この位置にコントロール通知ハンドラ ... } の// TODO: この位置にコントロール通知ハンドラ ...の部分にサイトの 記述に有るような AfxMessageBox("第 1 のボタンを押しました。"); という記述をしたのですがこれをビルドするとエラーになります。 エラーメッセージは c:\documents and settings\asakawa\my documents\visual studio 2005\projects\ren\ren\rendlg.cpp(160) : error C2665: 'AfxMessageBox' : 2 オーバーロードのどれも、すべての引数の型を変換できませんでした c:\program files\microsoft visual studio 8\vc\atlmfc \include\afxwin.h(5025): 'int AfxMessageBox(LPCTSTR,UINT,UINT)' の 可能性があります。 c:\program files\microsoft visual studio 8\vc\atlmfc \include\afxwin.h(5027): または 'int AfxMessageBox(UINT,UINT,UINT)' 引数リスト '(const char [17])' を一致させようとしているとき と出ます。 何が原因でしょうか? ヒントでも良いんですが…

  • Warning: initial dialog data is out of range. と言う警告について

    VC++ 6.0 MFC ダイアログベースです。 メインダイアログで、あるボタンをクリックすると、別のダイアログが開くと言う物を作っているのですが、 「F5キー」でデバックし、メインダイアログから別のダイアログを開くと、 Warning: initial dialog data is out of range. と言うメッセージがデバックのメッセージウィンドウにでていました。 これはどういった警告なのでしょうか?よろしくお願い致します。 また、どこを見る必要があるのでしょうか? (1)警告メッセージが出るのは selectingdlg->DoModal(); で出ていました。 (2)OnInitDialog()の中身を全部削除しても、(下記状態)同様の警告が出ました。 (3)最初のころはこのような警告はなく、最近になって見つけたのですが、何を追記した時かが自分でももお解らなくなってしまいました・・・。 よろしくお願い致します。 void CMainDlg::Onbutton1() {   selectingdlg->DoModal(); } BOOL CChildDlg::OnInitDialog() {   CDialog::OnInitDialog();   // TODO: この位置に初期化の補足処理を追加してください   return TRUE; // コントロールにフォーカスを設定しないとき、戻り値は TRUE となります          // 例外: OCX プロパティ ページの戻り値は FALSE となります }

  • 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); } 計測終了はボタンを押して終了します. どうが具体的な解決策を教えてください.

専門家に質問してみよう