• <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)論排行榜

            97精品伊人久久久大香线蕉| 99久久精品免费看国产一区二区三区| 亚洲欧美日韩精品久久亚洲区| 亚洲色欲久久久久综合网| 精品多毛少妇人妻AV免费久久| 波多野结衣AV无码久久一区| 久久亚洲精品中文字幕三区| 久久综合伊人77777麻豆| 久久久免费精品re6| 久久免费观看视频| av无码久久久久久不卡网站| 伊人久久大香线蕉精品不卡| 久久精品嫩草影院| 久久人人爽人人爽人人片av麻烦| 日韩亚洲欧美久久久www综合网| 久久亚洲精品国产精品婷婷| 久久综合综合久久97色| 久久99热这里只有精品国产| 久久无码精品一区二区三区| 国内精品久久久久影院优| 久久精品中文字幕一区| 欧美久久一区二区三区| 品成人欧美大片久久国产欧美...| 久久天堂AV综合合色蜜桃网| 噜噜噜色噜噜噜久久| 亚洲国产精品无码久久久久久曰 | 亚洲国产精品一区二区久久| 国内精品九九久久精品| 久久久久久毛片免费看| 色综合久久中文综合网| 国产精品一久久香蕉产线看| 亚洲人成精品久久久久| 久久天天躁狠狠躁夜夜躁2014| 久久久久女教师免费一区| 久久国产视频99电影| 久久国产V一级毛多内射| 久久国产影院| 一本大道久久东京热无码AV| 亚洲综合久久夜AV | 久久久久久精品免费免费自慰| 青青草原综合久久大伊人|