• <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>
            面對現實,超越自己
            逆水行舟,不進則退
            posts - 269,comments - 32,trackbacks - 0

            安裝程序的使用

            生成的安裝程序和卸載程序接受一些命令行的參數。這些參數可以讓用戶在安裝過程中對安裝程序作部分控制。

            公共選項

            • /NCRC 禁止 CRC 檢測,除非在腳本里強制使用了 CRCCheck force
            • /S 靜默運行安裝程序或卸載程序。更多信息請參看 section 4.12
            • /D 指定默認的安裝目錄 ($INSTDIR), 可以越過 InstallDirInstallDirRegKey 。這個參數必須是最后一個參數并且不能帶任何引號即使路徑帶有空格。僅支持絕對路徑。

            卸載程序特殊選項

            • _?= 指定 $INSTDIR。這也會阻止卸載程序把它自己復制到臨時文件夾再運行。這將可以使用 ExecWait 來運行卸載程序并等待它完成。這個參數必須是最后一個參數并且不能帶任何引號即使路徑帶有空格。

            例子

            1 installer.exe /NCRC
            2 installer.exe /S
            3 installer.exe /D=C:\Program Files\NSIS
            4 installer.exe /NCRC //D=C:\Program Files\NSIS
            5 uninstaller.exe /S _?=C:\Program Files\NSIS
            # 靜默卸載舊版本并等待它完成后才繼續
            1 ExecWait '"$INSTDIR\uninstaller.exe" /S _?=$INSTDIR'


            以上信息來自NSIS幫助。下面為實例代碼:

             1 !define APPLOCALPATH "Test.exe"
             2 !define APPPATH "$TEMP\${APPLOCALPATH}"
             3 
             4 OutFile "Test ${__DATE__}.exe"
             5 
             6 Section "Silent MakeNSIS"
             7         SetOutPath "$TEMP"
             8         File /r  "install\*.*"
             9         ExecWait '$TEMP\${APPLOCALPATH} /S /D=F:\Program Files\NSIS'
            10         Delete '$TEMP\${APPLOCALPATH}'
            11 SectionEnd


             

            posted @ 2012-05-25 09:30 王海光 閱讀(8672) | 評論 (0)編輯 收藏
            本文轉自:http://www.shnenglu.com/humanchao/default.html?page=2

            已知前序和中序:

            struct NODE 
            {
                NODE 
            *pLeft;
                NODE 
            *pRight;
                
            char chValue;
            };

            int  CharInStrFirstPos(char ch, char *str, int nLen)
            {
                
            char *pOrgStr = str;
                
            while (nLen > 0 && ch != *str)
                {
                    str
            ++;
                    nLen
            --;
                }
                
                
            return (nLen > 0? (str - pOrgStr) : -1;
            }

            void ReBuild_PreIn(char *pPreOrder, char *pInOrder, int nTreeLen, NODE **pRoot)
            {
                
            if (pPreOrder == NULL || pInOrder == NULL)
                {
                    
            return;
                }

                NODE 
            *pTemp = new NODE;
                pTemp
            ->chValue = *pPreOrder;
                pTemp
            ->pLeft = NULL;
                pTemp
            ->pRight = NULL;

                
            if (*pRoot == NULL)
                {
                    
            *pRoot = pTemp;
                }

                
            if (nTreeLen == 1)
                {
                    
            return;
                }

                
            int nLeftLen = CharInStrFirstPos(*pPreOrder, pInOrder, nTreeLen);
                assert(nLeftLen 
            != -1);
                
            int nRightLen = nTreeLen - nLeftLen -1;

                
            if (nLeftLen > 0)
                {
                    ReBuild_PreIn(pPreOrder 
            + 1, pInOrder, nLeftLen, &((*pRoot)->pLeft));
                }

                
            if (nRightLen > 0)
                {
                    ReBuild_PreIn(pPreOrder 
            + nLeftLen + 1, pInOrder + nLeftLen + 1,
                        nRightLen, 
            &((*pRoot)->pRight));
                }
            }

            已知后序和中序:


            void ReBuild_AftIn(char *pAftOrder, char *pInOrder, int nTreeLen, NODE **pRoot)
            {
                
            if (pAftOrder == NULL || pInOrder == NULL)
                {
                    
            return;
                }
                
                NODE 
            *pTemp = new NODE;
                pTemp
            ->chValue = *pAftOrder;
                pTemp
            ->pLeft   = NULL;
                pTemp
            ->pRight  = NULL;
                
                
            if (*pRoot == NULL)
                {
                    
            *pRoot = pTemp;
                }
                
                
            if (nTreeLen == 1)
                {
                    
            return;
                }
                
                
            int nLeftLen = CharInStrFirstPos(*pAftOrder, pInOrder, nTreeLen);
                assert(nLeftLen 
            != -1);
                
            int nRightLen = nTreeLen - nLeftLen -1;
                
                
            if (nLeftLen > 0)
                {
                    ReBuild_AftIn(pAftOrder 
            + nRightLen + 1, pInOrder, nLeftLen, &((*pRoot)->pLeft));
                }
                
                
            if (nRightLen > 0)
                {
                    ReBuild_AftIn(pAftOrder 
            + 1, pInOrder + nLeftLen + 1,
                        nRightLen, 
            &((*pRoot)->pRight));
                }
            }

            我上傳了一個工VC的工程,有興點此下載趣的朋友。代碼參考于《編程之美》。
            posted @ 2012-05-24 13:57 王海光 閱讀(877) | 評論 (1)編輯 收藏
            本文轉自:http://www.cnblogs.com/jillzhang/archive/2007/09/16/894936.html


            遞歸算法學習系列二(歸并排序)

                  歸并排序是利用遞歸和分而治之的技術將數據序列劃分成為越來越小的半子表,再對半子表排序,最后再用遞歸步驟將排好序的半子表合并成為越來越大的有序序列,歸并排序包括兩個步驟,分別為:

                  1)劃分子表

                  2)合并半子表 

                 首先我們來討論歸并算法,歸并算法將一系列數據放到一個向量中,索引范圍為[first,last],這個序列由兩個排好序的子表構成,以索引終點(mid)為分界線,以下面一個序列為例

                7,10,19,25,12,17,21,30,48

               這樣的一個序列中,分為兩個子序列 7,10,19,25  和 12,17,21,30,48,如下圖所示:

               image 

            再使用歸并算法的時候的步驟如下:

             第一步:比較v[indexA]=7和v[indexB]=12,將較小的v[indexA]取出來放到臨時向量tempArray中,然后indexA加1

              image

             

             第二步:比較v[indexA]=10和v[indexB]=12,將較小的10放到臨時變量tempArray中,然后indexA++;

              image

            第三步:比較v[indexA]=19與v[indexB]=12,將較小的12存放到臨時變量tempArray中,然后indexB++;

               image

            第四步到第七步:按照以上規則,進行比對和存儲,得到如下結果:

               image

            最后一步:將子表b中剩余項添加到臨時向量tempArray中

               image 

            然后將臨時變量中的值按照索引位置,拷貝回向量v中,就完成了對向量v的歸并排序

            算法函數為:

             1 public void Merger(int[] v, int first, int mid, int last)
             2        {
             3            Queue<int> tempV = new Queue<int>();
             4            int indexA, indexB;
             5            //設置indexA,并掃描subArray1 [first,mid]
             6            //設置indexB,并掃描subArray2 [mid,last]
             7            indexA = first;
             8            indexB = mid;
             9            //在沒有比較完兩個子標的情況下,比較 v[indexA]和v[indexB]
            10            //將其中小的放到臨時變量tempV中
            11            while (indexA < mid && indexB < last)
            12            {
            13                if (v[indexA] < v[indexB])
            14                {
            15                    tempV.Enqueue(v[indexA]);
            16                    indexA++;
            17                }
            18                else
            19                {
            20                    tempV.Enqueue(v[indexB]);
            21                    indexB++;
            22                }
            23            }
            24            //復制沒有比較完子表中的元素
            25            while (indexA < mid)
            26            {
            27                tempV.Enqueue(v[indexA]);
            28                indexA++;
            29            }
            30            while (indexB < last)
            31            {
            32                tempV.Enqueue(v[indexB]);
            33                indexB++;
            34            }
            35            int index = 0;
            36            while (tempV.Count > 0)
            37            {
            38                v[first+index] = tempV.Dequeue();
            39                index++;
            40            }
            41        } 

                實現歸并排序;歸并排序算法分為兩步,第一步:先將原來的數據表分成排好序的子表,然后調用 Merger  對子表進行歸并,使之成為有序表,例如有如下向量:

              25,10,7,19,3,48,12,17,56,30,21

            對此序列進行歸并排序的步驟為:

               image

                歸并算法函數為

             1 public void MergerSort(int[] v, int first, int last)
             2        {
             3            if (first + 1 < last)
             4            {
             5                int mid = (first + last) / 2;
             6                MergerSort(v, first, mid);
             7                MergerSort(v, mid, last);
             8                Merger(v, first, mid, last);
             9            }
            10        } 

                歸并算法的劃分子表和歸并子表與原數據序列次序無關,因此算法的最壞情況,最壞情況和平均情況時間復雜度是一樣的

            下面是歸并算法的函數調用圖

                   image

            示例程序: MergerSort.rar

            posted @ 2012-05-23 14:01 王海光 閱讀(529) | 評論 (0)編輯 收藏
            通過API函數::GetPrinter()來獲取打印機的相關信息。
             1 HANDLE hPrinter; 
             2 DWORD dwNeeded=0
             3 PRINTER_INFO_2* pPrinterInfo = NULL;
             4 PPRINTER_NOTIFY_INFO pNotify = NULL;
             5 ::OpenPrinter((LPTSTR)(LPCTSTR)"打印機名稱"&hPrinter, NULL);
             6 ::GetPrinter(hPrinter,2,0,0,&dwNeeded);
             7 if (dwNeeded <= 0)
             8 {
             9     LOG("獲取打印機信息長度dwNeeded=%d失敗,添加打印機消息處理失敗", dwNeeded);
            10     return 0;
            11 }
            12 pPrinterInfo = new PRINTER_INFO_2[dwNeeded]; 
            13 if(!::GetPrinter(hPrinter,2,(LPBYTE)pPrinterInfo,dwNeeded,&dwNeeded))
            14 
            15     DWORD dError = GetLastError();
            16     LOG("獲取打印信息失敗,錯誤代碼:%d,添加打印機消息處理失敗", dError);
            17     return 0;
            18                          
            19 
            20 ::ClosePrinter(hPrinter); 
            21 delete []pPrinterInfo; 

            posted @ 2012-05-23 11:00 王海光 閱讀(1082) | 評論 (0)編輯 收藏
            本文轉自:http://www.shnenglu.com/fztcjjl/archive/2012/05/02/173434.html

            Linux開發工具視頻

            工欲善其事必先利其器,《Linux開發工具使用》視頻講解Linux底下C/C++開發工具的使用。主要包括編譯工具gcc、調試工具gdb、make(Makefile)工具以及當前流行的自動化編譯工具cmake工具。

            gcc入門(上)
            本節課的主要內容有:
            什么是gcc
            gcc特點
            gcc編譯過程
            gcc常用選項
            gcc編譯多文件
            在線播放地址:http://www.cppcourse.com/gcc1.html
            gcc入門(下)
            本節課的主要內容有:
            使用外部庫
            靜態庫與共享庫
            生成靜態庫
            生成動態庫
            在線播放地址:http://www.cppcourse.com/gcc2.html
            Makefile(上)
            本節課的主要內容有:
            make與Makefile介紹
            Makefile基本規則
            簡單的Makefile編寫
            Make自動化變量
            Makefile編譯多個可執行文件
            在線播放地址:http://www.cppcourse.com/makefile1.html
            Makefile(下)
            本節課的主要內容有:
            make常用內嵌函數
            多級目錄Makefile
            實用的Makefile
            在線播放地址:http://www.cppcourse.com/makefile2.html
            gdb入門(上)
            本章的主要內容有:
            什么是gdb
            gdb功能
            運行程序
            查看源碼
            設置斷點
            單步調試
            gdb常用命令總結
            在線播放地址:http://www.cppcourse.com/gdb1.html
            gdb入門(下)
            本章的主要內容有:
            查看運行時數據
            程序錯誤
            gdb調試邏輯錯誤
            gdb調試段錯誤
            core文件調試
            在線播放地址:http://www.cppcourse.com/gdb2.html
            posted @ 2012-05-22 11:29 王海光 閱讀(396) | 評論 (0)編輯 收藏
                 摘要: 用GetPrivateProfileString和WritePrivateProfileString函數讀寫文件操作。以及轉載的一篇關于文件操作的文章  閱讀全文
            posted @ 2012-05-17 16:46 王海光 閱讀(7168) | 評論 (0)編輯 收藏
            本文轉自:http://topic.csdn.net/u/20120329/15/ee6b04a0-a797-4f59-b538-5d8be71db9a4.html

            大家都知道,當編寫一個win32 console application時,當運行此類程序的時候默認情況下會有一個類似dos窗口的console窗口,但是有的時候我們只想在程序中運行一段功能代碼,不希望顯示這個console窗口,讓代碼執行完畢之后程序自動退出.下面就介紹一下,如何隱藏win32 console application的console窗口 .

            因為此種方法是通過設置編譯器的鏈接開關來實現,所以讓我們來看一下編譯器的鏈接開關選項(也就是linker選項).

            首先我們來看一下linker的 /subsystem 選項該選項的語法形式如下:
            /subsystem:{console|efi_application|efi_boot_service_driver|
            efi_rom|efi_runtime_driver|native|posix|windows|windowsce}
            [,major[.minor]]

            這個鏈接選項告訴操作系統如何運行可執行文件

            console: win32 字符模式應用程序,此種類型的應用程序在運行的時候會產生一個類似dos窗口的控制臺窗口,如果在應用程序的主函數為main()或者wmain(),在默認情況下該應用程序就是一個控制臺應用程序.

            extensible firmware interface 和cpu具體架構相關的一個參數選項,并不常用,在這里暫不詳細介紹.
            如果對此有興趣的可以訪問intel主頁來查看相關內容

            native;設備驅動器選項,如果/driver:wdm選項被設定的話,該鏈接選項(native)就為默認選項

            posix: 在windows nt 種運行在posix子系統上的應用程序

            windows:該類型的應用程序不產生console窗口,該類型的應用程序的窗口由用戶自己創建,簡而言之
            就是一個標準的win32 application,其入口地址為winmain()函數或者wwinmain()函數的地址
            如果你在應用程序種定義的主函數為winmain或者wwinmain,在默認情況下該應用程序就是一個
            win32 application !

            windowsce:運行在windows ce上的應用程序

            major and minor (optional):主版本號和次版本號,該選項為可選,該選項為0~65535之間的十進制整數

            從上面可以看出如果我們建立一個win32 console application的話,linker的/subsystem選項應該為
            console,可以在vc開發環境的project->setting->link->project option中看到!

            接下來我們再看看應用程序是如何運行的!

            我們知道用vc編寫的程序,運行的時候是需要 cc 運行庫支持的.當我們運行一個c/c 程序的時候鏈接器會首先尋找應用程序的啟動函數,例如:

            如果你建立了一個console程序的話,編譯器得鏈接開關會是以下這種形式
            /subsystem:console /entry:maincrtstartup (ansi)
            /subsystem:console /entry:wmaincrtstartuup (unicode)

            如果你建立了一個win32 application,編譯器得鏈接開關則會是一下形式
            /subsystem:windows /entry:winmain (ansi)
            /sbusystem:windows /entry:wwinmain (uincode)

            上面的兩種形式可以再project->setting->link->project option中看到,上面的subsystem和entry并不需要都設置,如果你只設置了/subsystem:console的話,那么默認的entry開關在默認情況下應為/entry:maincrtstartup.反之,如果你在應用程序中定義了main函數的話,默認情況下,你/subsystem開關應該為/system:console.

            在默認情況下/subsystem 和/entry開關是匹配的,也就是console對應maincrtstartup或者wmaincrtstartup.windows對應winmain或者wwinmain.但是我們也可以通過手動改動的方式使他們不匹配.例如我們可以這樣改動

            #pragma comment( linker, /subsystem:windows /entry:maincrtstartup ) // 設置入口地址
            int main(int argc, char* argv[])
            {
            messagebox(null, hello, notice, mb_ok);
            return 0;
            }

            在默認情況下鏈接器看到/subsystem下是windows選項的時候,它會自動尋找winmain或者wwinmain
            但我們強制指定入口地址,這樣運行程序的時候默認的console窗口就會隱藏!

            上面是在代碼中使用#pragma指令來設置,還有一種就是直接在開發環境的
            project->setting->link->project option中手工改動!

            總結如下:
            1:如果console程序已經寫好了,不能改了,也可以。寫一個API程序,不要畫窗口,然后用CreateProcess調用寫好的console程序,把屬性設成SW_HIDE即可。
            2:不能用控制臺來寫(CONSLOE),要用WINMAIN做入口就可以了,不畫窗口,別人就都看不見了. 你只用想想辦法把你的進程在任務欄里面隱藏住就可以.
            3:如果是console程序,用API函數GetStdHandle()獲得控制臺程序的窗口句柄,然后在隱藏窗口
            4://這一句隱藏控制臺
            #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
            你要寫控制臺程序就用這個.在控制臺程序中隱藏控制臺窗口!
            posted @ 2012-05-17 16:10 王海光 閱讀(531) | 評論 (0)編輯 收藏
            查找指定進程:
             1 BOOL Test::FindProcess(const CString &sProcessName)
             2 {
             3     BOOL bResult = FALSE;
             4     HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//
             5     //PROCESSENTRY32 *info = new PROCESSENTRY32; 
             6     //info->dwSize=sizeof(PROCESSENTRY32); 
             7 
             8     PROCESSENTRY32 info; 
             9     info.dwSize = sizeof(PROCESSENTRY32); 
            10     Process32First(handle, &info); 
            11     while (Process32Next(handle, &info) != FALSE) 
            12     {   
            13         if (sProcessName.CompareNoCase(info.szExeFile) == 0)   
            14         {   
            15             bResult = TRUE;
            16             break;
            17         }   
            18     } 
            19     CloseHandle(handle);
            20 
            21     return bResult;
            22 }

            posted @ 2012-05-10 14:20 王海光 閱讀(1079) | 評論 (0)編輯 收藏
                 在MFC中,向線程傳遞CString變量參數時,很容易犯一個錯誤,就是使用一個超出生存期的變量,在主函數中定義的CString變量是局部變量,當主函數結束時,這個CString變量就會被析構,而卻在另一個線程中繼續使用,參數傳遞就會出現問題。
                 解決此問題,可以在主函數中new一個CString,在線程結束時在delete一下釋放內存。或者聲明一個全局變量,保證CString變量不會超出生存期,這樣傳遞進線程的參數就可以正常使用了。
                 下面為示例代碼: 
             1 DWORD WINAPI test::ProcessNotifyThread(LPVOID pParam)
             2 {
             3 
             4     CString* sTest = (CString*)pParam;
             5     //AfxMessageBox(*sTest);
             6     delete sTest;
             7     return 0 ;
             8 }
             9 
            10 void test::OnBnClickedButton1()
            11 {
            12     // TODO: Add your control notification handler code here
            13      CString *sTest = new CString;
            14      *sTest = "hello";
            15      LPVOID lpvoid=sTest;
            16 
            17     CWinThread* pThread = AfxBeginThread((AFX_THREADPROC)test::ProcessNotifyThread, lpvoid);
            18 }
                 CString類是很好用,但在多線程時最好不要用CString,因為MSDN明確說了,CString類是非線程安全的。
                 下面為摘抄的:

                 CString只保證類級的線程安全, 
                 要做到對象級別的線程安全,需要你自己進行同步, 也就是說, 可以同時有N個線程在讀, 但是寫的時候,必須保證沒有任何線程"正在"讀和寫 才可以寫入.

            1 CString str; 
            2 
            3 CCriticalSection cs; 
            4 cs->Lock( ); 
            5 str+="abcdefg";.. 
            6 do anything you want 
            7 cs->Unlock( );


            線程傳遞char*

             1 DWORD WINAPI test::ProcessNotifyThread(LPVOID pParam)
             2 {
             3 
             4     char *pSectionName = (char *)lpvoid;
             5     CString sSectionName;
             6     sSectionName.Format("%s", pSectionName);     return 0 ;
             7  }
             8  
             9  void test::OnBnClickedButton1()
            10  {
            11      // TODO: Add your control notification handler code here
            12       CString str = _T("aaaa");
            13       const char *pSectionName = (LPCTSTR)str;     
            14       CWinThread* pThread = AfxBeginThread((AFX_THREADPROC)test::ProcessNotifyThread, (LPVOID)pSectionName);
            15  }

             

            posted @ 2012-05-10 10:20 王海光 閱讀(2601) | 評論 (0)編輯 收藏
                在Windows 2000下調試程序時,碰到一個問題:在導入一個win32 DLL時,LoadLibrary()函數返回值為空,GetLastError返回值為127 (找不到指定的程序)。其他DLL文件調用都正常。最后發現這個DLL文件中一個API函數WTSGetActiveConsoleSessionId()不支持2000系統,所以導致DLL文件總是導入不成功。
                加載dll失敗,原因大致有:
                1.dll初始化時失敗,這是因為dll本身有問題;
                2.dll需要的其他dll文件不存在;
                3.調用的dll再本地機器上不存在。
                
                解決方案: 用動態加載的方式
               
             1 typedef DWORD (WINAPI *LoadWTSGetActiveConsoleSessionId)(VOID);
             2 
             3             HMODULE hModKrl  =  LoadLibrary(TEXT("Kernel32.dll"));
             4             if (!hModKrl)  
             5             {  
             6                 LOG("導入 kernel32.dll 失敗");
             7                 return;
             8             }  
             9 
            10             LoadWTSGetActiveConsoleSessionId fWTSGetActiveConsoleSessionId  =  (LoadWTSGetActiveConsoleSessionId)GetProcAddress(hModKrl, "WTSGetActiveConsoleSessionId");
            11             if (!fWTSGetActiveConsoleSessionId)
            12             {
            13                 LOG("調用WTSGetActiveConsoleSessionId 失敗");
            14                 return;
            15             } 
            16             dwSessionId = fWTSGetActiveConsoleSessionId();
            17 
            18             if (hModKrl)  
            19             {  
            20                 FreeLibrary(hModKrl);  
            21             }
                使用動態加載dll,在Windows2000系統下成功,但獲取WTSGetActiveConsoleSessionId函數入口地址失敗。查找msdn發現此函數不支持2000系統。

               Requirements     

            Minimum supported client

            Windows XP

               Minimum supported server

            Windows Server 2003

               Header

            Winbase.h (include Windows.h)

               Library

            Kernel32.lib

               DLL

            Kernel32.dll
                  

            posted @ 2012-05-09 14:59 王海光 閱讀(10660) | 評論 (0)編輯 收藏
            僅列出標題
            共27頁: First 19 20 21 22 23 24 25 26 27 
            精品亚洲综合久久中文字幕| 欧美久久亚洲精品| 人妻无码久久精品| 久久99精品久久久久久hb无码| 久久国产色av免费看| 超级97碰碰碰碰久久久久最新| 久久国产欧美日韩精品| 性高湖久久久久久久久AAAAA| 国产激情久久久久影院老熟女免费| 久久青青草原国产精品免费| 国产精品熟女福利久久AV| 久久久综合九色合综国产| 久久九九亚洲精品| 久久国产福利免费| 精产国品久久一二三产区区别| 要久久爱在线免费观看| 久久天天躁狠狠躁夜夜avapp| 99久久无色码中文字幕| 久久综合伊人77777| 国产精品福利一区二区久久| 99久久综合狠狠综合久久止| 久久99精品国产一区二区三区| 91久久成人免费| 无码久久精品国产亚洲Av影片| 久久www免费人成看国产片| 精品久久久久久无码人妻热| 久久无码人妻精品一区二区三区| 亚洲欧美一级久久精品| 久久精品国产第一区二区三区| 久久九九久精品国产免费直播| 久久婷婷成人综合色综合| 美女写真久久影院| 婷婷久久综合九色综合绿巨人| 亚洲午夜久久久影院伊人| 欧美日韩中文字幕久久伊人| 婷婷久久综合| 青青草国产成人久久91网| 热99RE久久精品这里都是精品免费 | 国产综合久久久久久鬼色| 狠狠色丁香久久综合五月| 国产免费久久精品99re丫y|