1

VS2010 で MFC ダイアログ ベースのアプリを作成し、3 秒ごとに画像コントローラーを更新するタイマーを追加したいと考えました。しかし、OnTimer メソッドは機能しませんでした。

Class Wizard を使用して WM_TIMER をメッセージ キューに追加したところ、次のようになりました。

BEGIN_MESSAGE_MAP(CxxxxDlg, CDialogEx)
    ON_WM_PAINT()
    ON_BN_CLICKED(IDOK, &CxxxxDlg::OnBnClickedOK)
    ON_WM_TIMER()
END_MESSAGE_MAP()

xxxxDlg.cpp では、OnInitDialog に SetTimer メソッドを配置しました。

BOOL CxxxxDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
    SetIcon(m_hIcon, TRUE);
    SetIcon(m_hIcon, TRUE);

    _imageCounter = 1;
    _isMale = 3;
    _testNum = 0;

    SetTimer(123, 2000, NULL);

    bFullScreen = false;
    OnFullShow();
    updateImages();
    UpdateData();

    return TRUE;
}

OnTimer メソッドは xxxxdlv.h で宣言されています。

public:
    afx_msg void OnTimer(UINT_PTR nIDEvent);

アプリを実行すると、SetTimer は 123 を返しました。しかし、プログラムは OnTimer メソッドの 1 行目に設定したブレークポイントに到達しませんでした!

次に、タイマーをテストするためだけに別のhello worldプロジェクトを作成しました。まったく同じ方法でタイマーを設定しましたが、うまくいきました。

だから私は OnFullShow() メソッドが問題かもしれないと思った。このメソッドは、ウィンドウを全画面モードに変更するために使用されました。この行にコメントしますが、それでも OnTimer は機能しませんでした。

ここで質問を確認しました。しかし、それは役に立ちません。

誰が問題がどこから来たのか知っていますか? ありがとう!

PS。メモリリークの警告をいくつか受け取りました。これは問題でしたか?

4

1 に答える 1

1

@IInspectable に感謝します。ここで技術サポートを見つけました。原因を完全に説明し、1 つの解決策を示します。

// Rewrite PreTranslateMessage method
BOOL CMyApp::PreTranslateMessage( MSG *pMsg )
{
   // If this is a timer callback message let it pass on through to the
   // DispatchMessage call.
   if( (pMsg->message==WM_TIMER) && (pMsg->hwnd==NULL) )
       return FALSE;
   ...
   // The rest of your PreTranslateMessage goes here.
   ...

   return CWinApp::PreTranslateMessage(pMsg);
}

この解決策は私の問題を解決しませんが、ヒントを与えてくれます。DispatchMessage 呼び出しにパススルーPreTranslateMessageできるようにメソッドを書き直す必要があります。ただし、たとえば、他のメッセージを処理するために を使用している場合、上記の解決策は機能しない可能性があります優先順位の問題のようです。最後に、代わりに次を使用して解決します。WM_TIMERPreTranslateMessageWM_KEYDOWNswitchif

// Rewrite PreTranslateMessage method
BOOL CMyApp::PreTranslateMessage( MSG *pMsg )
{
   // If this is a timer callback message let it pass on through to the
   // DispatchMessage call.
   switch(pMsg->message)
   {
    case WM_KEYDOWN: // your codes
    case WM_TIMER: return false;
    ...
   }
   ...
   // The rest of your PreTranslateMessage goes here.
   ...

   return CWinApp::PreTranslateMessage(pMsg);
}

これが同様の問題を抱えている人に役立つことを願っています。

PS。pMsg->hwnd==NULLで削除されswitch、安全かどうかわかりません。

于 2013-10-07T16:22:04.457 に答える