首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

3.2.3  消息循环

至此,注册窗口类、创建窗口、显示和更新窗口的工作都已完成,就该进入消息循环了。CWinThread类的Run函数就是完成消息循环这一任务的,该函数是在AfxWinMain函数中调用的,调用形式如下(位于例3-7所示AfxWinMain函数实现代码的符号④处)所示

pThread->Run();

CWinThread类的Run函数的定义位于THRDCORE.CPP文件中,代码如例3-16所示。

3-16

// 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

}

该函数的主要结构是一个for循环,该循环在接收到一个WM_QUIT消息时退出。在此循环中调用了一个PumpMessage函数,该函数的部分定义代码如例3-17所示。

3-17

BOOL CWinThread::PumpMessage()

{

    ASSERT_VALID(this);

 

    if (!::GetMessage(&m_msgCur, NULL, NULL, NULL))

    {

……

        return FALSE;

    }

……

    // process this message

    if (m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage(&m_ msgCur))

    {

        ::TranslateMessage(&m_msgCur);

        ::DispatchMessage(&m_msgCur);

    }

    return TRUE;

}

可以发现,这与前面第2章中讲述的SDK编程的消息处理代码是一致的。