• <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>
            蝸牛的家
            男兒當自強
            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(消息泵)的實現和上面講的差不多。都是派送消息到窗口。
               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);
               消息分為隊列消息(進入線程的消息隊列)和非隊列消息(不進入線程的消息隊列)。對于隊列消息,最常見的是鼠標和鍵盤觸發的消息,例如 WM_MOUSERMOVE,WM_CHAR等消息;還有例如:WM_PAINT、WM_TIMER和WM_QUIT。當鼠標、鍵盤事件被觸發后,相應的鼠標或鍵盤驅動程序就會把這些事件轉換成相應的消息,然后輸送到系統消息隊列,由Windows系統負責把消息加入到相應線程的消息隊列中,于是就有了消息循環(從消息隊列中讀取并派送消息)。還有一種是非隊列消息,他繞過系統隊列和消息隊列,直接將消息發送到窗口過程。例如,當用戶激活一個窗口系統發送 WM_ACTIVATE, WM_SETFOCUS, and WM_SETCURSOR。創建窗口時發送WM_CREATE消息。
            BOOL CWinThread::PumpMessage()
            {
             ASSERT_VALID(
            this);
             
             
            //如果是WM_QUIT就退出函數(return FALSE),這將導致程序結束.
             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); //鍵轉換
              ::DispatchMessage(&m_msgCur); //派送消息
             }

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

             
            // 如果是線程消息,那么將會在消息映射表中找到消息入口,調用線程消息的處理函數
             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函數發送線程之間的消息,他和窗口消息不同,需要指定線程id,消息激被系統放入到目標線程的消息隊列中;用 ON_THREAD_MESSAGE( message, memberFxn )宏可以映射線程消息和他的處理函數。這個宏必須在應用程序類(從CWinThread繼承)中,因為只有應用程序類才處理線程消息。如果你在別的類(比如視圖類)中用這個宏,線程消息的消息處理函數將得不到線程消息。
               2.消息的目標窗口的PreTranslateMessage函數首先得到消息處理權,如果函數返回FALSE,那么他的父窗口將得到消息的處理權,直到主窗口;如果函數返回TRUE(表示消息已經被處理了),那么就不需要調用父類的PreTranslateMessage函數。這樣,保證了消息的目標窗口以及他的父窗口都可以有機會調用PreTranslateMessage,如果你想要消息不傳遞給父類進行處理的話,返回TRUE就行了
             
               //對話框程序的消息循環
            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++)) 
                     //發送WM_KICKIDLE消息,如果對話框中有狀態欄或是工具欄等,靠這個消息更新狀態,相當于OnIdle
               
            {
                
            // stop idle processing next time
                bIdle = FALSE;
               }

              }


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

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


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

               // 檢測對話框是否還是模式狀態,如果不是則退出
               
            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));
             }
             //無限循環

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

            <2009年1月>
            28293031123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            常用鏈接

            留言簿(2)

            隨筆分類

            隨筆檔案

            文章檔案

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            性做久久久久久免费观看| 国产美女久久精品香蕉69| 久久播电影网| 久久久亚洲裙底偷窥综合 | 色成年激情久久综合| 久久亚洲高清观看| 欧美亚洲国产精品久久| 无码人妻精品一区二区三区久久久 | 久久99久久99精品免视看动漫| 人妻精品久久久久中文字幕69| 66精品综合久久久久久久| 久久无码高潮喷水| 国产成人精品综合久久久| 日韩精品无码久久久久久| 久久精品国产一区二区 | 色诱久久久久综合网ywww| 久久九九久精品国产| 久久精品国产亚洲av麻豆色欲| 亚洲国产精品婷婷久久| 色偷偷88欧美精品久久久| 天天综合久久一二三区| 国产综合精品久久亚洲| 色8激情欧美成人久久综合电| 亚洲国产精品无码久久SM| 丁香狠狠色婷婷久久综合| 精品久久人人妻人人做精品| 亚洲另类欧美综合久久图片区| 日韩人妻无码精品久久免费一| 99久久www免费人成精品| 久久亚洲AV成人无码| 久久久国产精品福利免费| 一本色道久久88综合日韩精品 | 人人狠狠综合88综合久久| 新狼窝色AV性久久久久久| 天天综合久久久网| 中文字幕精品久久| 999久久久免费国产精品播放| 欧美日韩久久中文字幕| 国产精品热久久无码av| 国内精品久久久久伊人av | 欧美伊人久久大香线蕉综合|