• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            蝸牛的家
            男兒當(dāng)自強(qiáng)
            posts - 48,  comments - 21,  trackbacks - 0
            int CWnd::RunModalLoop(DWORD dwFlags)
            {
             ASSERT(::IsWindow(m_hWnd)); 
            // window must be created
             ASSERT(!(m_nFlags & WF_MODALLOOP)); // window must not already be in modal state

             
            // for tracking the idle time state
             BOOL bIdle = TRUE;
             LONG lIdleCount 
            = 0;
             BOOL bShowIdle 
            = (dwFlags & MLF_SHOWONIDLE) && !(GetStyle() & WS_VISIBLE);
             HWND hWndParent 
            = ::GetParent(m_hWnd);
             m_nFlags 
            |= (WF_MODALLOOP|WF_CONTINUEMODAL);
             MSG
            * pMsg = &AfxGetThread()->m_msgCur;

             
            // acquire and dispatch messages until the modal state is done
             for (;;)
             
            {
              ASSERT(ContinueModal());

              
            // phase1: check to see if we can do idle work
              while (bIdle &&
               
            !::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE))
              
            {
               ASSERT(ContinueModal());

               
            // show the dialog when the message queue goes idle
               if (bShowIdle)
               
            {
                ShowWindow(SW_SHOWNORMAL);
                UpdateWindow();
                bShowIdle 
            = FALSE;
               }


               
            // call OnIdle while in bIdle state
               if (!(dwFlags & MLF_NOIDLEMSG) && hWndParent != NULL && lIdleCount == 0)
               
            {
                
            // send WM_ENTERIDLE to the parent
                ::SendMessage(hWndParent, WM_ENTERIDLE, MSGF_DIALOGBOX, (LPARAM)m_hWnd);
               }

               
            if ((dwFlags & MLF_NOKICKIDLE) ||
                
            !SendMessage(WM_KICKIDLE, MSGF_DIALOGBOX, lIdleCount++))
               
            {
                
            // stop idle processing next time
                bIdle = FALSE;
               }

              }


              
            // phase2: pump messages while available
              do
              
            {
               ASSERT(ContinueModal());

               
            // pump message, but quit on WM_QUIT
               
            //PumpMessage(消息泵)的實(shí)現(xiàn)和上面講的差不多。都是派送消息到窗口。
               if (!AfxGetThread()->PumpMessage())
               
            {
                AfxPostQuitMessage(
            0);
                
            return -1;
               }


               
            // show the window when certain special messages rec'd
               if (bShowIdle &&
                (pMsg
            ->message == 0x118 || pMsg->message == WM_SYSKEYDOWN))
               
            {
                ShowWindow(SW_SHOWNORMAL);
               消息分為隊(duì)列消息(進(jìn)入線程的消息隊(duì)列)和非隊(duì)列消息(不進(jìn)入線程的消息隊(duì)列)。對于隊(duì)列消息,最常見的是鼠標(biāo)和鍵盤觸發(fā)的消息,例如 WM_MOUSERMOVE,WM_CHAR等消息;還有例如:WM_PAINT、WM_TIMER和WM_QUIT。當(dāng)鼠標(biāo)、鍵盤事件被觸發(fā)后,相應(yīng)的鼠標(biāo)或鍵盤驅(qū)動(dòng)程序就會(huì)把這些事件轉(zhuǎn)換成相應(yīng)的消息,然后輸送到系統(tǒng)消息隊(duì)列,由Windows系統(tǒng)負(fù)責(zé)把消息加入到相應(yīng)線程的消息隊(duì)列中,于是就有了消息循環(huán)(從消息隊(duì)列中讀取并派送消息)。還有一種是非隊(duì)列消息,他繞過系統(tǒng)隊(duì)列和消息隊(duì)列,直接將消息發(fā)送到窗口過程。例如,當(dāng)用戶激活一個(gè)窗口系統(tǒng)發(fā)送 WM_ACTIVATE, WM_SETFOCUS, and WM_SETCURSOR。創(chuàng)建窗口時(shí)發(fā)送WM_CREATE消息。
            BOOL CWinThread::PumpMessage()
            {
             ASSERT_VALID(
            this);
             
             
            //如果是WM_QUIT就退出函數(shù)(return FALSE),這將導(dǎo)致程序結(jié)束.
             if (!::GetMessage(&m_msgCur, NULL, NULL, NULL)) {
            #ifdef _DEBUG
              
            if (afxTraceFlags & traceAppMsg)
               TRACE0(
            "CWinThread::PumpMessage - Received WM_QUIT.\n");
              m_nDisablePumpCount
            ++// application must die
               
            // Note: prevents calling message loop things in 'ExitInstance'
               
            // will never be decremented
            #endif
              
            return FALSE;
             }


            #ifdef _DEBUG
             
            if (m_nDisablePumpCount != 0)
             
            {
              TRACE0(
            "Error: CWinThread::PumpMessage called when not permitted.\n");
              ASSERT(FALSE);
             }

            #endif

            #ifdef _DEBUG
             
            if (afxTraceFlags & traceAppMsg)
              _AfxTraceMsg(_T(
            "PumpMessage"), &m_msgCur);
            #endif

             
            // process this message

             
            if (m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage(&m_msgCur))
            {
              ::TranslateMessage(
            &m_msgCur); //鍵轉(zhuǎn)換
              ::DispatchMessage(&m_msgCur); //派送消息
             }

             
            return TRUE;
            }
            BOOL CWinThread::PreTranslateMessage(MSG* pMsg)
            {
             ASSERT_VALID(
            this);

             
            // 如果是線程消息,那么將會(huì)在消息映射表中找到消息入口,調(diào)用線程消息的處理函數(shù)
             if (pMsg->hwnd == NULL && DispatchThreadMessageEx(pMsg))
              
            return TRUE;

             
            // walk from target to main window
             CWnd* pMainWnd = AfxGetMainWnd();
             
            if (CWnd::WalkPreTranslateTree(pMainWnd->GetSafeHwnd(), pMsg))
              
            return TRUE;

             
            // in case of modeless dialogs, last chance route through main
             
            //   window's accelerator table
             if (pMainWnd != NULL)
             
            {
               CWnd
            * pWnd = CWnd::FromHandle(pMsg->hwnd);
               
            if (pWnd->GetTopLevelParent() != pMainWnd)
               
            return pMainWnd->PreTranslateMessage(pMsg);
             }


             
            return FALSE;   // no special processing
            }
            注:1.一般用PostThreadMessage函數(shù)發(fā)送線程之間的消息,他和窗口消息不同,需要指定線程id,消息激被系統(tǒng)放入到目標(biāo)線程的消息隊(duì)列中;用 ON_THREAD_MESSAGE( message, memberFxn )宏可以映射線程消息和他的處理函數(shù)。這個(gè)宏必須在應(yīng)用程序類(從CWinThread繼承)中,因?yàn)橹挥袘?yīng)用程序類才處理線程消息。如果你在別的類(比如視圖類)中用這個(gè)宏,線程消息的消息處理函數(shù)將得不到線程消息。
               2.消息的目標(biāo)窗口的PreTranslateMessage函數(shù)首先得到消息處理權(quán),如果函數(shù)返回FALSE,那么他的父窗口將得到消息的處理權(quán),直到主窗口;如果函數(shù)返回TRUE(表示消息已經(jīng)被處理了),那么就不需要調(diào)用父類的PreTranslateMessage函數(shù)。這樣,保證了消息的目標(biāo)窗口以及他的父窗口都可以有機(jī)會(huì)調(diào)用PreTranslateMessage,如果你想要消息不傳遞給父類進(jìn)行處理的話,返回TRUE就行了
             
               //對話框程序的消息循環(huán)
            int CWnd::RunModalLoop(DWORD dwFlags)
            {
             ASSERT(::IsWindow(m_hWnd)); 
            // window must be created
             ASSERT(!(m_nFlags & WF_MODALLOOP)); // window must not already be in modal state

             
            // for tracking the idle time state
             BOOL bIdle = TRUE;
             LONG lIdleCount 
            = 0;
             BOOL bShowIdle 
            = (dwFlags & MLF_SHOWONIDLE) && !(GetStyle() & WS_VISIBLE);
             HWND hWndParent 
            = ::GetParent(m_hWnd);
             m_nFlags 
            |= (WF_MODALLOOP|WF_CONTINUEMODAL);
             MSG
            * pMsg = &AfxGetThread()->m_msgCur;

             
            // acquire and dispatch messages until the modal state is done
             for (;;)
             
            {
              ASSERT(ContinueModal());

              
            // phase1: check to see if we can do idle work
              while (bIdle &&
               
            !::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE))
              
            {
               ASSERT(ContinueModal());

               
            // show the dialog when the message queue goes idle
               if (bShowIdle)
               
            {
                ShowWindow(SW_SHOWNORMAL);
                UpdateWindow();
                bShowIdle 
            = FALSE;
               }


               
            // call OnIdle while in bIdle state
               if (!(dwFlags & MLF_NOIDLEMSG) && hWndParent != NULL && lIdleCount == 0)
               
            {
                
            // send WM_ENTERIDLE to the parent
                ::SendMessage(hWndParent, WM_ENTERIDLE, MSGF_DIALOGBOX, (LPARAM)m_hWnd);
               }

               
            if ((dwFlags & MLF_NOKICKIDLE) ||
                
            !SendMessage(WM_KICKIDLE, MSGF_DIALOGBOX, lIdleCount++)) 
                     //發(fā)送WM_KICKIDLE消息,如果對話框中有狀態(tài)欄或是工具欄等,靠這個(gè)消息更新狀態(tài),相當(dāng)于OnIdle
               
            {
                
            // stop idle processing next time
                bIdle = FALSE;
               }

              }


              
            // phase2: pump messages while available
              do
              
            {
               ASSERT(ContinueModal());

               
            // pump message, but quit on WM_QUIT
               
            //PumpMessage(消息泵)的實(shí)現(xiàn)和上面講的差不多。都是派送消息到窗口。
               if (!AfxGetThread()->PumpMessage())
               
            {
                AfxPostQuitMessage(
            0);
                
            return -1;
               }


               
            // 消息為WM_SYSTIMER或者WM_SYSKEYDOWN,并且空閑顯示標(biāo)志為真的話,就顯示窗口并通知窗口立刻重繪。
               if (bShowIdle &&
                (pMsg
            ->message == 0x118 || pMsg->message == WM_SYSKEYDOWN))
               
            {
                ShowWindow(SW_SHOWNORMAL);
                UpdateWindow();
                bShowIdle 
            = FALSE;
               }

               // 檢測對話框是否還是模式狀態(tài),如果不是則退出
               
            if (!ContinueModal())
                
            goto ExitModal;

               
            // reset "no idle" state after pumping "normal" message
               if (AfxGetThread()->IsIdleMessage(pMsg))
               
            {
                bIdle 
            = TRUE;
                lIdleCount 
            = 0;
               }


              }
             while (::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE));
             }
             //無限循環(huán)

            ExitModal:
             m_nFlags 
            &= ~(WF_MODALLOOP|WF_CONTINUEMODAL);
             
            return m_nModalResult;
            }
            posted on 2008-09-02 23:16 黑色天使 閱讀(651) 評(píng)論(0)  編輯 收藏 引用 所屬分類: VC&MFC

            <2008年10月>
            2829301234
            567891011
            12131415161718
            19202122232425
            2627282930311
            2345678

            常用鏈接

            留言簿(2)

            隨筆分類

            隨筆檔案

            文章檔案

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            国产精品一区二区久久精品无码 | 久久久久久久久波多野高潮| 精品综合久久久久久98| 国产精品禁18久久久夂久| 91久久婷婷国产综合精品青草 | 94久久国产乱子伦精品免费| 久久精品9988| 久久久www免费人成精品| 久久99精品综合国产首页| 日韩一区二区三区视频久久| 久久99精品久久久久久hb无码| 久久久亚洲精品蜜桃臀| 精品久久久久久成人AV| 亚洲欧美成人久久综合中文网 | 国产精品一区二区久久精品涩爱| 久久这里只有精品18| 一本久久免费视频| 99热热久久这里只有精品68| 97久久香蕉国产线看观看| 久久99精品国产麻豆宅宅| 久久伊人五月天论坛| 青青热久久综合网伊人| 色偷偷久久一区二区三区| 香蕉久久夜色精品国产尤物| 国内精品伊人久久久久影院对白| 久久er热视频在这里精品| 亚洲AV成人无码久久精品老人| 久久香蕉国产线看观看猫咪?v| 久久精品国产只有精品2020| 精品国产乱码久久久久久郑州公司| 久久99国产精品久久99小说| 天天综合久久一二三区| 久久久久久A亚洲欧洲AV冫 | 性做久久久久久久| 久久久一本精品99久久精品88| 欧美午夜A∨大片久久| 亚洲国产成人精品91久久久 | 国产福利电影一区二区三区久久老子无码午夜伦不 | 久久综合给合综合久久| 久久强奷乱码老熟女网站| 一本久久免费视频|