本人最近在看侯杰的<<深入浅出MFC>>,有几点不明白,想向大家请教一下:
他在书中举得第一个例子-HELLO中,重写了OnIdle函数,而参数为LONG LCOUNT, 在文中他只简单提了一下,说LCOUNT是系统传进来的值,我就不明白了-像定义函数的参数一样的形式,怎么看都是一个自己写的函数,怎么能从操作系统传进来呢,也不是特殊字,这是怎么回事?
整个为:
BOOL CMyWinApp::OnIdle(LONG lCount)
{
   CMyFrameWnd* pWnd = (CMyFrameWnd*)m_pMainWnd;
   pWnd->IdleTimeHandler(lCount);
   return TRUE;
}
CMyFrameWnd* pWnd = (CMyFrameWnd*)m_pMainWnd;这句我也不明白,pWnd是为了得了主窗口的指针,怎么能够(CMyFrameWnd*)m_pMainWnd(在成员变量前面强制转换???请大家详细帮我分析一下,谢谢

解决方案 »

  1.   

    侯杰 是模仿MFC 写的实验程序。
    真正的MFC 是通过虚函数 来调用OnIdle的。你可以理解成系统调用CWinApp::OnIdle但由于这个函数使虚函数,所以执行的是你写的CMyWinApp::OnIdle(LONG lCount)。
      

  2.   

    嗯,这个我明白的,我的意思是说为什么LONG lCout可以是系统传进来的,本来他这样写应该理解为函数的形参的.
    而且我也查不到由哪里调进来的?
      

  3.   

    这个参数应该是内核或者监测后台程序传给应用程序的进程的,系统内核在不断的检测应用程序运行状况,在空闲时会将此参数传过去。CWinApp封装了应用程序进程的功能。故它有OnIdle。
    估计内核在应用程序线程创建初会分配一个定时器。所以有这个count。
    这些是我的猜测,因为我没有深入研究过。windows毕竟封装的太厉害。
    同样的消息也不就是这样的么?比如按键的键值就由操作系统包装后放到消息中,让窗口函数取得来处理的。
      

  4.   

    CMyFrameWnd* pWnd = (CMyFrameWnd*)m_pMainWnd;这句我也不明白,pWnd是为了得了主窗口的指针,怎么能够(CMyFrameWnd*)m_pMainWnd(在成员变量前面强制转换??? 
    ==============================
    为什么不能强制转化呢?m_pMainWnd本来就是CMyFrameWnd指针,转化当然是可以的.
      

  5.   

    谢谢3楼与4楼的回答,对m_pMainwnd我理解是它是CWinThread的成员变量是指向主窗口的指针,那么前面的强制转换不是没有意义,因为它本身就是指向CMyFrameWnd的啊!
    4楼的我不太明白,是不是LONG LCout在前面只是申明与定义,在pWnd->IdleTimeHandler(lCount)中的lCount才将系统的确lCount传进来呢?
      

  6.   

    我在演示程序上面将lCount改成lCount1还是可以编译与运行,运行情况也是正确的,那就表明lCount不是系统已经定义的变量了?pWnd->IdleTimeHandler(lCount)中的lCount也就不是实参了?请大家帮忙分析一下,特别是看过侯杰的<<深入浅出MFC>>的朋友
      

  7.   


    有意义,
    CWnd* m_pMainWnd;       // main window (usually same AfxGetApp()->m_pMainWnd)
    这是CWinThread的成员变量定义。现在我们要调用IdleTimeHandler函数。必须将指针从CWnd*改成CMyFrameWnd*指针。
      

  8.   

    lCount是函数参数,你想改成什么名字都行,你要看实际调用的地方传的什么
    也就是那里调用CMyWinApp::OnIdle()
      

  9.   

    这个onidle在pumpmessage中调用的!其实这本书并不适合初学的!至少要懂了一定的mfc再来看!那看这本书真的很舒服!
      

  10.   

    好的,多谢7楼的回答,明白了.8楼的回答不确切,我知道是调用CMyWinApp::OnIdle(),但是这个调用过程我只看到形参,那lCount的值是从哪里得到的呢?因为运行后程序是显示一个不断变化的数值(调用IDLE的次数)是我提问时表达不清,能详细分析一下吗?
      

  11.   


    // main running routine until thread exits
    int CWinThread::Run()
    {
    ASSERT_VALID(this); // for tracking the idle time state
    BOOL bIdle = TRUE;
    LONG lIdleCount = 0; // acquire and dispatch messages until a WM_QUIT message is received.
    for (;;)
    {
    // phase1: check to see if we can do idle work
    while (bIdle &&
    !::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE))
    {
    // call OnIdle while in bIdle state
    if (!OnIdle(lIdleCount++))
    bIdle = FALSE; // assume "no idle" state
    } // phase2: pump messages while available
    do
    {
    // pump message, but quit on WM_QUIT
    if (!PumpMessage())
    return ExitInstance(); // reset "no idle" state after pumping "normal" message
    if (IsIdleMessage(&m_msgCur))
    {
    bIdle = TRUE;
    lIdleCount = 0;
    } } while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));
    } ASSERT(FALSE);  // not reachable
    }看看这段代码,lz应该就会明白了吧。
      

  12.   

    呵呵,OnIle的确是在pumpmessage中调用的,但是在这个例子中,侯杰不是把它重写了吗?
    那个在CWinThread::Run()中应该调用它写的这个OnIdle(),是这样吗?
      

  13.   

    非常感谢xylicon!!!我现在总结一下我看书时遇到的疑惑与解答:1.我误解了类指针,虽然都是指向MainWnd,但是m_pMainWnd是指CMyWndApp的指针,而要调用CMyFrameWnd类的成员函数,则一定要是CMyFrameWnd类的指针;2.OnIdle()是VIRTUAL的,侯杰重写了之后只是在程序
      for (;;)
        {
            // phase1: check to see if we can do idle work
            while (bIdle &&
                !::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE))
            {
                // call OnIdle while in bIdle state
                if (!OnIdle(lIdleCount++))
                    bIdle = FALSE; // assume "no idle" state
            }
    中调用了侯杰写的OnIdle(LONG lCount),lCount的确是形参,在if (!OnIdle(lIdleCount++))中程序或者说系统把lIdleCount++传进去,而lIdleCount这个是实参(应该是系统中定义的),把lIdleCount进行操作,得到IDLE的次数.