• ベストアンサー

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

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

  • _jast
  • お礼率40% (15/37)

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

  • ベストアンサー
  • sha-girl
  • ベストアンサー率52% (430/816)
回答No.1

>アサートエラー assertはコードの中で(MFCを記述した)プログラマが意図的に止めているだけですから その箇所をみれば原因はわかると思います。 (SetTimerの部分にブレークポイントをはりステップインしていけばわかります。) 私の環境はVisual Studio 2005なので環境が異なるかもしれませんが SetTimer(MFC)の中でassertの記述のある箇所は下記の1箇所だけです。 ASSERT(::IsWindow(m_hWnd)); IsWindowはそのウィンドウが存在しているかどうかを 調べるAPIですが、m_hWndの指すウインドウが存在していない為assertが発生しています。 assertが出るときにm_hWndがNULL等の無効な値か、 既にm_hWndのウインドウが破棄された後か、 或いはまだウインドウが作成されていない可能性があります。

_jast
質問者

お礼

とてもわかりやすい回答ありがとうございました。 アサートの調べ方も教えていただきありがとうございます。

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

  • 超初心者の質問です。今、MFCでプログラムを作成しています。問題は、O

    超初心者の質問です。今、MFCでプログラムを作成しています。問題は、OnTimer関数が呼ばれないことです。 Cxxxsocket::test (){ (CMainFrame *)afxGetMainWnd()->SetTimer(1, 100, Null); } CxxxsocketはCsocketのクラスでSetTimerおよびOnTimerは使えません。この関数でSetTimerを呼び出したい。 afxGetMainWnd()はアプリケーションのアクティブなメイン ウィンドウへのポインタをさしており、恐らくCFrameWndのCMainFrame もしくは、CWinAPPのCxxxAppのポインタをさしていると思います。CFrameWndの場合、OnTimerが定義されているので、SetTimerのイベントは本OnTimerにて処理されると考えていたのですが、全くOnTimerがCallされません。 CMainFrameで利用しているOnTimerを使いたいのですが、SetTimerの呼び出し方法に問題あるのでしょうか?

  • SetTimer関数について。

    プログラム初心者です。質問させてください! 現在私はWin32APIを用いて、簡単なプログラムを作成しています。 そこで例えばイベントAが起きた10秒後にあるアクション(1)をさせたくて、 WM_イベントAの時: SetTimer(hWnd,ID_MYTIMER1, 10000, NULL); というようにプログラムを書きました。 そのSetTimer関数が実行されることより、 WM_TIMER:イベントが発生するので、WM_TIMER:イベントのところにあるアクション(1)をさせるプログラムを書きました。 しかし、イベントAが起きた100秒後には、あるアクション(1)とは違うあるアクション(2)をさせたいのですが、 この場合、WM_イベントAが起きたときに、 SetTimer(hWnd,ID_MYTIMER1, 10000, NULL); SetTimer(hWnd,ID_MYTIMER2, 100000, NULL); のようにプログラムをかいてしまうと、 二つともWM_TIMERイベントがおこるので、 あるアクション(1)も(2)も100秒後には実行されてしまいます。 100秒後にはアクション(1)はおこらず、アクション(2)だけおこる。 10秒後にはアクション(2)はおこらず、アクション(1)だけおこる。 このようにするには、どのようにすればいいのでしょうか? アドバイスよろしくお願いいたします。

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

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

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

    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 ダイアログベース です。よろしくお願いいたします。

  • スレッドでWM_TIMERを受け取れない

    スレッドの中でタイマー処理を行いたいのですが、WM_TIMERが受け取れません。 というか、メッセージマップ内でON_WM_TIMER()と記述すると、型が違うとエラーが出てしまいます。 どなたか、スレッド内でタイマー処理を行うすべを教えて下さい。よろしくお願いします。 CWinThreadを派生したクラス内での処理です。

  • Timerの使用方法

    AppWizawdを使用してプログラムを作成していますが, Timerの使用法を説明した本などがありましたら教えてください。 (SetTimerとOnTimerが関係することは分かりましたが,どこに記述するのか,引数はどのようにするのかがよくわかりません)

  • ビットマップ表示とSetTimer関数を同居させる方法

    ビットマップ表示とSetTimer関数を同居させる方法 現在、vc++2005を使用して、簡易的なGUIアプリケーションを作成しようとしているのですが、自分では解決ができない問題が発生してしまったので、質問させていただきます。 それはビットマップ表示とSetTimer関数を同居させる方法についてです。 ビットマップを読み込んで表示させる機能を追加してから、SetTimer関数が反応しなくなってしまい困っています。 ちなみにビットマップ表示の機能を追加する前まではSetTimer関数が正常に機能していました。 ウィンドウのハンドルhWndが何か関係しているのかと思ったのですが、解決方法がわからず・・・・・・ ご存知の方がいらっしゃましたら御教授いただけると幸いです。 ↓ ソースの一部です case WM_CREATE: //ビットマップファイル読み込み + 表示の準備 static HBITMAP hbitmap,prebitmap; static HDC hDC, hcomDC;      hbitmap = (HBITMAP)LoadImage(NULL,_T("kouen.bmp"),IMAGE_BITMAP,0,0, LR_LOADFROMFILE); if( hbitmap == NULL ) { MessageBox(hWnd, _T("ビットマップのロードに失敗しました"), _T("エラー"),MB_OK | MB_ICONWARNING); return 0; } hDC =GetDC(hWnd); hcomDC =CreateCompatibleDC(hDC); prebitmap= (HBITMAP)SelectObject(hcomDC,hbitmap);            (中略) break;                     case WM_LBUTTONDOWN: //2連続のシングルクリック防止 EnableWindow(hWnd,FALSE); SetTimer(hWnd, ID_TIMER1, 500, NULL); ← これが機能していない          (中略) break; case WM_PAINT: BitBlt( hDC, 0, 0, 1024, 690, hcomDC, 0, 0, SRCCOPY ); break; case WM_TIMER://機能しなくなってしまった部分 if(wParam==ID_TIMER1){ KillTimer(hWnd,ID_TIMER1); EnableWindow(hWnd,TRUE); }

  • [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++プログラムです ボタン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' : ローカル関数の定義が正しくありません。 というエラーが出ました・・・ どこをどう手直しすればよいのか教えていただける方、お願いします 関数についても教えていただけると幸いです

専門家に質問してみよう