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

VC++動態(tài)鏈接庫編程之MFC規(guī)則DLL

第4節(jié)我們對非MFC DLL進行了介紹,這一節(jié)將詳細(xì)地講述MFC規(guī)則DLL的創(chuàng)建與使用技巧。

  另外,自從本文開始連載后,收到了一些讀者的e-mail。有的讀者提出了一些問題,筆者將在本文的最后一次連載中選取其中的典型問題進行解答。由于時間的關(guān)系,對于讀者朋友的來信,筆者暫時不能一一回復(fù),還望海涵!由于筆者的水平有限,文中難免有錯誤和紕漏,也熱誠歡迎讀者朋友不吝指正!

  5. MFC規(guī)則DLL

  5.1 概述

  MFC規(guī)則DLL的概念體現(xiàn)在兩方面:

  (1) 它是MFC的
  
  “是MFC的”意味著可以在這種DLL的內(nèi)部使用MFC;

  (2) 它是規(guī)則的

  “是規(guī)則的”意味著它不同于MFC擴展DLL,在MFC規(guī)則DLL的內(nèi)部雖然可以使用MFC,但是其與應(yīng)用程序的接口不能是MFC。而MFC擴展DLL與應(yīng)用程序的接口可以是MFC,可以從MFC擴展DLL中導(dǎo)出一個MFC類的派生類。

  Regular DLL能夠被所有支持DLL技術(shù)的語言所編寫的應(yīng)用程序調(diào)用,當(dāng)然也包括使用MFC的應(yīng)用程序。在這種動態(tài)連接庫中,包含一個從CWinApp繼承下來的類,DllMain函數(shù)則由MFC自動提供。

  Regular DLL分為兩類:

  (1)靜態(tài)鏈接到MFC 的規(guī)則DLL

  靜態(tài)鏈接到MFC的規(guī)則DLL與MFC庫(包括MFC擴展 DLL)靜態(tài)鏈接,將MFC庫的代碼直接生成在.dll文件中。在調(diào)用這種DLL的接口時,MFC使用DLL的資源。因此,在靜態(tài)鏈接到MFC 的規(guī)則DLL中不需要進行模塊狀態(tài)的切換。

  使用這種方法生成的規(guī)則DLL其程序較大,也可能包含重復(fù)的代碼。

  (2)動態(tài)鏈接到MFC 的規(guī)則DLL

  動態(tài)鏈接到MFC 的規(guī)則DLL 可以和使用它的可執(zhí)行文件同時動態(tài)鏈接到 MFC DLL 和任何MFC擴展 DLL。在使用了MFC共享庫的時候,默認(rèn)情況下,MFC使用主應(yīng)用程序的資源句柄來加載資源模板。這樣,當(dāng)DLL和應(yīng)用程序中存在相同ID的資源時(即所謂的資源重復(fù)問題),系統(tǒng)可能不能獲得正確的資源。因此,對于共享MFC DLL的規(guī)則DLL,我們必須進行模塊切換以使得MFC能夠找到正確的資源模板。

  我們可以在Visual C++中設(shè)置MFC規(guī)則DLL是靜態(tài)鏈接到MFC DLL還是動態(tài)鏈接到MFC DLL。如圖8,依次選擇Visual C++的project -> Settings -> General菜單或選項,在Microsoft Foundation Classes中進行設(shè)置。


圖8 設(shè)置動態(tài)/靜態(tài)鏈接MFC DLL

  5.2 MFC規(guī)則DLL的創(chuàng)建

  我們來一步步講述使用MFC向?qū)?chuàng)建MFC規(guī)則DLL的過程,首先新建一個project,如圖9,選擇project的類型為MFC AppWizard(dll)。點擊OK進入如圖10所示的對話框。


圖9 MFC DLL工程的創(chuàng)建


圖10所示對話框中的1區(qū)選擇MFC DLL的類別。

  2區(qū)選擇是否支持automation(自動化)技術(shù), automation 允許用戶在一個應(yīng)用程序中操縱另外一個應(yīng)用程序或組件。例如,我們可以在應(yīng)用程序中利用 Microsoft Word 或Microsoft Excel的工具,而這種使用對用戶而言是透明的。自動化技術(shù)可以大大簡化和加快應(yīng)用程序的開發(fā)。

  3區(qū)選擇是否支持Windows Sockets,當(dāng)選擇此項目時,應(yīng)用程序能在 TCP/IP 網(wǎng)絡(luò)上進行通信。 CWinApp派生類的InitInstance成員函數(shù)會初始化通訊端的支持,同時工程中的StdAfx.h文件會自動include <AfxSock.h>頭文件。

  添加socket通訊支持后的InitInstance成員函數(shù)如下:

BOOL CRegularDllSocketApp::InitInstance()
{
 if (!AfxSocketInit())
 {
  AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
  return FALSE;
 }
 return TRUE;
}

  4區(qū)選擇是否由MFC向?qū)ё詣釉谠创a中添加注釋,一般我們選擇“Yes,please”。


圖10 MFC DLL的創(chuàng)建選項

5.3 一個簡單的MFC規(guī)則DLL

  這個DLL的例子(屬于靜態(tài)鏈接到MFC 的規(guī)則DLL)中提供了一個如圖11所示的對話框。


圖11 MFC規(guī)則DLL例子

  在DLL中添加對話框的方式與在MFC應(yīng)用程序中是一樣的。 在圖11所示DLL中的對話框的Hello按鈕上點擊時將MessageBox一個“Hello,pconline的網(wǎng)友”對話框,下面是相關(guān)的文件及源代碼,其中刪除了MFC向?qū)ё詣由傻慕^大多數(shù)注釋(下載本工程):

  第一組文件:CWinApp繼承類的聲明與實現(xiàn)

// RegularDll.h : main header file for the REGULARDLL DLL

#if !defined(AFX_REGULARDLL_H__3E9CB22B_588B_4388_B778_B3416ADB79B3__INCLUDED_)
#define AFX_REGULARDLL_H__3E9CB22B_588B_4388_B778_B3416ADB79B3__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifndef __AFXWIN_H__
#error include ’stdafx.h’ before including this file for PCH
#endif
#include "resource.h" // main symbols

class CRegularDllApp : public CWinApp
{
 public:
  CRegularDllApp();
  DECLARE_MESSAGE_MAP()
};

#endif

// RegularDll.cpp : Defines the initialization routines for the DLL.

#include "stdafx.h"
#include "RegularDll.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

BEGIN_MESSAGE_MAP(CRegularDllApp, CWinApp)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CRegularDllApp construction

CRegularDllApp::CRegularDllApp()
{
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CRegularDllApp object

CRegularDllApp theApp;

  分析:

  在這一組文件中定義了一個繼承自CWinApp的類CRegularDllApp,并同時定義了其的一個實例theApp。乍一看,您會以為它是一個MFC應(yīng)用程序,因為MFC應(yīng)用程序也包含這樣的在工程名后添加“App”組成類名的類(并繼承自CWinApp類),也定義了這個類的一個全局實例theApp。

  我們知道,在MFC應(yīng)用程序中CWinApp取代了SDK程序中WinMain的地位,SDK程序WinMain所完成的工作由CWinApp的三個函數(shù)完成:

virtual BOOL InitApplication( );

virtual BOOL InitInstance( );

virtual BOOL Run( ); //傳說中MFC程序的“活水源頭”

  但是MFC規(guī)則DLL并不是MFC應(yīng)用程序,它所繼承自CWinApp的類不包含消息循環(huán)。這是因為,MFC規(guī)則DLL不包含CWinApp::Run機制,主消息泵仍然由應(yīng)用程序擁有。如果DLL 生成無模式對話框或有自己的主框架窗口,則應(yīng)用程序的主消息泵必須調(diào)用從DLL 導(dǎo)出的函數(shù)來調(diào)用PreTranslateMessage成員函數(shù)。

  另外,MFC規(guī)則DLL與MFC 應(yīng)用程序中一樣,需要將所有 DLL中元素的初始化放到InitInstance 成員函數(shù)中。

  第二組文件 自定義對話框類聲明及實現(xiàn)

#if !defined(AFX_DLLDIALOG_H__CEA4C6AF_245D_48A6_B11A_A5521EAD7C4E__INCLUDED_)
#define AFX_DLLDIALOG_H__CEA4C6AF_245D_48A6_B11A_A5521EAD7C4E__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// DllDialog.h : header file
/////////////////////////////////////////////////////////////////////////////
// CDllDialog dialog

class CDllDialog : public CDialog
{
 // Construction
 public:
  CDllDialog(CWnd* pParent = NULL); // standard constructor
  enum { IDD = IDD_DLL_DIALOG };
 protected:
  virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
  // Implementation
 protected:
  afx_msg void OnHelloButton();
  DECLARE_MESSAGE_MAP()
};
#endif

// DllDialog.cpp : implementation file

#include "stdafx.h"
#include "RegularDll.h"
#include "DllDialog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDllDialog dialog

CDllDialog::CDllDialog(CWnd* pParent /*=NULL*/)
: CDialog(CDllDialog::IDD, pParent)
{}

void CDllDialog::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CDllDialog, CDialog)
 ON_BN_CLICKED(IDC_HELLO_BUTTON, OnHelloButton)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDllDialog message handlers

void CDllDialog::OnHelloButton()
{
 MessageBox("Hello,pconline的網(wǎng)友","pconline");
}

  分析:

  這一部分的編程與一般的應(yīng)用程序根本沒有什么不同,我們照樣可以利用MFC類向?qū)碜詣訛閷υ捒蛏系目丶砑邮录FC類向?qū)д諛訒深愃芆N_BN_CLICKED(IDC_HELLO_BUTTON, OnHelloButton)的消息映射宏。

  第三組文件 DLL中的資源文件

//{{NO_DEPENDENCIES}}

// Microsoft Developer Studio generated include file.

// Used by RegularDll.rc

//

#define IDD_DLL_DIALOG 1000

#define IDC_HELLO_BUTTON 1000

  分析:

  在MFC規(guī)則DLL中使用資源也與在MFC應(yīng)用程序中使用資源沒有什么不同,我們照樣可以用Visual C++的資源編輯工具進行資源的添加、刪除和屬性的更改。

  第四組文件 MFC規(guī)則DLL接口函數(shù)

#include "StdAfx.h"
#include "DllDialog.h"

extern "C" __declspec(dllexport) void ShowDlg(void)
{
 CDllDialog dllDialog;
 dllDialog.DoModal();
}

  分析:

  這個接口并不使用MFC,但是在其中卻可以調(diào)用MFC擴展類CdllDialog的函數(shù),這體現(xiàn)了“規(guī)則”的概類。

  與非MFC DLL完全相同,我們可以使用__declspec(dllexport)聲明或在.def中引出的方式導(dǎo)出MFC規(guī)則DLL中的接口。
5.4 MFC規(guī)則DLL的調(diào)用

  筆者編寫了如圖12的對話框MFC程序(下載本工程)來調(diào)用5.3節(jié)的MFC規(guī)則DLL,在這個程序的對話框上點擊“調(diào)用DLL”按鈕時彈出5.3節(jié)MFC規(guī)則DLL中的對話框。


圖12 MFC規(guī)則DLL的調(diào)用例子

  下面是“調(diào)用DLL”按鈕單擊事件的消息處理函數(shù):

void CRegularDllCallDlg::OnCalldllButton()
{
 typedef void (*lpFun)(void);
 HINSTANCE hDll; //DLL句柄
 hDll = LoadLibrary("RegularDll.dll");
 if (NULL==hDll)
 {
  MessageBox("DLL加載失敗");
 }

 lpFun addFun; //函數(shù)指針
 lpFun pShowDlg = (lpFun)GetProcAddress(hDll,"ShowDlg");
 if (NULL==pShowDlg)
 {
  MessageBox("DLL中函數(shù)尋找失敗");
 }
 pShowDlg();
}

  上述例子中給出的是顯示調(diào)用的方式,可以看出,其調(diào)用方式與第4節(jié)中非MFC DLL的調(diào)用方式?jīng)]有什么不同。

  我們照樣可以在EXE程序中隱式調(diào)用MFC規(guī)則DLL,只需要將DLL工程生成的.lib文件和.dll文件拷入當(dāng)前工程所在的目錄,并在RegularDllCallDlg.cpp文件(圖12所示對話框類的實現(xiàn)文件)的頂部添加:

#pragma comment(lib,"RegularDll.lib")
void ShowDlg(void);

  并將void CRegularDllCallDlg::OnCalldllButton() 改為:

void CRegularDllCallDlg::OnCalldllButton()
{
 ShowDlg();
}

  5.5 共享MFC DLL的規(guī)則DLL的模塊切換

  應(yīng)用程序進程本身及其調(diào)用的每個DLL模塊都具有一個全局唯一的HINSTANCE句柄,它們代表了DLL或EXE模塊在進程虛擬空間中的起始地址。進程本身的模塊句柄一般為0x400000,而DLL模塊的缺省句柄為0x10000000。如果程序同時加載了多個DLL,則每個DLL模塊都會有不同的HINSTANCE。應(yīng)用程序在加載DLL時對其進行了重定位。

  共享MFC DLL(或MFC擴展DLL)的規(guī)則DLL涉及到HINSTANCE句柄問題,HINSTANCE句柄對于加載資源特別重要。EXE和DLL都有其自己的資源,而且這些資源的ID可能重復(fù),應(yīng)用程序需要通過資源模塊的切換來找到正確的資源。如果應(yīng)用程序需要來自于DLL的資源,就應(yīng)將資源模塊句柄指定為DLL的模塊句柄;如果需要EXE文件中包含的資源,就應(yīng)將資源模塊句柄指定為EXE的模塊句柄。

  這次我們創(chuàng)建一個動態(tài)鏈接到MFC DLL的規(guī)則DLL(下載本工程),在其中包含如圖13的對話框。


圖13 DLL中的對話框

  另外,在與這個DLL相同的工作區(qū)中生成一個基于對話框的MFC程序,其對話框與圖12完全一樣。但是在此工程中我們另外添加了一個如圖14的對話框。


圖14 EXE中的對話框

  圖13和圖14中的對話框除了caption不同(以示區(qū)別)以外,其它的都相同。

  尤其值得特別注意,在DLL和EXE中我們對圖13和圖14的對話框使用了相同的資源ID=2000,在DLL和EXE工程的resource.h中分別有如下的宏:

//DLL中對話框的ID

#define IDD_DLL_DIALOG 2000

//EXE中對話框的ID

#define IDD_EXE_DIALOG 2000

  與5.3節(jié)靜態(tài)鏈接MFC DLL的規(guī)則DLL相同,我們還是在規(guī)則DLL中定義接口函數(shù)ShowDlg,原型如下:

#include "StdAfx.h"
#include "SharedDll.h"

void ShowDlg(void)
{
 CDialog dlg(IDD_DLL_DIALOG); //打開ID為2000的對話框
 dlg.DoModal();
}

  而為應(yīng)用工程主對話框的“調(diào)用DLL”的單擊事件添加如下消息處理函數(shù):

void CSharedDllCallDlg::OnCalldllButton()
{
 ShowDlg();
}

  我們以為單擊“調(diào)用DLL”會彈出如圖13所示DLL中的對話框,可是可怕的事情發(fā)生了,我們看到是圖14所示EXE中的對話框!
驚訝?

  產(chǎn)生這個問題的根源在于應(yīng)用程序與MFC規(guī)則DLL共享MFC DLL(或MFC擴展DLL)的程序總是默認(rèn)使用EXE的資源,我們必須進行資源模塊句柄的切換,其實現(xiàn)方法有三:

  方法一 在DLL接口函數(shù)中使用:

AFX_MANAGE_STATE(AfxGetStaticModuleState());

  我們將DLL中的接口函數(shù)ShowDlg改為:

void ShowDlg(void)
{
 //方法1:在函數(shù)開始處變更,在函數(shù)結(jié)束時恢復(fù)
 //將AFX_MANAGE_STATE(AfxGetStaticModuleState());作為接口函數(shù)的第一//條語句進行模塊狀態(tài)切換

 AFX_MANAGE_STATE(AfxGetStaticModuleState());
 CDialog dlg(IDD_DLL_DIALOG);//打開ID為2000的對話框
 dlg.DoModal();
}

  這次我們再點擊EXE程序中的“調(diào)用DLL”按鈕,彈出的是DLL中的如圖13的對話框!嘿嘿,彈出了正確的對話框資源。

  AfxGetStaticModuleState是一個函數(shù),其原型為:

AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState( );

  該函數(shù)的功能是在棧上(這意味著其作用域是局部的)創(chuàng)建一個AFX_MODULE_STATE類(模塊全局?jǐn)?shù)據(jù)也就是模塊狀態(tài))的實例,對其進行設(shè)置,并將其指針pModuleState返回。

  AFX_MODULE_STATE類的原型如下:

// AFX_MODULE_STATE (global data for a module)

class AFX_MODULE_STATE : public CNoTrackObject
{
 public:
  #ifdef _AFXDLL
   AFX_MODULE_STATE(BOOL bDLL, WNDPROC pfnAfxWndProc, DWORD dwVersion);
   AFX_MODULE_STATE(BOOL bDLL, WNDPROC pfnAfxWndProc, DWORD dwVersion,BOOL bSystem);
  #else
   AFX_MODULE_STATE(BOOL bDLL);
  #endif
  ~AFX_MODULE_STATE();

  CWinApp* m_pCurrentWinApp;
  HINSTANCE m_hCurrentInstanceHandle;
  HINSTANCE m_hCurrentResourceHandle;
  LPCTSTR m_lpszCurrentAppName;

  … //省略后面的部分
}

  AFX_MODULE_STATE類利用其構(gòu)造函數(shù)和析構(gòu)函數(shù)進行存儲模塊狀態(tài)現(xiàn)場及恢復(fù)現(xiàn)場的工作,類似匯編中call指令對pc指針和sp寄存器的保存與恢復(fù)、中斷服務(wù)程序的中斷現(xiàn)場壓棧與恢復(fù)以及操作系統(tǒng)線程調(diào)度的任務(wù)控制塊保存與恢復(fù)。

  許多看似不著邊際的知識點居然有驚人的相似!

  AFX_MANAGE_STATE是一個宏,其原型為:

AFX_MANAGE_STATE( AFX_MODULE_STATE* pModuleState )

  該宏用于將pModuleState設(shè)置為當(dāng)前的有效模塊狀態(tài)。當(dāng)離開該宏的作用域時(也就離開了pModuleState所指向棧上對象的作用域),先前的模塊狀態(tài)將由AFX_MODULE_STATE的析構(gòu)函數(shù)恢復(fù)。

  方法二 在DLL接口函數(shù)中使用:

AfxGetResourceHandle();

AfxSetResourceHandle(HINSTANCE xxx);

  AfxGetResourceHandle用于獲取當(dāng)前資源模塊句柄,而AfxSetResourceHandle則用于設(shè)置程序目前要使用的資源模塊句柄。

  我們將DLL中的接口函數(shù)ShowDlg改為:

void ShowDlg(void)
{
 //方法2的狀態(tài)變更
 HINSTANCE save_hInstance = AfxGetResourceHandle();
 AfxSetResourceHandle(theApp.m_hInstance);
 CDialog dlg(IDD_DLL_DIALOG);//打開ID為2000的對話框
 dlg.DoModal();

 //方法2的狀態(tài)還原
 AfxSetResourceHandle(save_hInstance);
}

  通過AfxGetResourceHandle和AfxSetResourceHandle的合理變更,我們能夠靈活地設(shè)置程序的資源模塊句柄,而方法一則只能在DLL接口函數(shù)退出的時候才會恢復(fù)模塊句柄。方法二則不同,如果將ShowDlg改為:

extern CSharedDllApp theApp; //需要聲明theApp外部全局變量

void ShowDlg(void)
{
 //方法2的狀態(tài)變更
 HINSTANCE save_hInstance = AfxGetResourceHandle();
 AfxSetResourceHandle(theApp.m_hInstance);

 CDialog dlg(IDD_DLL_DIALOG);//打開ID為2000的對話框
 dlg.DoModal();

 //方法2的狀態(tài)還原

 AfxSetResourceHandle(save_hInstance);

 //使用方法2后在此處再進行操作針對的將是應(yīng)用程序的資源

 CDialog dlg1(IDD_DLL_DIALOG); //打開ID為2000的對話框
 dlg1.DoModal();
}

  在應(yīng)用程序主對話框的“調(diào)用DLL”按鈕上點擊,將看到兩個對話框,相繼為DLL中的對話框(圖13)和EXE中的對話框(圖14)。

  方法三 由應(yīng)用程序自身切換

  資源模塊的切換除了可以由DLL接口函數(shù)完成以外,由應(yīng)用程序自身也能完成(下載本工程)。

  現(xiàn)在我們把DLL中的接口函數(shù)改為最簡單的:

void ShowDlg(void)
{
 CDialog dlg(IDD_DLL_DIALOG); //打開ID為2000的對話框
 dlg.DoModal();
}

  而將應(yīng)用程序的OnCalldllButton函數(shù)改為:

void CSharedDllCallDlg::OnCalldllButton()
{
 //方法3:由應(yīng)用程序本身進行狀態(tài)切換
 //獲取EXE模塊句柄

 HINSTANCE exe_hInstance = GetModuleHandle(NULL);

 //或者HINSTANCE exe_hInstance = AfxGetResourceHandle();
 //獲取DLL模塊句柄

 HINSTANCE dll_hInstance = GetModuleHandle("SharedDll.dll");
 AfxSetResourceHandle(dll_hInstance); //切換狀態(tài)
 ShowDlg(); //此時顯示的是DLL的對話框
 AfxSetResourceHandle(exe_hInstance); //恢復(fù)狀態(tài)

 //資源模塊恢復(fù)后再調(diào)用ShowDlg
 ShowDlg(); //此時顯示的是EXE的對話框
}

  方法三中的Win32函數(shù)GetModuleHandle可以根據(jù)DLL的文件名獲取DLL的模塊句柄。如果需要得到EXE模塊的句柄,則應(yīng)調(diào)用帶有Null參數(shù)的GetModuleHandle。

  方法三與方法二的不同在于方法三是在應(yīng)用程序中利用AfxGetResourceHandle和AfxSetResourceHandle進行資源模塊句柄切換的。同樣地,在應(yīng)用程序主對話框的“調(diào)用DLL”按鈕上點擊,也將看到兩個對話框,相繼為DLL中的對話框(圖13)和EXE中的對話框(圖14)。

  在下一節(jié)我們將對MFC擴展DLL進行詳細(xì)分析和實例講解,歡迎您繼續(xù)關(guān)注本系列連載。

posted on 2009-06-09 21:16 wrh 閱讀(273) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


導(dǎo)航

<2009年6月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

統(tǒng)計

常用鏈接

留言簿(19)

隨筆檔案

文章檔案

收藏夾

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            免费观看不卡av| 欧美成人久久| 国产美女搞久久| 国产精品高清在线| 国产精品国产三级国产aⅴ浪潮| 欧美区国产区| 欧美三区不卡| 国产日韩欧美在线观看| 国产亚洲在线观看| 亚洲成在人线av| 一本色道久久综合亚洲精品不 | 免费看成人av| 新片速递亚洲合集欧美合集| 亚洲成色www8888| 久久婷婷国产麻豆91天堂| 午夜精品一区二区三区四区 | 久久香蕉国产线看观看av| 亚洲精品乱码久久久久久按摩观 | 国产日韩欧美精品一区| 久久国产99| 欧美色图首页| 91久久精品久久国产性色也91| 国产在线视频欧美| 久久国产乱子精品免费女 | 美女视频黄免费的久久| 在线亚洲一区| 最新精品在线| 亚洲美女黄网| 欧美成人69av| 亚洲欧美日韩综合aⅴ视频| 亚洲国产精品尤物yw在线观看 | 亚洲图片你懂的| 欧美黄色视屏| 亚洲午夜电影网| 欧美主播一区二区三区| 亚洲在线免费观看| 性色av一区二区三区| 中文在线不卡视频| 日韩视频一区二区| 亚洲午夜久久久久久尤物| 久久成人精品一区二区三区| 亚洲人成亚洲人成在线观看图片 | 欧美a级片网站| 欧美高清在线视频| 欧美区一区二| 国产精品久久久久免费a∨大胸| 国产精品一二一区| 国产精品免费在线| 亚洲视频自拍偷拍| 亚洲精品国产拍免费91在线| 欧美va亚洲va国产综合| 亚洲午夜视频在线| 亚洲国产精彩中文乱码av在线播放| 亚洲一区二区黄| 欧美另类亚洲| 日韩午夜精品视频| 欧美 日韩 国产在线| 香蕉久久夜色| 国产伦精品一区二区三区视频黑人| 欧美巨乳波霸| 久久精品九九| 亚洲一区在线看| 欧美日韩精品一区二区三区| 亚洲国产一区二区在线| 久久这里只精品最新地址| 亚洲欧洲av一区二区三区久久| 欧美午夜无遮挡| 亚洲综合精品| 亚洲综合色婷婷| 国产亚洲一区二区三区在线观看| 亚洲一区二区在线播放| 亚洲午夜视频| 免费h精品视频在线播放| 亚洲风情亚aⅴ在线发布| 欧美 亚欧 日韩视频在线| 欧美成人资源| 亚洲一区二区三区成人在线视频精品| 一区电影在线观看| 国产伦精品一区二区三区视频黑人 | 夜夜嗨av色综合久久久综合网| 免费毛片一区二区三区久久久| 久久免费视频在线观看| 尤物yw午夜国产精品视频| 欧美大片专区| 欧美日韩一区二区视频在线观看| 欧美一二三区精品| 老司机一区二区三区| 一本久久综合| 欧美一区久久| 日韩亚洲精品在线| 亚洲免费视频中文字幕| 亚洲第一页自拍| 99在线观看免费视频精品观看| 国产欧美一区二区三区久久| 欧美国产日韩一区| 国产精品成人一区二区网站软件 | 亚洲欧美国内爽妇网| 亚洲电影免费观看高清| 99精品欧美| 在线看片一区| 亚洲一区二区毛片| 亚洲国产欧美一区二区三区丁香婷| 亚洲美女精品一区| 国模套图日韩精品一区二区| 亚洲欧洲久久| 黑人极品videos精品欧美裸| av成人激情| 亚洲激情欧美| 久久精品视频免费观看| 亚洲自拍都市欧美小说| 欧美一区二区私人影院日本| 欧美成人在线免费观看| 久久深夜福利| 国产精品美女| 日韩亚洲欧美综合| 亚洲欧洲日本一区二区三区| 久久国产婷婷国产香蕉| 午夜在线a亚洲v天堂网2018| 欧美区日韩区| 亚洲国产专区| 亚洲国产精品va在看黑人| 欧美中文字幕视频| 久久精品99无色码中文字幕| 国产精品裸体一区二区三区| 一本色道久久综合| 一区二区91| 欧美日韩国产小视频在线观看| 欧美成熟视频| 亚洲欧洲视频| 欧美精品日韩三级| 亚洲国产日韩欧美综合久久| 亚洲国产成人不卡| 久久伊人亚洲| 欧美国产一区二区在线观看 | 久久久久久夜精品精品免费| 亚洲影院一区| 欧美午夜无遮挡| 亚洲最黄网站| 亚洲欧美中文另类| 国产精品裸体一区二区三区| 亚洲视频一区在线观看| 亚洲一区二区3| 国产精品乱码一区二三区小蝌蚪 | 久久av二区| 国产日韩欧美视频| 欧美专区在线观看| 欧美a级理论片| 亚洲精品在线三区| 欧美四级在线观看| 亚洲欧美日本在线| 久久久久久夜| 亚洲三级视频| 欧美午夜宅男影院在线观看| 午夜精品在线| 欧美成人精品h版在线观看| 最新国产乱人伦偷精品免费网站| 美女国产一区| 一区二区欧美亚洲| 久久久久久综合网天天| 91久久久在线| 国产精品久久久久91| 欧美一区二区三区视频免费播放| 麻豆精品视频在线| 亚洲激情不卡| 国产精品久久久久久av福利软件| 午夜在线视频观看日韩17c| 欧美不卡视频| 亚洲欧美日韩一区在线| 在线不卡免费欧美| 欧美色中文字幕| 久久久久91| 亚洲视频在线观看免费| 欧美va亚洲va国产综合| 亚洲伊人伊色伊影伊综合网| 精品成人在线| 国产精品日韩久久久久| 美女诱惑一区| 午夜精品久久久久久久| 亚洲日本一区二区三区| 久久久久久久久岛国免费| 一本色道久久综合亚洲精品不| 国产亚洲精品bv在线观看| 欧美日韩国产首页在线观看| 久久米奇亚洲| 亚洲欧美国产另类| 99精品国产一区二区青青牛奶| 欧美另类69精品久久久久9999| 午夜欧美大片免费观看| 亚洲伦理自拍| 亚洲成人在线视频播放 | 欧美激情成人在线视频| 午夜电影亚洲| 夜夜爽av福利精品导航| 欧美激情成人在线视频| 久久精彩免费视频| 亚洲少妇一区| 亚洲欧洲日夜超级视频| 久久亚洲二区| 中文久久乱码一区二区| 在线视频观看日韩|