国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開(kāi)通VIP
讓你的VC也支持手勢(shì)----【手勢(shì)扒手】制作過(guò)程下-gangyilovevc的專欄...
 讓你的VC也支持手勢(shì)----【手勢(shì)扒手】制作過(guò)程 下
 
接上篇,好,我們繼續(xù),在剩下的文字中,(還是有點(diǎn)長(zhǎng),就不在分了)我們重點(diǎn)剖析下插件主要部分的設(shè)計(jì)思想和實(shí)現(xiàn),對(duì)其做個(gè)簡(jiǎn)單總結(jié)。
前面說(shuō)過(guò),插件采用VC的add-in實(shí)現(xiàn),他是一個(gè)基于ATL/COM的組件應(yīng)用程序,如果不了解ATL/com的也無(wú)所謂(了解當(dāng)然更好啦。。),因?yàn)樯婕暗剿麄儢|西很少,它最重要的地方就是提供了一個(gè)框架殼子,而且此框架也不必深究,都交給IDE來(lái)處理,我們更多還是用MFC,這個(gè)應(yīng)該熟悉把,最起碼也應(yīng)該會(huì)用把,如果不會(huì)。。。。。,厄,那也能看懂,因?yàn)槲覀冎攸c(diǎn)說(shuō)思想,不涉及具體的代碼,當(dāng)然示例性代碼還是有的,嘿嘿。
新建一工程,命名為MouseGesture,向?qū)нx擇DevStudio Add-in Wizard,單擊OK,來(lái)到add-in向?qū)У谝徊?,我們插件也提供一個(gè)工具欄,可以保持默認(rèn),單擊完成,這時(shí)具有擴(kuò)展IDE開(kāi)發(fā)環(huán)境的插件已經(jīng)建好了,編譯成功后,通過(guò) Tools—Customize---Andin and Macro Files標(biāo)簽頁(yè)將我們的插件添加道IDE中,成功后應(yīng)該在IDE中顯示一個(gè)新的工具欄,后續(xù)工作我們都以此工程為基礎(chǔ)實(shí)現(xiàn)我們自己的插件。
現(xiàn)在就讓我們一步步把程序核心關(guān)鍵地方一一講解,當(dāng)你看完時(shí),也許你會(huì)這么想,“就這么簡(jiǎn)單啊,我也來(lái)做一個(gè)。。。”
開(kāi)始啦~~~~~~!
1.  既然是手勢(shì),鼠標(biāo)相關(guān)的信息我們得知道把,這里我們通過(guò)鼠標(biāo)鉤子來(lái)實(shí)現(xiàn),分別在插件初始化和卸載時(shí)實(shí)現(xiàn)鉤子的掛鉤及脫鉤。代碼簡(jiǎn)單的連注釋都省了。如下。
 
//掛鉤
CDSAddIn::OnConnection()
{   
      ………….
   g_hook = SetWindowsHookEx(WH_MOUSE,&MouseProc,NULL,GetCurrentThreadId());
}
//脫鉤
CDSAddIn::OnDisconnection()
{
      …………………..
      UnhookWindowsHookEx(g_hook);
}
2.  鼠標(biāo)的消息我們已經(jīng)可以拿到了,先讓我們把鼠標(biāo)消息轉(zhuǎn)換成屏幕上的線把,只要完成這一步手勢(shì)看著就有點(diǎn)樣子。
程序中我們實(shí)現(xiàn)了一個(gè)類CMouseEx,由他來(lái)實(shí)現(xiàn)所有功能,先看下他的聲明,后面用的到。
class CMouseEx 
{
      ………………..
//程序本身提供的功能
      void CloseCur(); //關(guān)閉當(dāng)前窗口,
      //加速鍵相關(guān)
      //WM_COMMND相關(guān)
      ……………………
}
關(guān)于用鼠標(biāo)劃線的功能,想必大家都不陌生,無(wú)非是記住鼠標(biāo)當(dāng)前位置(我們已經(jīng)下鉤了),然后MoveTo、LinetTo之類的,這些就不在說(shuō)了,這里著重要說(shuō)的是在那個(gè)DC上作畫?DC有沒(méi)有裁剪?由于我們程序是一個(gè)輔助的劃線工具,不可能讓線畫到整個(gè)IDE環(huán)境,比方說(shuō)菜單、工具欄、類視圖等這些地方是不允許劃線的,要不太亂了,而且平時(shí)我們大多也在代碼編輯地方待的時(shí)間最長(zhǎng),所以這里應(yīng)該是理想手勢(shì)執(zhí)行區(qū)。所以呢, DC我們采用屏幕DC,屏幕DC對(duì)我們來(lái)說(shuō)已經(jīng)夠用了,操作范圍以代碼編輯區(qū)為界限。
決定了使用屏幕DC,和操作DC范圍,看看如何得到他把,得到屏幕DC應(yīng)該很簡(jiǎn)單的,如下。
if (!m_pWindowDC)
{
m_pWindowDC = new CWindowDC(CWnd::FromHandle(GetDesktopWindow()));
}
  以后操作都針對(duì)此DC,由于此DC可以操作到整個(gè)屏幕,剛才我們也說(shuō)過(guò)應(yīng)該將范圍限制在代碼編輯區(qū)中,所以呢給此DC加個(gè)裁剪,這個(gè)怎么做呢?
代碼編輯區(qū)其實(shí)也是一個(gè)窗口,具體窗口的屬性大家可以通過(guò)spy++看看,由此知道他其實(shí)是一個(gè)類名為MDIClient的窗口,已打開(kāi)的文件是他的子窗口。那現(xiàn)在就很明顯了,得到這個(gè)MDIClient窗口句柄,在得到他的RECT,然后在以此RECT對(duì)DC做裁剪,這樣就把操作限制在代碼編輯區(qū)了。
  MDIClient窗口同時(shí)有是IDE的一個(gè)子窗口,顯然我們要先得到IDE的窗口句柄,然后遍歷其子窗口,在查找類名為MDIClient的窗口即可。
好,繼續(xù)看代碼。
//尋找IDE 句柄 原理就是IDE的父窗口為NULL
      HWND hWnd, hDesktopWnd;
      hWnd = ::GetActiveWindow();
      hDesktopWnd = ::GetDesktopWindow();
      while (hWnd  &&  hWnd != hDesktopWnd)
    {
        m_hDevStudioWnd = hWnd;
        hWnd = ::GetParent(hWnd);
    }
     CWnd *pDevStudioWnd = CWnd::FromHandle(m_hDevStudioWnd);
 
      //找到IDE句柄了在根據(jù)類名查找MDIClient子窗口
      char szClassName[256];
     
      m_hMDIWnd = pDevStudioWnd->GetTopWindow()->m_hWnd;
   ::GetClassName(m_hMDIWnd, (LPTSTR)szClassName, sizeof(szClassName));
      while (strcmp(szClassName, "MDIClient") != 0)
      {
               m_hMDIWnd = ::GetNextWindow(m_hMDIWnd, GW_HWNDNEXT);
               ::GetClassName(m_hMDIWnd, (LPTSTR)szClassName, sizeof(szClassName));
        }
    //給DC加裁剪
CRgn rgn;
rgn.CreateRectRgnIndirect(&rcClient);           
m_pWindowDC->SelectClipRgn(&rgn);
到這里時(shí),DC和裁剪都有了,在加上劃線功能,恩,有點(diǎn)手勢(shì)味道了,我們劃線采用Polyline方式,因?yàn)槲覀兪謩?shì)還有tip顯示功能,如果用Move\Line畫線的話,Tip窗口可能將我們劃的線給擦掉,簡(jiǎn)單期間我們直接使用Polyline方式,讓他每次都重新畫一邊。
3.  鼠標(biāo)消息、劃線功能都有了,現(xiàn)在應(yīng)該說(shuō)手勢(shì)命令識(shí)別了,怎樣識(shí)別手勢(shì)呢?起初我也想復(fù)雜了,當(dāng)時(shí)是想到了文字的識(shí)別?那肯定是很復(fù)雜的,但其實(shí)那些我們用不到,我們用到的只是記錄鼠標(biāo)移動(dòng)過(guò)的軌跡,并辨別它,比如說(shuō)RD、LD之類的,(U -上,D-下,L-左,R-右)核心代碼也是從網(wǎng)上摘錄的,代碼很簡(jiǎn)單也很經(jīng)典,直接看代碼吧。
//生成手勢(shì)命令
BOOL CMouseEx::MakeMouseGestureCommnd( CPoint pt )
{
     int x = pt.x - m_ptGenerateCur.x;   
     int y = pt.y - m_ptGenerateCur.y;   
     int dist = x*x+y*y;
    
     if(dist>64)                  
     {       
              if(x>abs(y) && x>0)
              {// R
              }
              else if(abs(x)>abs(y) && x<0)
              {// L
              }
              else if(y>abs(x) && y>0)
              {//D 
              }
              else if(abs(y)>abs(x) && y<0)
              {// U
              }
              else return FALSE;   
              return TRUE;            
     }       
     else          return FALSE;  
}
         沒(méi)騙你把,很簡(jiǎn)單不是。
4.  現(xiàn)在應(yīng)該到了具體的功能了,程序支持三種手勢(shì)功能分別是本身實(shí)現(xiàn)的、通過(guò)快捷鍵的、發(fā)送WM_COMMND的,下面一一介紹。
a)  程序本身的功能
在這個(gè)模塊可以實(shí)現(xiàn)一些自己特有功能(總不能老拿別人的把),或者對(duì)某個(gè)功能擴(kuò)充,好處嗎?自然很明顯,舉個(gè)簡(jiǎn)單例子,對(duì)話框應(yīng)用程序中,往往是在OnInitDialog中對(duì)一些控件變量初始化,然后在OnOK中把其值的在拿回來(lái),類似如下這樣。
CInfo m_info;//舉例 一個(gè)類,屬性對(duì)應(yīng)dlg每個(gè)控件
OnInitDialog()
{//edit 控件
     m_EditName = m_info.m_csName;
     m_EditAge = m_info.m_csAge;
     m_EditSex = m_info.m_csSex;
  …… //假設(shè)有很多edit控件需要賦值
 
}
OnOK()
{//點(diǎn)擊確定后,要拿到最新值,怎么做呢?反正我是這樣做的,上面代碼拷貝過(guò)來(lái),一個(gè)一個(gè)在修改,也就是修改下等號(hào)位置,但往往這些賦值操作很多,讓我改的很痛苦。。。。
m_info.m_csName = m_EditName;
m_info.m_csAge= m_ EditAge;
m_info.m_ csSex = m_EditSex ;
………//很多
}
如果我將這個(gè)手工操作改為用代碼來(lái)實(shí)現(xiàn),并且通過(guò)手勢(shì)來(lái)觸發(fā),以后在遇到此類問(wèn)題,我首先選中一段代碼,然后鼠標(biāo)一畫便實(shí)現(xiàn)反向賦值,很爽不是嗎?
恩,這個(gè)是挺好,原有的一個(gè)一個(gè)改確實(shí)很煩,但。。。這個(gè)功能我卻沒(méi)有實(shí)現(xiàn),到不是復(fù)雜,關(guān)鍵是類似這樣問(wèn)題太多了。。。。
現(xiàn)在插件本身的功能,沒(méi)有一個(gè)是自己實(shí)現(xiàn)的,都只使用了接口IApplication本身的幾個(gè)方法,實(shí)現(xiàn)了幾個(gè)功能?主要還是‘偷‘現(xiàn)有功能。呵呵。
b)  快捷鍵
之前我的想法是,可以把所有的快捷鍵都轉(zhuǎn)換成手勢(shì),都可以用手勢(shì)來(lái)觸發(fā),但那畢竟只是一個(gè)想法而已,在真正實(shí)現(xiàn)的時(shí)候,發(fā)現(xiàn)了一個(gè)讓人極度不爽的事情,那就是對(duì)快捷鍵有個(gè)特殊要求,必須帶ALT 否則不起作用,觸發(fā)快捷鍵我采用keybd_event/ SendInput方式,但發(fā)現(xiàn)如果不帶ALT的話,就相應(yīng)應(yīng)不了,原因還不太確定?所以不便多說(shuō),如果有知道的朋友,請(qǐng)告訴我。
不過(guò)那并不代表我們就沒(méi)有辦法了,可以把我們頻繁用到的功能(主要針對(duì)IDE),重新給他指定一個(gè)帶ALT的快捷鍵,在 Tools—Customize---Keyboard中設(shè)置,然后將此快捷鍵添加到配置中,我么可以一樣用。呵呵,條條大路通羅馬。
c)  WM_COMMND
如果不愿意重新設(shè)置快捷鍵、或者某個(gè)功能在Keyboard沒(méi)有、在或者需要‘偷‘某插件功能以及其他?那怎么辦?這是就用到了發(fā)送消息方法了, 理論上所有基于發(fā)送WM_COMMND實(shí)現(xiàn)的功能我們都能夠‘偷’過(guò)來(lái),因?yàn)楸旧砭褪前l(fā)送了一個(gè)WM_COMMND消息而已。WM_COMMND詳細(xì)介紹請(qǐng)參見(jiàn)MSDN,這里簡(jiǎn)單說(shuō)明一下我們的使用原理,基于菜單、加速鍵的功能都是通過(guò)發(fā)送WM_COMMND來(lái)實(shí)現(xiàn)的,
HIWORD(wParam) 1 來(lái)自己菜單 0 來(lái)自加速鍵
LOWORD(wParam) 控件標(biāo)示ID。
其實(shí)這個(gè)功能實(shí)現(xiàn)起來(lái)是最簡(jiǎn)單的,就是發(fā)送一個(gè)WM_COMMND消息,但他功能也是最強(qiáng)的,等等。。。。??丶?biāo)示ID怎么得到,單擊一個(gè)菜單項(xiàng),或者一個(gè)加速鍵我怎么知道他的標(biāo)示ID,你如果能想到這點(diǎn),證明你是一個(gè)心思縝密的人,沒(méi)想到的證明你是一個(gè)做大事的人。嘿嘿。。。。
不錯(cuò),我們還沒(méi)有得到這個(gè)ID?沒(méi)有這個(gè)ID我們的消息也沒(méi)有辦法發(fā)啊?怎么拿呢?應(yīng)該有更好的辦法把,反正我沒(méi)用,也沒(méi)具體想,我只是拿出了SPY++,監(jiān)視IDE消息,因?yàn)闆](méi)有用的消息太多,為了不影響輸出,我只過(guò)濾了WM_COMMND消息,然后在IDE中操作一下我將要‘偷’的功能,完畢后,我在看看SPY++輸出什么,然后將對(duì)應(yīng)的信息,輸入到程序配置中 ,僅次而已。
恩,是的,雖然麻煩但他的確可以工作,而且平時(shí)我也不會(huì)在修改它,真可謂一勞永逸。。。。。。
5.  具體功能總是對(duì)應(yīng)具體實(shí)現(xiàn),如果明白了上述功能的原理,那么看下面的結(jié)構(gòu)應(yīng)該是很簡(jiǎn)單的。讓我們看看上述功能如何用程序來(lái)描述。
 //0 軟件功能 1 扒 快捷鍵 2 扒 菜單命令
typedef enum {Commnd_Self=0x00,Commnd_ShorCut,Commnd_Menu} CommndType;
typedef struct
{
           CommndType  type;
           char*                 lpCommndData; //數(shù)據(jù)
           CString        csMouseGesture; //鼠標(biāo)手勢(shì) LRUD
           CString    csDesc; //描述 用于tip
}MouseCommnd;
不錯(cuò),一個(gè)結(jié)構(gòu)而已,相當(dāng)于上述功能快照。
也許唯一點(diǎn)要說(shuō)明的就是lpCommndData了。不同手勢(shì)類型代表不同數(shù)據(jù)(也許用個(gè)union比較好,做的時(shí)候,是想到那就做到那,有的地方也許欠考慮。。。),在最后執(zhí)行命令時(shí),根據(jù)type類型,做不同處理,如下。
BOOL CMouseEx::Excute()
{
      MouseCommnd* pCommnd;
switch (pCommnd->type)
{
          case Commnd_Self:                  //程序本身的功能
case Commnd_ShorCut             //處理加速鍵
case Commnd_Menu:               //發(fā)送WM_COMMND
}
}
下面對(duì)每個(gè)不同類型的lpCommndData數(shù)據(jù)格式做個(gè)簡(jiǎn)要分析。
a.        類型為Commnd_Self的,代表程序本身實(shí)現(xiàn)的功能,說(shuō)白了就是實(shí)現(xiàn)一函數(shù)來(lái)完成某個(gè)具體邏輯, 因?yàn)樘峁┕δ芤呀?jīng)事先定好,所以我們?cè)趌pCommndData身上存放函數(shù)地址,這樣在執(zhí)行時(shí),我們可以在將其轉(zhuǎn)化為函數(shù)調(diào)用,之后這塊邏輯就不用在修改了,以后在增加功能,只要存放正確函數(shù)地址即可,為此用四個(gè)字節(jié),存放函數(shù)地址。怎樣確定一個(gè)函數(shù)地址呢?而且還是類成員函數(shù),比方說(shuō)就前面提到過(guò)的CloseCur這個(gè)成員方法,這個(gè)成員地址怎么得到呢?其實(shí)地址在編譯時(shí)就已經(jīng)確定,可以通過(guò)類的偏移來(lái)得到地址,但那樣如果類結(jié)構(gòu)改了,就有可能出錯(cuò),為此這里我們根據(jù)堆棧平衡原則來(lái)得到函數(shù)地址。
實(shí)現(xiàn)一函數(shù),參數(shù)為函數(shù)指針,將成員函數(shù)傳過(guò)去,這時(shí)堆棧里面就存放該函數(shù)地址了,我們得到他就可以了。描述有可能不清,直接來(lái)代碼把,正所謂‘源碼之下,了無(wú)秘密’,相信大家能看懂的。。。
//得先有一個(gè)成員函數(shù)指針把
typedef void (CMouseEx::*pSelffn)();
 
//如下是填充一個(gè)程序本身功能的代碼。使用時(shí)像這樣
MouseCommnd *pCommnd = new MouseCommnd;
pCommnd->type = Commnd_Self;
pCommnd->lpCommndData = new char[4];
//得到函數(shù)地址
DWORD dAddress  =  GetFunAddress(&CMouseEx::CloseCur);
*(DWORD*)pCommnd->lpCommndData = dAddress;
pCommnd->csMouseGesture = "DR";
pCommnd->csDesc = "關(guān)閉當(dāng)前窗口";
//、、、、、、可以增加更多功能
 
//采用內(nèi)聯(lián)匯編方式,得到成員函數(shù)的地址
DWORD CMouseEx::GetFunAddress( pSelffn p )
{
DWORD dAddress;
         __asm
         {
                   mov eax,[ebp+08h]
                   mov DWORD ptr[dAddress],eax
         }
         return dAddress;
}
在函數(shù)調(diào)用時(shí),無(wú)非也就是先PUSH 參數(shù)、push返回地址,、push ebp ,其中[EBP+8]為最右邊參數(shù),這里就一個(gè)參數(shù),也就是說(shuō)這個(gè)值,既函數(shù)地址。(以VC6以及stdcall 調(diào)用約定來(lái)解析)
這樣我們可以得到所有函數(shù)地址,在調(diào)用時(shí)就方便了。如下
接上面BOOL CMouseEx::Excute() 函數(shù)
case Commnd_Self:
{ //我們只保存函數(shù)地址,所以得自己實(shí)現(xiàn)函數(shù)調(diào)用,模擬CALL指令
       DWORD *dwThis = (DWORD*)this;
                                     __asm
       {
                 mov ebx,dword ptr [pCommnd]
                 mov edx,[ebx].lpCommndData
                 mov eax,dword ptr [edx] ;得到函數(shù)地址
                 mov ecx, dword ptr [dwThis]   ;模擬this指針
                 call  eax          ;調(diào)用函數(shù),無(wú)參
       }
}
應(yīng)該挺簡(jiǎn)單的把。。。。
VC中如果想看反匯編代碼,ALT+8能夠滿足你,那多麻煩,用手勢(shì)多好。
這樣做的好處時(shí),不管你以后在增加多少功能,只要初始化函數(shù)地址正確,它就能夠正常工作,也就是說(shuō)你要的工作是初始化pCommnd這個(gè)結(jié)構(gòu),并實(shí)現(xiàn)函數(shù)的具體邏輯,僅此而已,其他的你用管。這一塊是不需要修改的。當(dāng)然除了BUG。
b.   加速鍵
lpCommndData 在加速鍵類型中,存放hotkey的值,大小也為四個(gè)字節(jié),高位放wModifiers,低位放wVirtualKeyCode。
上面已經(jīng)說(shuō)過(guò),快捷鍵要起效,就必須帶ALT,其實(shí)觸發(fā)快捷鍵那就簡(jiǎn)單了keybd_event 完全可以勝任,具體實(shí)現(xiàn)就不用在舉例了把。無(wú)非也就如下這樣
keybd_event(wVirtualKeyCode,0,0,0); //模擬鍵按下
keybd_event(wVirtualKeyCode,0,KEYEVENTF_KEYUP,0);//彈起
c.    WM_COMMND
lpCommndData 在COMMND中,用于存放消息,大小也為四個(gè)字節(jié),高位放加速鍵、菜單項(xiàng)的標(biāo)示ID,低位放Notification Cod,既加速鍵為1,菜單為0。
至于發(fā)消息,那就更簡(jiǎn)單了,只要信息正確,如下OK。
USHORT nCode,nFlag;
nCode = *( USHORT *)pCommnd->lpCommndData;
nFlag = *( USHORT *)(pCommnd->lpCommndData + 2);// 偏移消息號(hào)
//向IDE 發(fā)消息。
PostMessage(m_hDevStudioWnd,WM_COMMAND,MAKEWPARAM(nCode,nFlag),0);
6.  至此對(duì)程序核心部分的設(shè)計(jì)思想及實(shí)現(xiàn)我做了一些簡(jiǎn)要分析,我希望我表達(dá)的夠清楚,以不至使你既浪費(fèi)了時(shí)間,有沒(méi)有搞清楚怎么回事?如果真的那樣,請(qǐng)不要懷疑你的能力,那是我的問(wèn)題,怪我沒(méi)有事情講清楚。
我們分析了程序主要部分,當(dāng)然這個(gè)小程序還涉及到一些其他知識(shí)點(diǎn),麻雀雖小,但也五臟俱全,比方說(shuō)
Ø   為了限制輸入手勢(shì)命令的EDIT只能接受幾個(gè)特定的字母,我使用了子類化
Ø   移動(dòng)tip窗口,并對(duì)其貼圖。
Ø   增加手勢(shì)命令的BUTTON ,我使用了重繪了。
Ø   以及其他小地方。
但這樣的一些東西,一不是我們分析目標(biāo),二也沒(méi)有必要說(shuō)這些東西,畢竟我們主要著重點(diǎn)是在手勢(shì)扒手。
      看下我的測(cè)試環(huán)境。
 

最后在說(shuō)說(shuō)源代碼的事,代碼在XP_SP2、VC_SP6下編譯并通過(guò)簡(jiǎn)單測(cè)試,其實(shí)我也想過(guò)把代碼放出來(lái),但由于最初沒(méi)有定具體功能,在做的時(shí)候,是想道那就做到那,感覺(jué)好的就加上了,代碼太。。。,實(shí)在不好意思拿出來(lái)誤導(dǎo)大家,不過(guò)核心思想我們已經(jīng)講過(guò)了,你也完全可以重新實(shí)現(xiàn)一個(gè),隨便一寫也比這個(gè)好。
      好了,終于完了,就到這里把,祝大家愉快~~~~~~

插件下載地址:
 
本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/gangyilovevc/archive/2010/11/29/6042014.aspx
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
深入淺出Win32多線程程序設(shè)計(jì)之綜合實(shí)例
串行通信及一個(gè)通信演示程序
深入淺出Win32多線程程序設(shè)計(jì)
共享內(nèi)存的使用
擴(kuò)展通用控件的功能
外掛編寫完全攻略 -
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服