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

            天下

            記錄修行的印記

            [原]Qt事件處理機制淺析

             

            [原]Qt事件處理機制淺析
                
            事件處理機制淺析是通過WM_ACTIVATE消息來分析的
            //調用堆棧
            WinMainCRTStartup()  
            __tmainCRTStartup() 
            WinMain()  
            main(
            int argc=1char ** argv)  
            QtGuid4.dll
            !QApplication::exec()  
            QtCored4.dll
            !QCoreApplication::exec()  
            QtCored4.dll
            !QEventLoop::exec()  
            QtCored4.dll
            !QEventLoop::processEvents()  
            QtGuid4.dll
            !QGuiEventDispatcherWin32::processEvents() 
            QtCored4.dll
            !QEventDispatcherWin32::processEvents()  
            user32.dll
            !_PeekMessageW@20()  //說明1,調用PeekMessage,非阻塞的取消息!
            QtGuid4.dll!QtWndProc(HWND__ * hwnd, unsigned int message=6, unsigned int wParam=2long lParam=0)  //即 WM_ACTIVATE 消息
            QtGuid4.dll!QApplication::winFocus(QWidget * widget, bool gotFocus=true)  
            QtGuid4.dll
            !QApplication::setActiveWindow(QWidget * act) 
            QtCored4.dll
            !QCoreApplication::sendSpontaneousEvent(QObject * receiver, QEvent * event)  
            QtCored4.dll
            !QCoreApplication::notifyInternal(QObject * receiver, QEvent * event)  
            QtGuid4.dll
            !QApplication::notify(QObject * receiver, QEvent * e)  
            QtGuid4.dll
            !QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) 
            QtGuid4.dll
            !QApplication::event(QEvent * e)  
            QtCored4.dll
            !QCoreApplication::event(QEvent * e)  
            QtCored4.dll
            !QObject::event(QEvent * e) 


            說明2:
            // QtWndProc() receives all messages from the main event loop
            extern "C" LRESULT QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
            {
                
            switch (message) {
                    
            //case 消息的處理
                    
            //1538行->1670行 
                }
                
            if (!widget)
                    widget 
            = (QETWidget*)QWidget::find(hwnd);
                
            if (!widget)                                // don't know this widget
                    goto do_default;
                    
                
            if (qt_is_translatable_mouse_event(message)) { 
                        
            //message=512 第3個消息
                        
            //#define WM_MOUSEFIRST 0x0200
                        
            //#define WM_MOUSEMOVE  0x0200
                    if (!qt_tabletChokeMouse) {
                        result 
            = widget->translateMouseEvent(msg);        // mouse event
                    }            
                }
                
            else {
                    
            switch (message) {    
                    
            //message = 136 第4個消息  #define WM_SYNCPAINT 0x0088
                    
            //message = 133,第5個消息    #define WM_NCPAINT 0x0085 
                    
            //message = 28 ,第6個消息 #define WM_ACTIVATEAPP 0x001C
                    
            //message = 6  ,第7個消息 #define WM_ACTIVATE 0x0006 =>進入 qApp->winFocus(widget, true); //說明3    
                    
            //#define WM_NCHITTEST 0x0084 第1個消息,result = false, 進入do_default標記中的DefWindowProc處理
                    
            //#define WM_SETCURSOR 0x0020 第2個消息,result = false, 進入do_default標記中的DefWindowProc處理
                    case WM_NCHITTEST: 
                    
            case WM_SETCURSOR: 
                }
                
            if (result)
                    RETURN(
            false);
            do_default:
                RETURN(QWinInputContext::DefWindowProc(hwnd,message,wParam,lParam))            
            }

            //說明3
            void QApplication::winFocus(QWidget *widget, bool gotFocus)
            {
                
            if (gotFocus) {
                    setActiveWindow(widget);
                }
            }    
            void QApplication::setActiveWindow(QWidget* act)
            {    
                
            if (!previousActiveWindow) {
                    QEvent appActivate(QEvent::ApplicationActivate); 
            //關鍵是這里,appActivate 對象
                    sendSpontaneousEvent(qApp, &appActivate);
                }
               
            for (int i = 0; i < toBeActivated.size(); ++i) {  
                       
            //這里會繼續調用
                    QWidget *= toBeActivated.at(i);
                    sendSpontaneousEvent(w, 
            &windowActivate);
                    sendSpontaneousEvent(w, 
            &activationChange);
                } 
                
            }
            inline 
            bool QCoreApplication::sendSpontaneousEvent(QObject *receiver, QEvent *event)

                
            if (eventevent->spont = truereturn self ? self->notifyInternal(receiver, event) : false
            }

            /*!
              \internal
              This function is here to make it possible for Qt extensions to
              hook into event notification without subclassing QApplication
            */
            bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event)
            {
                
            // Make it possible for Qt Jambi and QSA to hook into events even
                
            // though QApplication is subclassed
                bool result = false;
                
            void *cbdata[] = { receiver, event&result };
                
            if (QInternal::activateCallbacks(QInternal::EventNotifyCallback, cbdata)) {
                    
            return result;
                }

                
            // Qt enforces the rule that events can only be sent to objects in
                
            // the current thread, so receiver->d_func()->threadData is
                
            // equivalent to QThreadData::current(), just without the function
                
            // call overhead.
                QObjectPrivate *= receiver->d_func();
                QThreadData 
            *threadData = d->threadData;
                
            ++threadData->loopLevel;

                
            bool returnValue;
                QT_TRY {
                    returnValue 
            = notify(receiver, event);  //大名鼎鼎的notify(),處理后,調用notify_helper繼續處理
                } QT_CATCH () {
                    
            --threadData->loopLevel;
                    QT_RETHROW;
                }
                
            --threadData->loopLevel;
                
            return returnValue;
            }



            bool QApplication::notify(QObject *receiver, QEvent *e)
            {
                
            //
                
            // walk through parents and check for gestures
                if (d->gestureManager) {
                    
            switch (e->type()) {
                    
            case QEvent::Paint:
                    
            case QEvent::DynamicPropertyChange:
                    
            case QEvent::NetworkReplyUpdated:
                    
            //
                        break;
                    
            default:
                        
            if (receiver->isWidgetType()) {
                            
            if (d->gestureManager->filterEvent(static_cast<QWidget *>(receiver), e))
                                
            return true;
                        } 
            else {
                            
            // a special case for events that go to QGesture objects.
                            
            // We pass the object to the gesture manager and it'll figure
                            
            // out if it's QGesture or not.
                            if (d->gestureManager->filterEvent(receiver, e))
                                
            return true;
                        }
                    }
                }

                
            // User input and window activation makes tooltips sleep
                switch (e->type()) {
                
            case QEvent::Wheel:
                
            case QEvent::ActivationChange:
                
            //
                default:
                    res 
            = d->notify_helper(receiver, e);
                    
            break;
                }
                
            return res;
            }


            bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)
            {
                
            // send to all application event filters
                if (sendThroughApplicationEventFilters(receiver, e))
                    
            return true;

                
            if (receiver->isWidgetType()) {
                    QWidget 
            *widget = static_cast<QWidget *>(receiver);
                    
            //.
                    if (QLayout *layout=widget->d_func()->layout) {
                        layout
            ->widgetEvent(e);
                    }
                }

                
            // send to all receiver event filters 
                
            //說明4:這里也是關鍵的地方
                if (sendThroughObjectEventFilters(receiver, e))
                    
            return true;

                
            // deliver the event
                bool consumed = receiver->event(e); //說明5,receiver->event()調用
                e->spont = false;
                
            return consumed;
            }

            bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, QEvent *event)
            {
                Q_Q(QCoreApplication);
                
            if (receiver != q) {
                    
            for (int i = 0; i < receiver->d_func()->eventFilters.size(); ++i) {
                        register QObject 
            *obj = receiver->d_func()->eventFilters.at(i);
                        
            if (!obj)
                            
            continue;
                        
            if (obj->d_func()->threadData != receiver->d_func()->threadData) {
                            qWarning(
            "QCoreApplication: Object event filter cannot be in a different thread.");
                            
            continue;
                        }
                        
            if (obj->eventFilter(receiver, event))
                            
            return true;
                    }
                }
                
            return false;
            }


            bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
            {
                
            if (receiver->d_func()->threadData == this->threadData) {
                    
            // application event filters are only called for objects in the GUI thread
                    for (int i = 0; i < eventFilters.size(); ++i) {
                        register QObject 
            *obj = eventFilters.at(i);
                        
            if (!obj)
                            
            continue;
                        
            if (obj->d_func()->threadData != threadData) {
                            qWarning(
            "QCoreApplication: Application event filter cannot be in a different thread.");
                            
            continue;
                        }
                        
            if (obj->eventFilter(receiver, event))
                            
            return true;
                    }
                }
                
            return false;
            }
            bool QApplication::event(QEvent *e)
            {
                Q_D(QApplication);
                
            if(e->type() == QEvent::Close) {
                    QCloseEvent 
            *ce = static_cast<QCloseEvent*>(e);
                    ce
            ->accept();
                    closeAllWindows();

                    QWidgetList list 
            = topLevelWidgets();
                    
            for (int i = 0; i < list.size(); ++i) {
                        QWidget 
            *= list.at(i);
                        
            if (w->isVisible() && !(w->windowType() == Qt::Desktop) && !(w->windowType() == Qt::Popup) &&
                             (
            !(w->windowType() == Qt::Dialog) || !w->parentWidget())) {
                            ce
            ->ignore();
                            
            break;
                        }
                    }
                    
            if (ce->isAccepted()) {
                        
            return true;
                    } 
            else {
                    }
                } 
            else if(e->type() == QEvent::LanguageChange) {
                    QWidgetList list 
            = topLevelWidgets();
                    
            for (int i = 0; i < list.size(); ++i) {
                        QWidget 
            *= list.at(i);
                        
            if (!(w->windowType() == Qt::Desktop))
                            postEvent(w, 
            new QEvent(QEvent::LanguageChange));
                    }
                } 
            else if (e->type() == QEvent::Timer) {
                    QTimerEvent 
            *te = static_cast<QTimerEvent*>(e);
                    Q_ASSERT(te 
            != 0);
                    
            if (te->timerId() == d->toolTipWakeUp.timerId()) {
                        d
            ->toolTipWakeUp.stop();
                        
            if (d->toolTipWidget) {
                            QWidget 
            *= d->toolTipWidget->window();
                            
            // show tooltip if WA_AlwaysShowToolTips is set, or if
                            
            // any ancestor of d->toolTipWidget is the active
                            
            // window
                            bool showToolTip = w->testAttribute(Qt::WA_AlwaysShowToolTips);
                            
            while (w && !showToolTip) {
                                showToolTip 
            = w->isActiveWindow();
                                w 
            = w->parentWidget();
                                w 
            = w ? w->window() : 0;
                            }
                            
            if (showToolTip) {
                                QHelpEvent e(QEvent::ToolTip, d
            ->toolTipPos, d->toolTipGlobalPos);
                                QApplication::sendEvent(d
            ->toolTipWidget, &e);
                                
            if (e.isAccepted())
                                    d
            ->toolTipFallAsleep.start(2000this);
                            }
                        }
                    } 
            else if (te->timerId() == d->toolTipFallAsleep.timerId()) {
                        d
            ->toolTipFallAsleep.stop();
                    }
                }
                
            return QCoreApplication::event(e); ////說明6,最終QObject::event()調用
            }

            bool QCoreApplication::event(QEvent *e)
            {
                
            if (e->type() == QEvent::Quit) {
                    quit();
                    
            return true;
                }
                
            return QObject::event(e);
            }

             

            posted on 2013-06-27 11:10 天下 閱讀(5418) 評論(0)  編輯 收藏 引用 所屬分類: QT

            <2012年1月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            2930311234

            導航

            統計

            常用鏈接

            留言簿(4)

            隨筆分類(378)

            隨筆檔案(329)

            鏈接

            最新隨筆

            搜索

            最新評論

            久久久久亚洲Av无码专| 思思久久好好热精品国产| 色婷婷综合久久久久中文| 亚洲精品无码久久久影院相关影片| 精产国品久久一二三产区区别| 亚洲精品乱码久久久久久蜜桃不卡 | 亚洲国产精品无码久久九九| 中文成人久久久久影院免费观看| 久久av无码专区亚洲av桃花岛| 国产麻豆精品久久一二三| 日韩一区二区久久久久久 | 久久久久九国产精品| 亚洲v国产v天堂a无码久久| 亚洲AV日韩AV天堂久久| 久久久99精品成人片中文字幕| 婷婷综合久久中文字幕蜜桃三电影| 99久久综合国产精品二区| 久久亚洲AV成人无码电影| 人人狠狠综合久久亚洲| 成人午夜精品久久久久久久小说 | 97久久天天综合色天天综合色hd| 久久人搡人人玩人妻精品首页| 久久精品aⅴ无码中文字字幕重口 久久精品a亚洲国产v高清不卡 | 久久精品综合网| 成人免费网站久久久| 久久综合给合久久国产免费| 国产高清国内精品福利99久久| 亚洲精品乱码久久久久久按摩 | 久久99国产精品久久99果冻传媒| 国产精品久久久久蜜芽| 97精品国产97久久久久久免费 | 亚洲精品无码久久久久去q | 一本大道加勒比久久综合| 亚洲中文精品久久久久久不卡| 综合久久一区二区三区 | 亚洲欧美日韩中文久久| 久久久噜噜噜久久中文字幕色伊伊| 久久久久国产一级毛片高清板| 国产免费久久久久久无码| 国产欧美久久久精品| 国产精品99久久久久久www|