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

S.l.e!ep.¢%

像打了激速一樣,以四倍的速度運轉(zhuǎn),開心的工作
簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

關(guān)鍵字:COM MySpy IE SetUIHanlder IcustomDoc IDocHostUIHandler GetExternal

前言

作者在解決各種問題的時候喜歡首先使用C++ Builder來嘗試,這篇文章也是這樣,但這并不影響其他開發(fā)工具的使用者閱讀,因為這都是微軟的開發(fā)技術(shù),選擇什么工具并不重要,我們理解了他的原理可以使用任何工具實現(xiàn)同樣的功能。

正文

使用過VC.Net的朋友可能知道,在VC.Net中全新提供了一種基于Web的界面設(shè)計方法,不過可能真正用到的人很少,至少我在國內(nèi)的軟件中沒有看到過這樣的界面設(shè)計方法。當(dāng)初使用VC.net的時候就希望BCB的下個版本可以加入這樣靈活的界面設(shè)計方法,但是到現(xiàn)在還沒有等到,我想也不能一直這樣等下去,于是就自己研究其中的實現(xiàn)方法,終于讓我研究出來。這篇文章就是討論這樣方法,以及在軟件設(shè)計設(shè)計中的可行性。

說了這么多,可能還有朋友不知道這樣的界面到底有什么不同,有什么優(yōu)點呢?如果你也有同樣的好奇感的話,請你繼續(xù)看下去。

在Windows2000下,大家經(jīng)常使用控制面板/添加、卸載軟件的對話框就是基于這樣的界面(Xp下暫時不清楚),我不說出來可能很少有人知道-那個對話框整個就是個網(wǎng)頁?什么你不相信?如果是網(wǎng)頁為什么能和本地的計算機程序交互?為什么不能選擇網(wǎng)頁里面的文字?為什么不能彈出右鍵菜單?如果是網(wǎng)頁,那它的html代碼在那里?

為了證明上面的說法,我們需要一些特殊的軟件,這個軟件就是作者寫的MySpy,可以到作者的站點(http://siney.yeah.net)免費下載使用,我們可以從MySpy的界面中看到添加/刪除程序的對話框是個Internet Explorer_Server,這說明它是個網(wǎng)頁,


在MySpy的Web頁面還可以看到這個頁面的地址是:res://sp3res.dll/default.hta,

?


近一步使用MySpy得到這個網(wǎng)頁的代碼(不能直接右鍵獲取代碼),部分如下:

?


<HTML xmlns:ctls><HEAD><TITLE id=ARP>添加/刪除程序</TITLE>

<META http-equiv=Content-Type content="text/html; charset=gb2312"><BASE href=res://appwiz.cpl/><LINK href="arp.css" type=text/css rel=stylesheet>

<STYLE>>ctls\:PLACES { behavior: url(places.htc); }ctls\:LISTBOX { behavior: url(listbox.htc); }ctls\:ACCEL { behavior: url(accel.htc); }.PlacesBar {background-color:threedshadow}.Hide {display:none}.NonClientBackground { background-color: buttonface;}.Header { padding-bottom: 5px;vertical-align: text-top; }.GroupImage { margin-right: 5px;}.GroupDesc {padding-left: 1em;padding-right: 1em;}.AppNameRow {}.AppImageTD {width: 20px; padding: '4px 2px 2px 2px';}.InfoPane { padding-top:4px; vertical-align: top;}.PropLabel {width: 7em;padding-top: 2px;padding-bottom: 2px;padding-right: 3px;text-align: right;}.PropValue {width: 6em;text-align: right;padding-right: 7px;}.AddPropLabel {padding-top: 2px;padding-bottom: 2px;padding-right: 3px;text-align: right;}.AddPropValue {width: 13em;text-align: right;padding-right: 7px;}.ButtonDescPane { padding-top: 5px; padding-bottom: 7px;padding-right: 5px;}.ButtonPane { width: 15em; padding: 5px; text-align: right;}.FakeAnchor {cursor:hand;}#idClientCatName {font-weight: bold;padding-bottom: 1ex;}.disabled {color: graytext;}#idTblExtendedProps.Focus {color: highlighttext;}</STYLE>

?

?

嗬嗬,是不是很神奇呢,這只是一個應(yīng)用的例子,其實還有很多軟件的界面使用了上面的方法來創(chuàng)建界面,比如Norton AntiVirsu,MS Visual Studio.net,C# Builder等。其實深入仔細(xì)思考的話,這樣的界面最困難的是如何和本地代碼交互,為什么在網(wǎng)頁里點一個按鈕能執(zhí)行自己的代碼呢?有過COM編程經(jīng)驗的人,可能會想到用COM編寫一個外部對象,在網(wǎng)頁中使用腳本創(chuàng)建這個對象,然后調(diào)用對象的方法似乎可以完成這樣的功能?但是這里有很多不好的地方:

1. 需要注冊COM的本地運行安全,否則IE會有安全警告,這肯定是最終用戶不愿意看到的;

2. 用戶可以輕松從html代碼里獲得COM對象的使用方法(就像上面用MySpy獲得代碼一樣),這樣他們可以輕松使用你的COM對象完成他們自己的界面,這樣不夠隱蔽,不安全。

也許還有更多不好的地方,但暫時作者沒有想到,因為微軟及其他軟件公司都不是這樣做的,他們也許知道更多。下面我們就來討論一種既安全又隱蔽的實現(xiàn)方法。

從IE4開始,微軟提供了一個ICustomDoc接口,ICustomDoc的SetUIHandler允許用戶設(shè)置一個基于IDocHostUIHandler的接口來接管界面處理器,在IDocHostUIHandler提供了很多的虛擬方法,需要程序員來重載他們實現(xiàn)不同的定制功能,這里有一篇文章詳細(xì)介紹了這些信息http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/hosting/wbcustomization.asp,在這里我們需要重載GetExternal方法來擴(kuò)展IE DOM,如果我們成功的擴(kuò)展了DOM,那么我們就這可以這樣編寫html代碼來實現(xiàn)與本地程序交互,例如:

?

?


<html>

<head>

<SCRIPT language="JScript">

function MyFunc()

{

external.HelloWorld(); //HelloWorld是我們擴(kuò)展的方法

}

</SCRIPT>

</head>

<body>

<input type="Button" value="Show hello world" onClick="MyFunc();" />

</body>

</html>

?

HelloWorld就是我們擴(kuò)展的一個方法,當(dāng)點擊按鈕的時候external對象會調(diào)用HelloWorld方法調(diào)用本地代碼,對于external對象則會調(diào)用上面提到的GetExternal方法來查詢是否提供了擴(kuò)展,下面是如何實現(xiàn)GetExternal方法來實現(xiàn)擴(kuò)展external對象,代碼如下:

class MyDocHandler :public IDocHostUIHandler

{

long refcount;

public:

MyDocHandler() :refcount(1){ }

virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID classid, void** intf) {

if (classid == IID_IUnknown)

{

*intf = (IUnknown*)this;

AddRef();

}

else if (classid == IID_IDocHostUIHandler)

{

*intf = (IDocHostUIHandler*)this;

AddRef();

}

else if (classid == IID_IDispatch)

{

*intf = (IDispatch*)this;

AddRef();

}

else

return E_NOINTERFACE;

return S_OK;

}

virtual ULONG STDMETHODCALLTYPE AddRef() {

InterlockedIncrement(&refcount);

return refcount;

}

virtual ULONG STDMETHODCALLTYPE Release() {

InterlockedDecrement(&refcount);

if (refcount == 0)

delete this;

return refcount;

}

//返回S_OK,屏蔽掉右鍵菜單

virtual HRESULT STDMETHODCALLTYPE ShowContextMenu(

/* [in] */ DWORD dwID,

/* [in] */ POINT __RPC_FAR *ppt,

/* [in] */ IUnknown __RPC_FAR *pcmdtReserved,

/* [in] */ IDispatch __RPC_FAR *pdispReserved) {

return S_OK;

}

virtual HRESULT STDMETHODCALLTYPE GetHostInfo(

/* [out][in] */ DOCHOSTUIINFO __RPC_FAR *pInfo) {

return E_NOTIMPL;

}

virtual HRESULT STDMETHODCALLTYPE ShowUI(

/* [in] */ DWORD dwID,

/* [in] */ IOleInPlaceActiveObject __RPC_FAR *pActiveObject,

/* [in] */ IOleCommandTarget __RPC_FAR *pCommandTarget,

/* [in] */ IOleInPlaceFrame __RPC_FAR *pFrame,

/* [in] */ IOleInPlaceUIWindow __RPC_FAR *pDoc) {

return E_NOTIMPL;

}

virtual HRESULT STDMETHODCALLTYPE HideUI( void) {

return E_NOTIMPL;

}

virtual HRESULT STDMETHODCALLTYPE UpdateUI( void) {

return E_NOTIMPL;

}

virtual HRESULT STDMETHODCALLTYPE EnableModeless(

/* [in] */ BOOL fEnable) {

return E_NOTIMPL;

}

virtual HRESULT STDMETHODCALLTYPE OnDocWindowActivate(

/* [in] */ BOOL fActivate) {

return E_NOTIMPL;

}

virtual HRESULT STDMETHODCALLTYPE OnFrameWindowActivate(

/* [in] */ BOOL fActivate) {

return E_NOTIMPL;

}

virtual HRESULT STDMETHODCALLTYPE ResizeBorder(

/* [in] */ LPCRECT prcBorder,

/* [in] */ IOleInPlaceUIWindow __RPC_FAR *pUIWindow,

/* [in] */ BOOL fRameWindow) {

return E_NOTIMPL;

}

virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator(

/* [in] */ LPMSG lpMsg,

/* [in] */ const GUID __RPC_FAR *pguidCmdGroup,

/* [in] */ DWORD nCmdID) {

return E_NOTIMPL;

}

virtual HRESULT STDMETHODCALLTYPE GetOptionKeyPath(

/* [out] */ LPOLESTR __RPC_FAR *pchKey,

/* [in] */ DWORD dw) {

return E_NOTIMPL;

}

virtual HRESULT STDMETHODCALLTYPE GetDropTarget(

/* [in] */ IDropTarget __RPC_FAR *pDropTarget,

/* [out] */ IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget) {

return E_NOTIMPL;

}

virtual HRESULT STDMETHODCALLTYPE GetExternal(

/* [out] */ IDispatch __RPC_FAR *__RPC_FAR *ppDispatch) {

*ppDispatch = new MyCommandHandler();

return S_OK;

}

virtual HRESULT STDMETHODCALLTYPE TranslateUrl(

/* [in] */ DWORD dwTranslate,

/* [in] */ OLECHAR __RPC_FAR *pchURLIn,

/* [out] */ OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut) {

return E_NOTIMPL;

}

virtual HRESULT STDMETHODCALLTYPE FilterDataObject(

/* [in] */ IDataObject __RPC_FAR *pDO,

/* [out] */ IDataObject __RPC_FAR *__RPC_FAR *ppDORet) {

return E_NOTIMPL;

}

};


上面重載了ShowContextMenu方法屏蔽掉右鍵菜單,使用戶不能得到網(wǎng)頁代碼,關(guān)于GetExternal是這樣實現(xiàn)的:

virtual HRESULT STDMETHODCALLTYPE GetExternal(

/* [out] */ IDispatch __RPC_FAR *__RPC_FAR *ppDispatch) {

*ppDispatch = new MyCommandHandler();

return S_OK;

}


可以看到只是簡單返回了MyCommandHandler對象,MyCommandHandler必須繼承自IDispatch接口來實現(xiàn)支持自動化的調(diào)用方式,它是這樣實現(xiàn)的:

class MyCommandHandler : public IDispatch

{

long refcount;

public:

MyCommandHandler() :refcount(1){ }

virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(

/* [out] */ UINT *pctinfo){

return S_OK;

}

virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(

/* [in] */ UINT iTInfo,

/* [in] */ LCID lcid,

/* [out] */ ITypeInfo **ppTInfo){

return S_OK;

}

virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(

/* [in] */ REFIID riid,

/* [size_is][in] */ LPOLESTR *rgszNames,

/* [in] */ UINT cNames,

/* [in] */ LCID lcid,

/* [size_is][out] */ DISPID *rgDispId){

*rgDispId=1;

return S_OK;

}

virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke(

/* [in] */ DISPID dispIdMember,

/* [in] */ REFIID riid,

/* [in] */ LCID lcid,

/* [in] */ WORD wFlags,

/* [out][in] */ DISPPARAMS *pDispParams,

/* [out] */ VARIANT *pVarResult,

/* [out] */ EXCEPINFO *pExcepInfo,

/* [out] */ UINT *puArgErr){

if(dispIdMember==1)

{

MessageBox(0,"Hello World","Hello",0); //place your code here

frmweb->Edit1->Text="Hello World(這也可以?)";

}

return S_OK;

}

virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID classid, void** intf) {

if (classid == IID_IDispatch)

{

*intf = (IDispatch*)this;

AddRef();

}

else

return E_NOINTERFACE;

return S_OK;

}

virtual ULONG STDMETHODCALLTYPE AddRef() {

InterlockedIncrement(&refcount);

return refcount;

}

virtual ULONG STDMETHODCALLTYPE Release() {

InterlockedDecrement(&refcount);

if (refcount == 0)

delete this;

return refcount;

}

};


如果大家了解一些COM知識,我們知道這里關(guān)鍵的是GetIDsOfNames和Invoke方法的實現(xiàn),因為自動化對象只能通過這樣的方式來調(diào)用,而不能使用函數(shù)指針直接調(diào)用虛擬方法,GetIDsOfNames查詢指定的函數(shù)名的調(diào)用ID,就是說如果有一個方法是“HelloWorld”,那么它會先調(diào)用GetIDsOfNames方法來查詢這個方法是否支持,如果支持則給出該方法的調(diào)用ID(通過修改rgDispId[out]參數(shù)),如果不支持則返回E_NOTIMPL,他的實現(xiàn)簡單如下:

virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(

/* [in] */ REFIID riid,

/* [size_is][in] */ LPOLESTR *rgszNames,

/* [in] */ UINT cNames,

/* [in] */ LCID lcid,

/* [size_is][out] */ DISPID *rgDispId){

*rgDispId=1;

return S_OK;

}


這里我們假定了只有一個擴(kuò)展函數(shù)HelloWorld,如果有多個,我們需要比較rgszNames參數(shù)的函數(shù)名返回不同的調(diào)用ID,有了調(diào)用ID,實現(xiàn)Invoke方法就很簡單了:

virtual HRESULT STDMETHODCALLTYPE Invoke(

/* [in] */ DISPID dispIdMember,

/* [in] */ REFIID riid,

/* [in] */ LCID lcid,

/* [in] */ WORD wFlags,

/* [out][in] */ DISPPARAMS *pDispParams,

/* [out] */ VARIANT *pVarResult,

/* [out] */ EXCEPINFO *pExcepInfo,

/* [out] */ UINT *puArgErr){

if(dispIdMember==1)

{

MessageBox(0,"Hello World","Hello",0); //place your code here

frmweb->Edit1->Text="Hello World(這也可以?)";

}

return S_OK;

}


根據(jù)dispIdMember的不同實現(xiàn)不同的代碼,如果方法是有參數(shù)的可以在pDispParams中取得,如果有什么不明白可以參考MSDN和一些COM的書籍,這里就不詳細(xì)解釋了。

最后我們要做的就是使我們的瀏覽器知道我們擴(kuò)展了external,代碼如下:

dochandler = new MyDocHandler;

webBrowser->Navigate(WideString(L"E:\\Projects\\extWeb\\ext.htm"));

while(webBrowser->Busy)

Application->ProcessMessages();

ICustomDoc *custdoc;

webBrowser->Document->QueryInterface(&custdoc); //取得IcustomDoc接口

if (custdoc)

{

custdoc->SetUIHandler(dochandler); //設(shè)置我們自己的界面處理器

custdoc->Release();

}


注意上面的粗體“我們的瀏覽器”,因為這樣的擴(kuò)展僅針對與自己程序里使用WebBrowser控件,不影響IE本身的擴(kuò)展,也就是說那個ext.htm文件只能在我們的程序中有效,就算其他用戶得到了這段htm代碼也不能正常運行的,如果你想測試,你得到的是:


因為他們并不知道如何擴(kuò)展external對象,這點就解決了剛才我們說的使用COM的問題。

說句實話設(shè)計這樣界面還是有一定難度的,那么它在實際開發(fā)中到底有什么好處呢?我想至少有以下幾點:

1. 界面設(shè)計和程序邏輯設(shè)計分離,美工可以和程序員一起工作,界面設(shè)計再也不是沒有審美細(xì)胞程序員的問題;

2. 輕松實現(xiàn)Skin功能,界面的改變不需要重新編譯代碼,只需要換一個不同htm代碼文件就可以;

3. 再也無法使用Spy工具獲得窗體Handler做各種Hook,使你的程序運行的更安全;

4. 充分使用IE現(xiàn)有技術(shù),搭建功能更強大的軟件;

5. 使你的軟件看起來更酷,更專業(yè)。

怎么樣?心動了嗎?趕快改善你的界面吧。

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            99爱精品视频| 夜夜嗨av一区二区三区网站四季av| 亚洲欧美激情一区| 中文av字幕一区| 国产欧美日韩亚洲精品| 欧美在线黄色| 久久一区二区三区av| 亚洲毛片一区| 亚洲一区二区三区欧美| 国产一区二区日韩精品欧美精品 | 久久久久久久久久久久久女国产乱| 欧美色欧美亚洲高清在线视频| 午夜在线视频一区二区区别| 欧美一区二区啪啪| 亚洲青色在线| 亚洲欧美在线看| 亚洲激情图片小说视频| 久久久欧美一区二区| 久久人人爽人人爽爽久久| 亚洲精品日韩精品| 一二三区精品| 影音先锋一区| 一区二区三区四区蜜桃| 黄色成人在线免费| aaa亚洲精品一二三区| 国产一区二区视频在线观看| 亚洲欧洲精品一区二区三区不卡 | 亚洲国产裸拍裸体视频在线观看乱了中文 | 日韩一区二区精品视频| 国产精品久久网站| 亚洲高清不卡| 激情成人亚洲| 国产精品99久久久久久人| 亚洲国产精品一区二区尤物区| 亚洲激情网站| 激情91久久| 午夜精品久久久久99热蜜桃导演| 亚洲精品国产精品国自产观看浪潮 | 久久精品五月婷婷| 99re6热只有精品免费观看| 亚洲一区二区免费看| 日韩视频免费在线观看| 久久久久久久久一区二区| 午夜精品视频在线| 欧美日韩精品伦理作品在线免费观看| 久久精品国产一区二区三区免费看 | 国外视频精品毛片| 亚洲视频免费看| 亚洲精品色婷婷福利天堂| 久久久久国产精品厨房| 午夜精品免费| 国产精品日韩一区二区三区| 亚洲精品亚洲人成人网| 亚洲日本在线观看| 欧美chengren| 亚洲第一页自拍| 亚洲国产欧美一区二区三区久久 | 亚洲国产福利在线| 国产在线拍偷自揄拍精品| 销魂美女一区二区三区视频在线| 亚洲淫性视频| 国产精品香蕉在线观看| 亚洲一区欧美激情| 欧美一区二区三区视频| 国产精品久久77777| 美女诱惑黄网站一区| 国产精品色婷婷久久58| 夜夜爽夜夜爽精品视频| 一区二区三区国产盗摄| 欧美精品一区二区三区很污很色的 | 亚洲欧美一区二区三区在线 | 欧美激情五月| 日韩视频精品| 午夜激情综合网| 国产一区二区三区视频在线观看 | 久久综合中文| 国内外成人在线| 久久手机精品视频| 亚洲大胆美女视频| 一本综合精品| 国产欧美日本一区二区三区| 久久久久久69| 亚洲国产欧美不卡在线观看| 亚洲视频成人| 国产精品一区二区女厕厕| 欧美一区二区三区视频免费| 欧美大片在线看| 99精品视频免费全部在线| 国产精品久久久久毛片大屁完整版| 午夜日韩在线| 亚洲成人资源网| 亚洲欧美伊人| 亚洲二区在线观看| 国产精品久久久久国产a级| 久久国产免费看| 亚洲精品美女久久久久| 欧美一级在线视频| 亚洲精品护士| 国产一区二区三区久久 | 一本大道久久a久久精二百| 亚洲午夜视频| 怡红院精品视频| 欧美网站在线观看| 六月婷婷久久| 午夜电影亚洲| 亚洲精品一区二| 久久久久99| 亚洲一区二区三区在线看| 激情综合在线| 国产精品久久久久久久久久直播 | 一本色道久久综合亚洲精品婷婷| 欧美一区二区三区啪啪| 一区二区三区高清视频在线观看| 国内精品久久久久久久果冻传媒 | 香蕉免费一区二区三区在线观看 | 亚洲天堂成人| 亚洲国产一区二区三区青草影视 | 欧美精品色综合| 亚洲一级在线观看| 亚洲破处大片| 免费成人在线观看视频| 欧美一区影院| 亚洲一区二区综合| 亚洲麻豆av| 亚洲精品自在在线观看| 精品成人一区| 国产午夜精品美女视频明星a级 | 亚洲一区影院| 日韩一级免费| 亚洲日本一区二区三区| 欧美岛国激情| 美女精品在线| 老司机午夜精品视频在线观看| 欧美亚洲一区二区在线| 亚洲婷婷综合色高清在线| 日韩视频免费| 99在线热播精品免费| 亚洲人久久久| 亚洲伦理在线观看| 99国产精品99久久久久久| 亚洲日本免费| 一区二区三区国产精华| 亚洲色无码播放| 亚洲欧美一区二区视频| 欧美一区二区精品| 久久精品国产一区二区三| 久久久久综合网| 蜜臀久久99精品久久久画质超高清| 久久久噜噜噜久久人人看| 久久蜜桃香蕉精品一区二区三区| 久久全国免费视频| 欧美激情精品久久久久久黑人 | 一二三区精品福利视频| 亚洲日本va午夜在线电影| 日韩午夜激情av| 亚洲欧美激情视频在线观看一区二区三区| 亚洲视频一区| 欧美在线视屏| 欧美sm极限捆绑bd| 亚洲三级影片| 亚洲一二三区在线| 久久se精品一区精品二区| 久久久蜜臀国产一区二区| 欧美另类女人| 国产伦精品一区二区三区四区免费| 国产午夜精品久久久久久免费视| 红杏aⅴ成人免费视频| 91久久精品国产91久久性色| 中文亚洲视频在线| 久久人人精品| 99www免费人成精品| 亚洲欧美日本国产有色| 久久综合伊人77777麻豆| 欧美日韩一区二区欧美激情| 国产精品一国产精品k频道56| 在线观看一区| 西西人体一区二区| 亚洲第一区在线观看| 亚洲女同同性videoxma| 乱码第一页成人| 国产伦精品一区二区三区在线观看| 亚洲激情一区二区| 亚洲欧美综合v| 亚洲黄色成人网| 欧美在线视频免费| 欧美日韩1区| 亚洲高清不卡av| 久久www成人_看片免费不卡| 欧美激情视频网站| 久久高清一区| 国产精品久久久久久福利一牛影视| 亚洲激情在线| 久久综合色婷婷| 在线免费观看视频一区| 久久国产精品久久国产精品| 正在播放欧美视频| 欧美影片第一页| 欧美国内亚洲| 久久精品在线免费观看| 欧美三级韩国三级日本三斤|