• <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 天下 閱讀(5419) 評論(0)  編輯 收藏 引用 所屬分類: QT

            <2017年5月>
            30123456
            78910111213
            14151617181920
            21222324252627
            28293031123
            45678910

            導航

            統計

            常用鏈接

            留言簿(4)

            隨筆分類(378)

            隨筆檔案(329)

            鏈接

            最新隨筆

            搜索

            最新評論

            狠狠色综合网站久久久久久久| 亚洲中文字幕久久精品无码喷水 | 色综合久久久久综合99| 久久国产高清字幕中文| 国内精品伊人久久久久AV影院| 日韩乱码人妻无码中文字幕久久| 亚洲国产另类久久久精品黑人| 久久久无码精品亚洲日韩京东传媒 | 久久久久亚洲AV成人网人人网站 | 久久久免费观成人影院| 欧美性大战久久久久久| 亚洲精品视频久久久| 欧美久久久久久| 久久久国产乱子伦精品作者| 国内精品久久久久久99| 免费精品99久久国产综合精品| 久久精品亚洲福利| 久久国产劲爆AV内射—百度| 亚洲欧美成人综合久久久 | 免费观看久久精彩视频| 久久久久成人精品无码| 热久久视久久精品18| 久久久久人妻精品一区 | 欧美伊香蕉久久综合类网站| 久久www免费人成看国产片| 色天使久久综合网天天| 欧美亚洲另类久久综合| 国产成人久久精品一区二区三区 | 国产成人无码精品久久久久免费| 性高朝久久久久久久久久| 久久精品国产亚洲AV电影| 欧美日韩中文字幕久久久不卡| 浪潮AV色综合久久天堂| 色播久久人人爽人人爽人人片aV| 久久精品aⅴ无码中文字字幕不卡 久久精品aⅴ无码中文字字幕重口 | 99久久精品免费看国产| 亚洲AV日韩精品久久久久久| 久久国产成人| 韩国免费A级毛片久久| 久久精品亚洲AV久久久无码| 久久精品国产第一区二区|