none
削除 RRS feed

回答

  • TimerProc を使わず SetTimer の lpTimerFunc に NULL を渡せば、OnTimer で処理できるんじゃなかったでしたっけ。
    2008年10月22日 9:03
  • これは、TimerProc()がフレームのメンバでないためにおこり、また、

    これをメンバ関数にするとSetTimer()に渡すことができません。

    これは、メンバ関数は唯一のインスタンスで無いからです。

     

    まぁ、コールバックをNULLにしてOnTimer()の方が簡単ですけど、

    どうしてもやりたい場合、次のような方法があります。

     1.TimerProc()に事前にフレームのインスタンス(this)を教えておく

     2.TimerProc()をstaticにして、唯一のインスタンスとする。

     3.フレームの実体をTimerProc()から参照できる場所に置く。

     

    ・・・などです。1.はイレギュラーな方法で教えるしかないので、

    ソースを見た人からの非難を覚悟しなければならないでしょう。

    2.では、フレームのstaticなメンバしか参照できなくなります。はっきり言って使えません。

    3.では、Doc View ルールから外れてしまいそうですねぇ。

     

    で・・・自分のお気に入りは次のような方法です。

    Code Snippet

    void CALLBACK EXPORT TimerProc(
       HWND  hWnd,      // handle of CWnd that called SetTimer
       UINT  nMsg,      // WM_TIMER
       UINT_PTR nIDEvent,  // timer identification
       DWORD dwTime    // system time
    )
    {
       CMainFrame * main_frm = ( CMainFrame *)::GetWindowLongPtr( hWnd, GWLP_USERDATA);
       main_frm->Timer_CallBac();// フレームオブジェクトのタイマーコールバックを呼ぶ
    }
    class CMainFrame : public CFrameWndEx

    {

       // タイマーコールバック

       public: void Timer_CallBac()

        {

            // タイマーですよ。

        }

       void OnButton1()

       {

         ::SetWindowLongPtr( m_hWnd, GWLP_USERDATA, LPARAM( this));
         SetTimer( 1, 100, TimerProc);

       }

    };

     

    なんで、これでうまく行っちゃうのかは、自分で考えましょう(^^Wink

     

    2008年10月22日 9:41
  • MainFrameに限定された状況になりますが、MFCならCWinApp派生クラスのm_pMainWndあたりに入っているかもしれません。

    もっとも、ViewやDialog等で独自にやっているパターンだと、辿れないかもしれませんが。

     

    ただ、正攻法は既に言われているように最後の引数にNULLを置いて、OnTimerで処理することでしょう。

    2008年10月22日 15:26
    モデレータ
  • ご回答頂いた皆様、有難う御座います。

    アドバイス頂いた内容で、解決できました。

    本当に有難う御座います。

     

     

    2008年10月23日 0:19

すべての返信

  • TimerProc を使わず SetTimer の lpTimerFunc に NULL を渡せば、OnTimer で処理できるんじゃなかったでしたっけ。
    2008年10月22日 9:03
  • これは、TimerProc()がフレームのメンバでないためにおこり、また、

    これをメンバ関数にするとSetTimer()に渡すことができません。

    これは、メンバ関数は唯一のインスタンスで無いからです。

     

    まぁ、コールバックをNULLにしてOnTimer()の方が簡単ですけど、

    どうしてもやりたい場合、次のような方法があります。

     1.TimerProc()に事前にフレームのインスタンス(this)を教えておく

     2.TimerProc()をstaticにして、唯一のインスタンスとする。

     3.フレームの実体をTimerProc()から参照できる場所に置く。

     

    ・・・などです。1.はイレギュラーな方法で教えるしかないので、

    ソースを見た人からの非難を覚悟しなければならないでしょう。

    2.では、フレームのstaticなメンバしか参照できなくなります。はっきり言って使えません。

    3.では、Doc View ルールから外れてしまいそうですねぇ。

     

    で・・・自分のお気に入りは次のような方法です。

    Code Snippet

    void CALLBACK EXPORT TimerProc(
       HWND  hWnd,      // handle of CWnd that called SetTimer
       UINT  nMsg,      // WM_TIMER
       UINT_PTR nIDEvent,  // timer identification
       DWORD dwTime    // system time
    )
    {
       CMainFrame * main_frm = ( CMainFrame *)::GetWindowLongPtr( hWnd, GWLP_USERDATA);
       main_frm->Timer_CallBac();// フレームオブジェクトのタイマーコールバックを呼ぶ
    }
    class CMainFrame : public CFrameWndEx

    {

       // タイマーコールバック

       public: void Timer_CallBac()

        {

            // タイマーですよ。

        }

       void OnButton1()

       {

         ::SetWindowLongPtr( m_hWnd, GWLP_USERDATA, LPARAM( this));
         SetTimer( 1, 100, TimerProc);

       }

    };

     

    なんで、これでうまく行っちゃうのかは、自分で考えましょう(^^Wink

     

    2008年10月22日 9:41
  • MainFrameに限定された状況になりますが、MFCならCWinApp派生クラスのm_pMainWndあたりに入っているかもしれません。

    もっとも、ViewやDialog等で独自にやっているパターンだと、辿れないかもしれませんが。

     

    ただ、正攻法は既に言われているように最後の引数にNULLを置いて、OnTimerで処理することでしょう。

    2008年10月22日 15:26
    モデレータ
  • ご回答頂いた皆様、有難う御座います。

    アドバイス頂いた内容で、解決できました。

    本当に有難う御座います。

     

     

    2008年10月23日 0:19