青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-19  評論-2  文章-0  trackbacks-0

2009-10-1

========================================================
《深入解析MFC》筆記 10. MFC的DLL與線程
========================================================

---------------------
概念:
    模塊: 
        一段可執行的程序(包括EXE和DLL),其程序代碼、數據、資源被加載到內存中,由系統建置一個數據結構來管理它,這就是一個模塊。
    進程:
        進程是一堆擁有權(ownership)的集合,進場那個擁有地址空間,動態配置而來的內存、文件、線程和一序列的模塊。
    概要:
    · DLL與線程的實現依賴于內部 MFC 狀態類,MFC的狀態將數據分到不同的邏輯范圍中,從而使得線程和 DLL 不會破會對方的數據。
    · 擴展 DLL 僅僅用來擴展已存在的 MFC 應用程序。
    · MFC中,擴展 DLL 被創建時要使用 _AFXDLL標志。
    · 擴展 DLL 有一些資源和其他信息需要在運行時被檢索。CDynLinkLibrary是它的輔助類。
   
    · 輔助線程,UI線程 都是用 _beginthreadex()創建、以_endthread()來結束。
    · CWinThread::CreateThread創建線程,并且使用_AfxThreadEntry()來為線程提供執行路徑。
    · 核心:CWinThread::Run()
--------------------
MFC狀態

3中MFC狀態信息類型:
    模塊狀態、進程狀態、線程狀態
    win32中,一個模塊就是獨立于應用程序其他部分而操作的可執行代碼。
   
    模塊狀態,  既可以包含真正的全局狀態,也可以包含進程局部或者線程局部的狀態,且它可以被快速地切換。
    可把MFC狀態理解成應用程序不同部分的局部數據。
        進程狀態包含局部于進程和某個模塊的數據。模塊的狀態信息包含局部于該模塊的數據,線程的狀態信息包含局部于該線程的數據。
       
    ------------------------------
    MFC進程狀態       
  
AFX_MODULE_PROCESS_STATE的定義,   AFXSTAT_.H                  《深入解析MFC》P301
    · m_pfnFilterToolTipMessage —— 一個函數指針,指向用于過濾工具提示消息的函數。
    · CTypedSimpleList<CDynLinkLibrary*> m_libraryList —— 附加的MFC擴展DLL鏈表
    · HINSTANCE m_appLangDLL —— 當前被局部化的資源的實例句柄。
    · COccManager* m_pOccManager —— 指向OLE控件管理對象的指針
    · CTypedSimpleList<COleControlLock*>  m_lockList —— 被鎖定的 OLE 控件鏈表
   
    ------------------------------
    MFC模塊狀態

AFX_MODULE_STATE 定義,     AFXSTAT_.H            《深入解析MFC》  P302
    · CWinApp*  m_pCurrentWinApp —— 指向該模塊的CWinApp對象的指針
    · HINSTANCE  m_hCurrentInstanceHandle —— 模塊的實例句柄
    · HINSTANCE  m_hCurrentResourceHandle —— 資源的實例句柄
    · LPCTSTR  m_lpszCurrentAppName —— 當前應用程序的名稱
    · BYTE  m_bDLL  —— 指明該模塊是否是 DLL 的一個標志。
    · BYTE  m_bSystem —— 指明該模塊是否是系統模塊的一個標志
    · short  m_fRegisteredClasses —— 用于模塊的延遲注冊類的位標識。
    · CRuntimeClass*  m_pClassInit —— 指向第一個類的 CRuntimeClass 信息的指針(通常是 m_classList的頭)
    · CTypedSimpleList<CRuntimeClass*>  m_classList —— 模塊里各個對象的 CRuntimeClass 信息鏈表
    · COleObjectFactory*  m_pFactoryInit —— 指向第一個 COleObjectFactory對象的指針(通常是 m_factoryList 的頭)    
    · CTypedSimpleList<COleObjectFactory*>  m_factoryList —— 模塊里各個對象的 COleObjectFactory 對象的鏈表
    · long m_nObjectCount —— 被鎖住的OLE對象的數目。
    · BOOl  m_bUserCtrl —— 如果用戶有控制權,則設置為 TRUE,否則為FALSE
    · TCHAR  m_szUnregisterList —— 未被注冊的類鏈表
    · WNDPROC  m_pfnAfxWndProc —— 指向模塊所有的 AfxWndProc 的指針
    · DWORD   m_dwVesion —— 模塊連接所使用的 MFC 版本號
    · m_process —— 進程狀態信息  PROCESS_LOCAL( AFX_MODULE_PROCESS_STATE,  m_process )
    · m_thread —— 線程狀態信息   THTEAD_LOCAL( AFX_MODULE_THREAD_STATE, m_thread )
   
    -------------------------------
    MFC 線程狀態信息                  《深入解析MFC》P305
   
_AFX_THREAD_STATE
    · AFX_MODULE_STATE*  m_pModuleState —— 指向當前模塊狀態的指針
    · AFX_MODULE_STATE*  m_pPrevModuleState —— 指向下一個模塊狀態的指針
    · void* m_pSafetyPoolBuffer —— 指向安全緩沖區的指針,它支持強壯的臨時對象內存分配
    · AFX_EXCEPTION_CONTEXT  m_exceptionContext —— 當前的異常環境。
    · CWnd*  m_pWndInit —— 一個窗口指針,指向最近hook的窗口
    · CWnd*  m_pAlternateWndInit —— 指向最近被hook的公用對話框窗口的指針
    · DWORD  m_dwPropStyle ——屬性頁的風格
    · DWORD  m_dwPropExStyle —— 屬性頁的擴展風格
    · HWND  m_hWndInit —— m_pWndInit 的匹配句柄
    · BOOL  m_bDlgCreate —— 表明某個對話框被創建了,MFC為對話框繪制與普通窗口不同的背景顏色
    · HHOOK  m_hHookOldSendMsg —— 由::SetWindowsHookEx ( WH_CALLWNDPROC ) 返回的前一個句柄的句柄
    · HHOOK  m_hHookOldCbtFilter —— 由::SetWindowsHookEx ( WH_CBT )返回的前一句并的句柄。
    · HHOOK  m_hHookOldMsgFilter —— 由::SetWindowsHookEx ( WH_MSGFILTER )返回的前一個句柄的句柄
    · MSG  m_lastSentMsg —— 發送的最后一個消息
    · HWND  m_hTrackingWindow —— 當前跟蹤窗口的句柄
    · HMENU  m_hTrackingMenu —— 當前跟蹤菜單的句柄
    · TCHAR  m_szTempClassName —— 在 AfxRegisterWndClass() 中使用的緩沖區
    · HWND  m_hLockoutNotifyWindow —— 在鎖定(沒有OLE控件)的窗口句柄,如果存在一個的話。
    · BOOL  m_bInMsgFilter —— 表明該線程在一個消息過濾器中的標志。
    · CView*  m_pRoutingView —— 在將消息發送給文檔之前,視圖所先將自己保存到該變量中。
    · CFrameWnd*  m_bWaitForDataSource —— 之名 ODBC 正在等待的數據
    · CToolTipCtrl*  m_pToolTip —— 指向當前CToolTipCtrl的指針
    · CWnd*  m_pLastHit —— 指向擁有工具提示控件的最后一個窗口的指針
    · int  m_nLastHit —— 最后的點擊測試代碼(用于工具提示點擊測試)
    · TOOLINFO  m_lastInfo —— 最后的工具提示 TOOLINFO結構
    · int  m_nLastStatus —— 最后的浮動狀態代碼
    · CControlBar*  m_pLastStatus —— 指向最后的浮動狀態控制條的指針
   
    ----------------------------------------------
    MFC狀態之間的聯系               《深入解析MFC》P305
   
    當MFC需要到達當前的 _AFX_THREAD_STATE時,調用 AfxGetThreadState()
    THREAD_LOCAL( _AFX_THREAD_STATE, _afxThreadState )
    這行代碼為每個線程的 TLS 創建一個名為 _afxThreadState 的 _AFX_THREAD_STATE 類,可通過調用 AfxGetThreadState()來訪問
    _AFX_THREAD_STATE 記錄了指向當前模塊狀態的指針,名為 m_pModuleState。可通過調用 AfxGetModuleState()得到。
        · 多數情況會得到 _afxThreadState.m_pModuleState 的 AFX_MODULE_STATE
        · 如果為NULL,將有一個全局的進程局部模塊狀態,PROCESS_LOCAL( _AFX_BASE_MODULE_STATE,  _afxBaseModuleState )
    當MFC是一個DLL時,會通過調用 AfxSetModuleState() 來改變模塊的狀態。


=================
MFC的DLL
    ---------------------------《深入解析MFC》P307
    USRDLL   與  AFXDLL
   
    USRDLL:
            可被靜態“粘貼”到DLL上,可以再DLL使用MFC,而不必要求使用該DLL的應用程序也是用MFC寫的。           
    AFXDLL :
            是使用了MFC的DLL,只能用于MFC程序。

    ---------------------------
    DLL 的資源問題
   
        DLL 里有 3 種類型的信息:  
                    資源、      靜態的CRuntimeClass指針、           OLE對象廠(object factory)
        MFC 的 DLL 版本程序起點在 DllMain()(當DLL被裝載時該函數被調用)
       
            AfxInitExtensionModule( coreDLL, hInstance );
            CDynLinkLibrary*  pDLL  =  new  CDynLinkLibrary ( coreDLL,  TRUE );
           
        裝載資源時,通過調用 AfxFindResourceHandle() 來實現
            AfxInitExtensionModule( AFX_EXTENSION_MODULE& state,  HMODULE  hModule )
            {
            //only initialize once
                if ( state.bInitialized ){   //若該模塊已經初始化,AfxInitLocalData()被調用來更新 TLS 使用的模塊句柄。
                    AfxInitLocalData( hModule );
                    return TRUE;
                }
                state.bInitialized = TRUE;
                    // save the current HMODULE info for resource loading
                state.hModule  = hModule;
                state.hResource = hModule;
                    // save the start of the runtime class list
                AFX_MODULE_STATE* pModuleState  =  AfxGetModuleState();
                state.pFirstSharedClass  = pModuleState->m_classList.GetHead();
                pModuleState->m_classList.m_pHead  =  pModuleState->m_pClassInit;
                    //save the start of the class factory list
                state.pFirstSharedFactory  = pModuleState->m_factoryList.GetHead();
                pModuleState->m_factoryList.m_pHead = pModuleState->m_pFactoryInit;
                return TRUE; 
            }
           
        --------------------------------
        剖析 CDynLinkLibrary                        《深入解析MFC》P310
        class CDynLinkLibrary : public CCmdTarget
        {
            HMODULE  m_hModule;             //
            HMODULE  m_hResource;           //for  shared  resources
            CTypedSimpleList<CRuntimeClass* >  m_classList;
            CTypedSimpleList<COleObjectFactory*>  m_factoryList;
            BOOL   m_bSystem;                   // TRUE  only  for  MFC  DLLs
           
            CDynLinkLibrary*  m_pNextDLL;       //simple singly linked  list
                //implementation
            CDynLinkLibrary::CDynLinkLibrary ( AFX_EXTENSION_MODULE& state,  BOOL  bSystem ){
                m_factoryList.Construct( offsetof ( COleObjectFactory, m_pNextFactory ) );
                m_classList.Construct( offsetof ( CRuntimeClass, m_pNextClass ) );
                    //copy info from  AFX_EXTENSION_MODULE
                m_hResource  = state.hResource;
                m_classList.m_pHead  =  state.pFirstSharedClass;
                m_factoryList.m_pHead  =  state.pFirstSharedFactory;
                m_bSystem  =  bSystem;
                    //insert at the end of the list ( extensions will go in front of core  DLL )
                AFX_MODULE_PROCESS_STATE*  pState  =  AfxGetModuleProcessState();
                AfxLockGlobals ( CRIT_DYNLINKLIST );
                pState->m_libraryList.AddHead ( this );
                AfxUnlockGlobals ( CRIT_DYNLINKLIST );
            }
        }
       
        --------------------------------
        剖析 AfxFindResourceHandle()                《深入解析MFC》P311
            AfxFindResourceHandle()               "DLLINIT.CPP"
           
            首先,如果當前模塊不是系統模塊,在當前模塊的資源句柄(由AfxGetResourceHandle() 函數返回)里查找資源。
            接著,在進程狀態 m_libraryList 里遍歷 CDynLinkLibrary 鏈表。若擴展DLL不是系統 DLL,FindResource() 被調用。
                      然后在被進程狀態指向的與特定語言相關的DLL里尋找該信息。
            接著,檢查當前的模塊是否是系統模塊,調用FindResource() 搜索資源,最后再次遍歷 CDynLinkLibrary鏈表,在系統擴展DLL里查找該資源
            若沒有發現任何東西,返回 AfxGetResourceHandle(),即返回了進程的當前資源句柄。
           

        --------------------------------
        擴展 DLL 初始化與清除
       
        AFXDLL 與 宏
            DECLARE_DYNAMIC( DLL版 和 非DLL版本)  (AFX.H)      《深入解析MFC》P312
            IMPLEMENT_DYNAMIC            (AFX.H)
           
            DLL 和 非DLL之間的差別:
                MFC必須調用能返回靜態 CRuntimeClass成員地址的函數,而不是直接存儲、訪問靜態CRuntimeClass數據成員的地址。
               
               
=========================
MFC 線程
    輔助線程            UI 線程
    AfxBeginThread()
        輔助線程:將一個 CWinThread對象和一個指針傳遞給控制函數(控制函數負責工作的完成)
        UI 線程:  創建一個 CWinThread,將他的 CRuntimeClass 信息傳遞給 AfxBeginThread()。
       
    --------------------------
    MFC 的輔助線程               
            AfxBeginThread(){
                CWinThread*  pThread = new CWinThread ( pfnThreadProc,  pParam );
                if ( !pThread->CreateThread ( dwCreateFlags | CREATE_SUSPENDED, nStackSize, lpSecurityAttrs ) ){
                    pThread->Delete();          return NULL;
                }
                VERIFY ( pThread->SetThreadPriority ( nPriority ) );
                if( !(dwCreateFlags & CREATE_SUSPENDED )
                    VERIFY ( pThread->ResumeThread() != (DWORD) - 1);
                return  pThread;
            }
   
          
=========================
CWinThread                                          《深入解析MFC》P316
   
    數據成員:
        · CWnd*  m_pMainWnd —— 指向應用程序主窗口的指針, CWinThread需要用該指針來正確地用程序的主窗口。
        · CWnd*  m_bActiveWnd —— 當OLE 服務器在某個地方處于活動狀態時,該指針指向包含應用程序的主窗口。
        · BOOL   m_bAutoDelete —— 當該變量為 TRUE時, CWinThread會在線程結束時刪除自己。
        · HANDLE  m_hThread —— 被 CWinThread封裝的Win32線程的句柄
        · DWORD  m_hThreadID —— 被CWinThread 封裝的線程的 Win32 線程 ID。
        · MSG  m_msgCur —— 緩沖當前正被 CWinThread 消息發送其所處理的消息。
        · LPVOID  m_pThreadParams —— 保存pParam參數,他會繼續傳遞給輔助函數(worker function)。
        · AFX_THREADPROC  m_pfnThreadProc —— 指向輔助函數的指針
        · CPoint   m_ptCursorLast —— 最后鼠標移動消息中的 CPoint。被用來在 CWinThread 的空閑時刻過濾掉多與的鼠標移動信息。
        · UINT  m_nMsgLast —— 用來探測兩個連續的消息。
       
        · CommonConstruct() —— 供構造函數調用,僅僅將數據成員設置成正確的默認值
        · Delete() —— 如果 m_bAutoDelete為TRUE,則調用刪除自身。
       
    ----------------------.                                             《深入解析MFC》P317
    線程的創建——                   “THRDCORE.CPP”
    CWinThread::CreateThread() 第一部分:                      
        BOOL  CWinThread::CreateThread ( DWORD dwCreateFlags,  UINT nStackSize, LPSECURITY_ATTRIBUTES   lpSecurityAttrs ){
                //setup startup structure for thread initialization
            _AFX_THREAD_STARTUP  startup;
            memset ( &startup,  0, sizeof( startup) );
            startup.pThreadState = AfxGetThreadState();         //_AFX_THREAD_STATE
            startup.pThread = this;                     //指向 CWinThread 的后向指針 (back pointer)
            startup.hEvent = ::CreateEvent ( NULL, TRUE, FALSE, NULL);     //線程被成功創建后,hEvent被觸發
            startup.hEvent2 = ::CreateEvent ( NULL, TRUE, FALSE, NULL);   //線程被重新啟動,hEvent2 被觸發
            startup.dwCreateFlags = dwCreateFlags;        //指定線程是否應該被掛起以及其他信息的創建標志。
                //**some event checking and cleanup omitted for brevity
                //create the thread (it may or may not start to run)
            m_hThread = (HANDLE) _beginthreadex ( lpSecurityAttrs, nStackSize, &_AfxThreadEntry,  &startup,
                                                 dwCreateFlags | CREATE_SUSPENDED,  (UINT* ) &m_nThreadID );
            if( m_hThread ==NULL)   
                return FALSE;
        }
        線程創建之后:
                //CWinThread::CreateThread()  continued...
            ① ResumeThread();
            ::WaitForSingleObject ( startup.hEvent,  INFINITE );
            ② ::CloseHandle ( startup.hEvent );
                //if created suspended , suspend it until resum thread wakes it up
            if( dwCreateFlags & CREATE_SUSPENDED )
                ::SuspendThread ( m_hThread );
            if( startup.bError )
                //**Error cleanup omitted - lots of frees and closes <g>
                // allow thread to continue, once resumed (it may already be resumed)
                ::SetEvent ( startup.hEvent2 );
            return TRUE;
       
        一個最初調用CreateThread() 得到的線程(父線程),另一個處在幼稚期的線程。
            到①時調用::ResumeThread( m_hThread ),這是父進程暫停,它等待_AFX_THREAD_START::hEvent。
            幼稚期線程開始運行,開始的位置在 _beginthreadex()調用告訴的位置:_AfxThreadEntry()
    ⊙﹏⊙b      _AfxThreadEntry 簡稱為 “_ATE”         《深入解析MFC》P319
        1、_ATE將它的 _AFX_THREAD_STARTUP 參數的 pThread 域保存到真正的 CWinThread 指針里。
        2、然后調用 AfxGetThreadState(),它會返回父線程的狀態,復制大部分父線程的狀態信息,用_AFX_THREAD_STARTUP的參數來修改模塊狀態。
                新的子線程從父線程那里”繼承“到了模塊狀態信息。
        3、再調用 AfxInitThread(),該函數為該線程創建了一個消息隊列以及一些消息過濾器。
        4、在AfxInitThread()執行完成后,_ATE創建一個局部的 CWnd對象,并將它貼附到當前的主窗口里。
                即將它貼附到 CWinApp::m_pMainWnd::m_hWnd,然后使得 CWinThread::m_pMainWnd指針指向它的地址。
        5、hEvent2句柄被從 _AFX_STARTUP_THREAD指針里拷貝出來。
        6、準備通知父線程子線程已準備好,信號被轉換成時間,使得父線程里的 ::WaitForSingleObject() 被啟動。真正的函數調用是 ::SetEvent(startup->hEvent)
        7、_ATE調用 ::WaitForSingleObject( hEvent2, INFINITE ) 將新的 成人線程休眠,直到父線程發出最后的信號       
            這時,在調用完::WaitForSingleObject()后,回到父線程,即回到②。
            父線程調用::CloseHandle() 為它的子女清除 hEventHandle,若子線程以暫停方式被調用,則在子線程調用::SuspendThread()。
        8、WaitForSingleObject()調用完成后,子線程向它的父線程說再見,并關閉了 hEvent2 記錄的句柄
        9、如果CWinThread::m_pfnThreadProc非空,子線程會意識到自己是 輔助線程,并且通過控制傳遞給 m_pfnThreadProc來開始工作
        10、若m_pfnthreadproc為空,則為一個UI 線程。
       
            _AfxThreadEntry() 中與 UI 有關的部分          "THRDCORE.CPP"
                    //Initialization and synchronization with mom before here.
                if ( pThread->m_pfnThreadProc != NULL )
                    nResult = pThread->ExitInstance();
                else if ( ! pThread->InitInstance() )         // InitInstance() 被CWinThread的派生類重載
                    nResult = pThread->ExitInsance();
                else
                    nResult = pThread->Run();             // 通常情況調用 CWinThread::Run()
                    //cleanup and shutdown the thread
                threadWnd.Detach();                             //將局部的 CWnd 主窗口對象分離出來
                AfxEndThread( nResult );                        //最終調用 _endthreadex().
                return 0;           //not reached
    ----------------
    MFC   UI 線程                                                                《深入解析MFC》P320

        輔助線程僅需向 CWinThread 提供一個指向某個函數的指針,
        UI 線程 需要從CWinThread 派生。
            · ExitInstance() —— 當線程結束時執行一些清理工作。
            · InitInstance() —— 執行線程實例的初始化工作。
            · OnIdle() —— 執行與線程有關的空閑時的處理工作。
            · PreTranslateMessage() —— 消息過濾器
            · Run() —— 消息泵(非MFC消息的循環處理)
        CWinApp 是一個UI線程
                   
    -----------------------------
    CWinThread::Run()                        “THRDCORE.CPP”
  
    int CWinThread::Run(){
        BOOL bIdle = TRUE;
        LONG  lIdleCount = 0;
        for( ; ; ){
                //phase1: check to see if we can do idle work
            while (bIdle && ! ::PeekMessage ( &m_msgCur, NULL, NULL, NULL, PM_NOREMOVE ) ){
                if ( ! OnIdle ( lIdleCount ++ ) )
                    bIdle = FALSE;                      // assume "no idle " state
            }
                //phase 2: pump messages while available
            do  {
                  if ( !PumpMessage() )
                      return ExitInstance();
                  if ( IsIdleMessage ( &m_msgCur ) ){
                      bIdle = FALSE;
                      lIdleCount = 0;
                  }
            }while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE ) );
        }
    }
        通過bIdle標志 和 LONG變量 lIdleCount 連接兩個階段。
    · 階段一 —— while循環,當線程的消息隊列里沒有任何消息時,它處在閑置狀態。
    · 階段二 —— do-while 循環,當有消息需要被分發時,它進行消息的分發。
   
   
        ●  階段一: 空閑處理
        通過調用OnIdle() 來告訴用戶沒有執行任何操作,線程可以做一些清理工作或其他。閑置操作完成后,返回 0 ;
        OnIdle()的參數用來指示線程已經有多長時間處在非活動狀態了,這樣,可以對空閑處理做一些優先排序工作。
       
    CWinThread::OnIdle()                            “THRDCORE.CPP”
   
    BOOL CWinThread::OnIdle ( LONG lCount )
    {
            if ( lCount <= 0 ) {
                    //send  WM_DILEUPDATECMDUI  to the main window
                    //send  WM_IDLEUPDATECMDUI  to all  frame  windows
            }
            else if ( lCount >= 0 ){
                    //Call AfxLockTempMaps / AfxUnlockTempMaps to free maps, DLLS, etc...
            }
            return  lCount < 0;     //nothing more to do if lCount >= 0
    }
        若調用 OnIdle( -1 ),強制執行一次 UI 更新,
   
        ●  階段二 : 消息的分發
       
            do-while 循環中,調用 PumpMessage() 分發消息,然后調用 IsIdleMessage() 來確認當前正在被處理的消息是否是空閑消息。

 


 

posted on 2010-03-15 23:27 Euan 閱讀(2727) 評論(0)  編輯 收藏 引用 所屬分類: windows
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            午夜伦欧美伦电影理论片| 欧美激情国产日韩精品一区18| 免费看成人av| 亚洲欧美精品suv| 欧美一区二区三区在| 国产亚洲制服色| 欧美成人免费在线| 国语对白精品一区二区| 欧美日韩国产综合视频在线| 亚洲午夜羞羞片| 欧美高清hd18日本| 欧美激情久久久久久| 宅男噜噜噜66一区二区66| 久久综合国产精品台湾中文娱乐网| 免费在线成人av| 韩国三级电影一区二区| 欧美视频一区二区| 国产欧美日韩亚洲| 欧美va天堂| 国产精品久久久久久久久久妞妞 | 欧美激情视频在线免费观看 欧美视频免费一| 中文在线一区| 午夜精品视频在线观看| 先锋影音国产精品| 亚洲欧美国产一区二区三区| 亚洲国产精选| 狠狠色综合网| 1000部精品久久久久久久久| 久久夜色精品| 亚洲第一精品电影| 欧美一区二区三区婷婷月色| 亚洲一区激情| 国产日韩精品视频一区| 亚洲精品视频中文字幕| 亚洲一区二区毛片| 欧美成人午夜激情| 国产精品乱码久久久久久| 欧美激情免费在线| 亚洲精品乱码久久久久久黑人| 欧美一区观看| 欧美激情第10页| 亚洲第一区色| 午夜精品av| 麻豆成人在线| 欧美日韩亚洲另类| 国产在线视频欧美| 亚洲国产高清在线| 美女脱光内衣内裤视频久久网站| 欧美午夜寂寞影院| 久久夜精品va视频免费观看| 欧美亚洲免费电影| 亚洲综合色自拍一区| 亚洲第一在线综合在线| 亚洲一区二区欧美日韩| 久久电影一区| 欧美一区二区三区视频| 亚洲日本欧美| 欧美黑人在线观看| 欧美成人黑人xx视频免费观看| 亚洲一区二区三区777| 韩国一区二区在线观看| 国产亚洲欧美在线| 黄色亚洲在线| 欧美gay视频| 亚洲第一狼人社区| 国产麻豆午夜三级精品| 欧美激情免费在线| 一本色道久久88精品综合| 亚洲第一精品久久忘忧草社区| 欧美不卡福利| 欧美激情在线狂野欧美精品| 亚洲桃花岛网站| 午夜国产精品视频免费体验区| 国产精品视频1区| 裸体丰满少妇做受久久99精品| 噜噜噜在线观看免费视频日韩| 久久综合九色综合欧美狠狠| 一区二区三区黄色| 久久久青草婷婷精品综合日韩| 99精品国产在热久久下载| 欧美高清影院| 久久频这里精品99香蕉| 国产欧美 在线欧美| 午夜在线一区| 9国产精品视频| 最新日韩精品| 欧美另类视频| 久久精品盗摄| 久久影音先锋| 欧美大片免费| 黄色国产精品一区二区三区| 老司机67194精品线观看| 亚洲毛片在线免费观看| 欧美亚日韩国产aⅴ精品中极品| 悠悠资源网久久精品| 欧美va亚洲va香蕉在线| 欧美日韩精品一区二区在线播放 | 久久综合激情| 亚洲国产精品一区二区久| 亚洲精品在线观看视频| 在线视频一区观看| 亚洲高清一区二区三区| 久久免费视频这里只有精品| 在线欧美三区| 一区二区电影免费观看| 久久夜色精品亚洲噜噜国产mv| 国产精品亚洲精品| 老司机凹凸av亚洲导航| 欧美视频在线看| 欧美成人午夜激情| 国产欧美一区二区三区沐欲| 亚洲欧美日韩另类| 欧美在线视频播放| 亚洲欧美日韩专区| 欧美精品成人91久久久久久久| 国产一区二区三区久久久久久久久 | 国产精品一区2区| 欧美专区一区二区三区| 在线综合亚洲| 国产精品高潮粉嫩av| 欧美.www| 亚洲午夜在线观看| 欧美福利影院| 一区三区视频| 亚洲黄色影片| 久久久久久91香蕉国产| 国产精品99久久99久久久二8| 免费一区二区三区| 久久精品夜色噜噜亚洲a∨| 国产日本亚洲高清| 国产精品激情偷乱一区二区∴| 午夜国产精品视频免费体验区| 亚洲天堂av图片| 亚洲精品在线二区| 欧美三区在线视频| 欧美成ee人免费视频| 久久丁香综合五月国产三级网站| 久久久青草青青国产亚洲免观| 欧美另类综合| 欧美日韩激情网| 国产视频一区在线观看一区免费 | 免费一区视频| 久久人人爽人人| 欧美在线视频播放| 国产一区二区精品在线观看| 欧美fxxxxxx另类| 久久久久九九视频| 一本久久综合亚洲鲁鲁| 一二三区精品| 国产精品久久久亚洲一区| 99爱精品视频| 欧美v国产在线一区二区三区| 日韩视频一区| 欧美成人一二三| 最新亚洲一区| 制服丝袜亚洲播放| 国产精品久久久久aaaa樱花 | 国产精品入口福利| 亚洲一区二区日本| 久久久人人人| 亚洲乱码一区二区| 国产精品九九久久久久久久| 亚洲综合色视频| 欧美成人精品一区| 亚洲午夜性刺激影院| 国产一区二区观看| 欧美h视频在线| 亚洲免费在线观看| 亚洲日本成人女熟在线观看| 欧美777四色影视在线| 亚洲毛片av在线| 久久综合色婷婷| 一区二区三区欧美亚洲| 亚洲色图在线视频| 激情综合色丁香一区二区| 欧美www在线| 亚洲免费视频在线观看| 久久综合激情| 亚洲色图自拍| 最新69国产成人精品视频免费| 亚洲欧美日韩一区| 日韩一级黄色大片| 国产欧美一区二区精品仙草咪| 亚洲免费观看| 久久频这里精品99香蕉| 亚洲一区二区在线播放| 怡红院精品视频在线观看极品| 亚洲欧美在线一区二区| 一本久久综合亚洲鲁鲁| 国产综合一区二区| 国产精品视频xxxx| 亚洲私拍自拍| 亚洲第一区在线观看| 性欧美大战久久久久久久免费观看| 欧美偷拍另类| 狂野欧美激情性xxxx| 欧美一站二站| 亚洲欧美国产视频| 亚洲欧美日韩国产中文| 亚洲精品在线观看免费|