CAD開發中遇到的疑難問題整理與開發技巧


1.Winform窗體與CAD關系、窗體與CAD焦點切換

非模態窗口修改CAD圖元

在非模態窗口中修改實體時,需要將圖層鎖定,否則會報錯;模態窗口則無此情況。

Winfrom中打開DWG圖紙文件

如果要在Winform中打開DWG圖形文件,這個Form必須用Application.ShowModelessDialog方式顯示,不然會報錯(執行環境無效)。

模態窗口焦點切換

使用模態窗口時,如果需要與CAD主窗體進行交互,則用using (EditorUserInteraction edUI = ed.StartUserInteraction(this));使用非模態窗口時,會出現焦點切換問題

(如:當在非模態窗口中點擊按鈕后要去CAD中選擇一個實體,但是應用程序的焦點還在非模態窗口中,此時需要在CAD主窗口中點擊一下讓CAD獲取焦點,才能正常進行實體選取),此時可以用WinAPI中的SetFocus將焦點移到CAD主窗口即可:

[DllImport("user32.dll", EntryPoint = "SetFocus")]             

public static extern int SetFocus(IntPtr hWnd);

調用:SetFocus(Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Window.Handle);

要注意的是:需要配合窗體的MouseEnter、MouseLeave事件使用,但效果並不太理想,如果鼠標移動較快的時候,事件來不及觸發。暫時還沒有找到其他更好的方法,C++中可以接收一個KeepFocus消息,來監視和設置程序焦點,使焦點轉換更靈活,

C#中也可以收到CAD發來的這個消息,但是這個消息的Msg值不是固定的,C++中使用的時候不需要管這個值,因為是由CAD已經提供了,所以可以准確地方監聽這個消息;但是在C#中CAD並沒有提供這個Msg值,所以並不能使用監聽Windows消息的方法來實現焦點的切換功能。

Application.ShowModelessDialog在不同版本CAD的調用不同

CAD2010之前,這個方法有三個重載:

public static void ShowModelessDialog(Form formToShow);

public static void ShowModelessDialog(IWin32Window owner, Form formToShow);

public static void ShowModelessDialog(IWin32Window owner, Form formToShow, bool persistSizeAndPosition);

而在CAD2010中,這個方法有五個重載:

public static void ShowModelessDialog(Form formToShow);

public static void ShowModelessDialog(IntPtr owner, Form formToShow);

public static void ShowModelessDialog(IWin32Window owner, Form formToShow);

public static void ShowModelessDialog(IntPtr owner, Form formToShow, bool persistSizeAndPosition);

public static void ShowModelessDialog(IWin32Window owner, Form formToShow, bool persistSizeAndPosition);

然而,在CAD2010中,第三和第五個重載並沒有什么用,因為CAD2010的窗體對象(Application.MainWindow,即Autodesk.AutoCAD.Windows.Window類)不再實現IWin32Window接口,所以第一個參數沒辦法傳了,只能使用第一、二、四個重載方法。這是我目前的研究結果,不知道第三、第五個重載方法在CAD2010中還有沒有其他使用方式。

另外,上面的ShowModelessDialog是針對Winform窗體的,而CAD2010的窗體卻都是WPF的,於是在CAD2010中又提供了一個新接口方法:ShowModelessWindow,這個方法也是有五個重載:

public static void ShowModelessWindow(System.Windows.Window formToShow);

public static void ShowModelessWindow(IntPtr owner, System.Windows.Window formToShow);

public static void ShowModelessWindow(System.Windows.Window owner, System.Windows.Window formToShow);

public static void ShowModelessWindow(IntPtr owner, System.Windows.Window formToShow, bool persistSizeAndPosition);

public static void ShowModelessWindow(System.Windows.Window owner, System.Windows.Window formToShow, bool persistSizeAndPosition);

這個接口方法是用來顯示WPF窗體對象的,但是,雖然有五個重載方法,但是應該和ShowModelessDialog一樣,只有第一、二、四個方法能正常使用。

2.CAD注冊表

CAD 3264位系統注冊表不同

AutoCAD 注冊表項在32位與64系統中的不同

AutoCAD注冊表信息讀取,如獲取電腦上已安裝的所有CAD版本、安裝路徑等注冊表信息。

32位Windows系統中,這些信息保存在:HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD 中;

64位Windows系統中,32位的CAD軟件信息保存在HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Autodesk\AutoCAD 中,64位CAD軟件信息保存在HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD 中。

64位系統中,安裝的CAD版本可能是32位,也可能是64位。

如果在32位的CAD中調用我們的DLL,此DLL讀取 HKEY_LOCAL_MACHINE\SOFTWARE 時,實際讀到的是 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node;如果在64位的CAD中調用我們的DLL,則此時DLL讀取 HKEY_LOCAL_MACHINE\SOFTWARE 時,會得到真正的HKEY_LOCAL_MACHINE\SOFTWARE 對象。

上述情況是因為,為了做到64位系統兼容32位程序,同時又為了防止注冊表項沖突,所以32位應用程序在64位Windows系統中操作 HKEY_LOCAL_MACHINE\SOFTWARE 鍵時會被自動轉到 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node。

具體說明見:http://www.cnblogs.com/mingmingruyuedlut/archive/2011/01/20/1940371.html

這種問題的解決方法參考:較通用的WINAPI方法

http://www.cnblogs.com/mingmingruyuedlut/archive/2011/01/21/1941225.html

適用.NET 4.0的新方法:

     http://www.cnblogs.com/langu/archive/2012/02/26/2368877.html

但是還有一點要注意:在CAD二次開發中,由於我們的DLL最終是要被CAD調用的,所以我們程序集的位數是由CAD的位數來決定的。

注冊表權限

不允許所請求的注冊表訪問權。在win7等64位操作系統中,在CAD調用的C# dll插件中,如果操作注冊表(讀取、寫入等),可能會報這個錯誤,原因是CAD不是以管理員權限運行的,權限不足,要防止這種情況發生,需要讓CAD以管理員身份運行,在CAD的快捷方式或安裝目錄下的acad.exe上右鍵,選擇“屬性”,切換到“兼容性”頁面,選中“以管理員身份運行此程序”,這樣就不會出現這種情況了。

另外,對於這種錯誤,網上還有一種解決方案,是在操作注冊表的方法上加上RegistryPermissionAttribute屬性標識,如[RegistryPermissionAttribute(SecurityAction.PermitOnly, Read = @"HKEY_LOCAL_MACHINE\SOFTWARE\YourApp")],但是這種情況在CAD開發上好像並不適用,會提示錯誤。

CAD通過注冊表自動加載

用注冊表實現C#DLL或C++ARX隨CAD自動加載,可以往以下兩個地方添加啟動信息:

1)、HKEY_CURRENT_USER\Software\Autodesk\AutoCAD\RXX.X\ACAD-XXXX:XXX\Applications

2)、64位系統中的64位CAD 或 32位系統中的CAD:HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\RXX.X\ACAD-XXXX:XXX\Applications

64位系統中的32位CAD:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Autodesk\AutoCAD\RXX.X\ACAD-XXXX:XXX\Applications

其中,Current_User項不分32位和64位,而LOCAL_Machine則會分32位和64位,用程序進行注冊表讀寫時需要注意。但是CURRENT_USER注冊表信息只對當前登錄的系統用戶有效,而LOCAL_MACHINE注冊表信息則會對系統所有用戶都有效。

C#DLL或C++ARX隨CAD啟動需要向Applications項中添加一個自己命名的項,然后在該項下添加以下幾個值:

DESCRIPTION

字符串

程序名稱或描述

LOADCTRLS

DWord

啟動類型(十進制值):

2=隨CAD啟動加載

4=有命令觸發時加載

8=有載入請求時加載

16=從不加載該應用程序

32=顯式加載該應該程序

LOADER

字符串

要加載的文件位置

MANAGED

DWord

如果是C#DLL,十進制為1,如果是ARX則不添加此項

LOADCTRLS的值可以單獨使用,也可以多個值相加使用,例如:12=4+8=有命令觸發時加載或有載入請求時加載。

另外,如果要使用類型4(有命令觸發時加載),除了設置以上幾個值之外,還需要在自己創建的應用程序節點下創建新項並注冊命令,這樣在CAD啟動時,不會直接加載DLL或ARX,當注冊的命令被觸發時,會加載DLL或ARX:

在自己的應用程序節點下添加“Commands”項,在此項中添加String類型的值,這些值就是注冊的命令,例如:

 

圖中右側的Fcmd就是我們注冊的命令,當啟動CAD后,MyAP所指向的程序並不會被直接加載,只有當Fcmd命令被使用的時候,CAD才會加載MyAP程序。

關於命令注冊這個,在官方AutoCAD.NET文檔和常見的二次開發書籍中都沒有提到,還是無意間從這里(https://through-the-interface.typepad.com/through_the_interface/2009/05/creating-demand-loading-entries-automatically-for-your-autocad-application-using-net.html)找到的。

3.事務

嵌套事務問題

使用嵌套事務時,如果外層的事務不提交,即使里面的事務提交了,最終也會失效。

4.CAD文件、塊、擴展數據操作

寫塊克隆

寫塊克隆:WblockCloneObjects第二個參數為塊表記錄模型空間的ObjectID,此方法會將一個對象集(實體集)完全克隆到另一個DWG文件中,包括圖層名、圖層設置、坐標位置、擴展數據等。

后台打開dwg文件,用SaveAs保存

CAD中用后台打開方式打開DWG圖形文件,並進行修改后,要用SaveAs保存,用Save會出錯。

Autodesk.AutoCAD.DatabaseServices.DataTable 擴展數據表使用時要注意

當對象實體的擴展字典中還沒有這個表時,

DBDictionary.SetAt和Transaction.AddNewlyCreatedDBObject將擴展數據表添加到實體對象,

但是修改時就不能再這樣了,只需要獲取DataTable對象,然后用 DataTable.SetCellAt 方法修改數據表的值,最后提交事務即可。

(注:向實體擴展字典中添加DataTable時,必須將DataTable添加到BlockTableRecord中,不然在保存CAD圖紙的時候,會保存失敗)。

匿名塊

如果要創建匿名塊(在CAD的塊編譯器中看不到,但是在BlockTable中可以查找到並可以添加引用顯示到圖形中,並且不可以手動編輯),只需要在創建BlockTableRecord對象的時候指定其Name為“*U”即可,當把這個BlockTableRecord被成功添加到BlockTable后,會自動會重新分配一個名稱,格式為“*U數字”。

5.CAD選擇集

SelectionFilter 根據XData擴展數據過濾選擇集問題

使用根據對象的擴展數據XData進行過濾選擇時,如果過濾條件僅為DxfCode.ExtendedDataRegAppName(即注冊的應用程序名)時,可以過濾所有類型的對象,

但是如果要用DxfCode.ExtendedDataAsciiString、DxfCode.ExtendedDataInteger16等具體數據內容進行過濾時,則僅能選取到部分類型的對象,如:Line、PolyLine、Ellipse、Region,而像DBText、MText、Circle等類型的實體則會被忽略掉。

SelectionFilter過濾選擇單行文本對象問題

用SelectionFilter過濾選擇文本時,切記單行文本必須寫TypedValue((int)DxfCode.Start,"Text"),要寫成"Text",而不是"DBText"。

6.CAD圖案填充

Hatch填充時的問題

Hatch填充Region時,如果面域對象是由多個面域合並而來,會填充失敗,此時可以調用Region對象的Explode方法將Region炸散,得到多個Region,然后將這些Region一一填充。

對於Hatch.AppendLoop第二個參數:ObjectIdCollection 類型,傳入的是一個或多個實體對象的ID,這些實體必須滿足以下幾個條件:

    1. 如果只傳入一個對象,那么這個對象必須是一個非“回”字型閉合對象,如閉合的pline、單個的Region、Circle、Ellipse等;如果傳入的對象是回字型,即中間是空心的,那么將會報錯,填充將失敗。
    2. 如果傳入的是多個對象,那么這些對象必須正好可以首尾相接地組成一個閉合圖形,且沒有富余的對象,這樣才能成功填充;如果組成的圖形不能閉合,或者閉合后還剩余一些無用處的線、弧等,又或者組成了多個閉合圖形,那么將會報錯,填充將失敗。

7.CAD圖層

當前圖層代碼

AutoCAD.NET獲取CAD當前圖層代碼:            Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database.Clayer;

8.命令

修改命令快捷鍵並立即生效

CAD中點擊:工具-》自定義-》編輯程序參數(acad.pgp),在打開的文件中找到“Command alias format”,在其下方可以看到命令別名定義列表,定義的格式為:“別名,*命令”,每行只能定義一個,定義完成之后,重啟CAD即可生效。如果不想重啟CAD,還有兩種方式可以讓你的定義生效:

1)、在命令文本中輸入reinit,回車,在彈窗中選中“PGP文件”,然后確定,如下圖:                         

2)、在命令文本中輸入re-init,回車,然后輸入16,再回車即可。

第二種方法應該可以在程序中進行實現,不知道AutoCAD.NET中有沒有提供現成的方法,不過可以用sendcommand實現。這樣可以為用戶提供快捷鍵的自定義功能,並且在用戶定義完之后,可以立即生效。acad.pgp文件位置在:CAD安裝目錄\UserDataCache\Support中,是一個隱藏文件。

SendStringToExecuteCAD發送命令

使用SendStringToExecute向CAD發送命令時,如果命令參數中帶有路徑,這時如果執行有問題,可以嘗試使用“/”代替路徑中的“\”。

P/Invoke方式調用CADacedCmdacedCommand方法發送同步命令

關於在C#中使用P/Invoke方式調用CAD的acedCmd或acedCommand方法發送同步命令,如果這兩個接口函數是在自己的自定義命令中調用的,那么可以成功執行,並且是同步的,

但如果是在自己的某個窗體程序里調用的,那么可能會執行不成功(接口返回-5001)或者執行成功,但成了異步命令。另外,CAD2013以下版本這兩個接口是在acad.exe中的,而從CAD2013開始放到了accore.dll中。

另外,在CAD中還有一個未公開接口也可以發送同步命令:acedPostCommand,這個命令同樣在CAD2013以下版本中是在acad.exe中,從CAD2013開始放到了accore.dll中,

另外還有一點不同的是:在CAD2008中它的入口點是“?acedPostCommand@@YAHPB_W@Z”,而從CAD2009開始,它的入口點名稱變成了“?acedPostCommand@@YAHPEB_W@Z”,這一點使用的時候需要注意。

當加載的多個DLL或ARX中有同名的自定義命令時,最后在使用時觸發的是最后加載的那個程序集中的命令。

9.PaletteSet

PaletteSet可以用程序控制其最小尺寸,停靠位置,可停靠位置,按鈕、菜單顯示等,但是用程序指定其停靠位置時,每個面板只能占據單獨一列或一行,不能做到讓多個面板上下同列多行停靠,或左右同行多列停靠。

PaletteSet有兩個重載函數:

一般都用第一個,即在聲明PaletteSet時只傳一個name參數。

第二個重載有兩個參數,一個是name參數,一個是guid參數,CAD會以這個guid為標識,記錄此面板的位置、大小等信息,這樣在下一次,加載這個面板的時候,如果不指定面板的Dock屬性,則會自動使用上次保存的設置來管理面板的停靠位置和大小等。

即:第一次在CAD里加載此面板時,可以給面板指定一個默認的停靠位置,此時用戶可以隨意拖動面板重新指定停靠位置,當用戶關閉CAD時,這個面板的停靠設置會被CAD保存下來,下一次加載的時候,如果不再給此面板指定Dock屬性,則會自動使用上次保存的設置信息進行停靠,要實現這一點,最好用PaletteSet的Add和Save事件進行配合(具體實現,請看這篇文章https://adndevblog.typepad.com/autocad/2015/04/finding-if-paletteset-is-newly-created.html#tpe-action-posted-6a0167607c2431970b01b8d11e7d09970c)。

但是,這種實現方式,會有一個問題:如果在聲明PaletteSet時指定了傳了name參數,CAD會自動創建一個和這個name一樣的啟動命令,就像每次打開CAD時的“COMMANDLINE”命令一樣,每次CAD啟動時都會執行,但是我們創建PaletteSet的方法並不一定會聲明成為一個命令,而且就算聲明成命令,這個命令也不一定和PaletteSet的name參數一樣,這樣在CAD啟動時,就會提示“未知命令”,令人很不爽,解決方法有三種:

(1) 將創建PaletteSet的方法聲明為一個命令,且命令要和PaletteSet的name參數保持一致,而且你的dll要隨CAD自動啟動(可以用注冊表方法實現),但是這種方法太過狹隘,並不好。

(2) 在聲明PaletteSet的時候,name參數只傳一個空字符串,PaletteSet實例化之后,再為PaletteSet指定Text屬性指定面板的名稱即可,這樣CAD啟動時,就不會自動執行命令了。

(3) CAD保存面板停靠信息時,是保存在特殊文件夾Application  Data中的,即C#中的Environment.SpecialFolder.ApplicationData文件夾,比如我在XP系統中用32位CAD 2008測試,保存路徑為:C:\Documents and Settings\Administrator\Application Data\Autodesk\AutoCAD 2008\R17.1\chs\Support\Profiles\FixedProfile.aws,這是一個xml文件。

 

如果聲明PaletteSet的時候指定了第二個guid參數,CAD會在FixedProfile.aws文件ToolsInfo節點中添加一個Tool節點,用來保存面板信息,同時會在StartupInfo中也添加一個Tool節點,指定啟動命令,這個啟動命令和PaletteSet的name參數一樣,就算在聲明PaletteSet的時候傳的是一個空字符串,CAD也會在StartupInfo節點下添加一個Command=""的啟動命令,CAD啟動時,應該是會把空命令忽略.

所以使用第二個解決方法,CAD在啟動時不會執行面板對應的啟動命令,如果你對此有強迫症,不希望CAD保存啟動命令節點的話,那么你可以自行將其刪除,方法如下:

在聲明PaletteSet的時候,可以隨意指定name屬性,或干脆留空,這個不再有影響;實現CAD提供的IExtensionApplication接口,此的接口中的Terminate會在你的DLL被卸載時(即CAD被關閉時)執行,我們可以在這個方法內,打開當前CAD對應的FixedProfile.aws文件,然后把StartupInfo節點下面板對應的啟動命令刪除,此命令和之前聲明PaletteSet的時候指定的name參數一樣,刪除之后,保存FixedProfile.aws文件即可。

10.CAD事件處理

Document.CommandEnded

關於Document.CommandEnded事件:正常來說自己定義的命令都應該可以觸發CommandEnded事件.

但如果你的命令中使用了Application.ShowModelDialog,那么你的命令將不會觸發CommandEnded事件,如果把Application.ShowModelDialog換成Form本身的ShowDialog,則可以正常觸發CommandEnded事件。

Database_ObjectModified

關於Database_ObjectModified事件:如果啟動了一個事務,且最后沒有提交它,那么在這個事務中的所有更改都不生效,且不會觸發Database_ObjectModified事件。

如果最后提交了這個事務,那么如果在打開對象時是以OpenMode.ForWrite方式打開的,那么不管到底是否對這個對象有更改都會觸發Database_ObjectModified事件;

而如果在打開對象時是使用的OpenMode.ForRead打開的,后面沒有對實體進行修改則不會觸發Database_ObjectModified事件,如果后面使用UpgradeOpen升級了讀寫方式不管到底有沒有對實體做出修改,也都會觸發Database_ObjectModified事件。

另外,在此事件內部使用事務時要注意以下兩點,否則會彈出崩潰提示:Error handler re-entered;Exiting now

u 此事件內不能使用嵌套事務。

u 並且此事件外有其他事務正在被使用時不能再打開新事務。

ESC鍵影響DocumentManager_DocumentActivated

具體情況是:

有一個程序為DocumentManager綁定了DocumentActivated事件,在這個事件中進行圖紙掃描,掃描大部分的圖形實體。在打開測試圖紙時,會有一個彈窗:

此時如何按下ESC來關閉此窗體,那么在窗體關閉之后由於圖紙窗口又獲取到了焦點,所以會觸發DocumentActivated事件,但是之前按的ESC鍵會影響事件中掃描程序的執行,使程序報錯:eUserBreak。

這個情況只在AutoCAD2010中會出現,在其他版本CAD中測試未發現這種情況。

解決方案:

至於在CAD2010中,用了一個簡單方法解決了這個問題:創建一個窗體,在創建中放一個定時器,把掃描程序放到定時器中執行,再定義一個公共方法啟動定時器,這樣在DocumentActivated事件中調用此窗體的公共方法啟動定時器進行圖紙掃描.

這樣不不需要彈出窗體就可以完成工作。除了這個方法使用線程或者直接聲明定時器也許也能解決這個問題,不過沒有進行嘗試,不知道行不行得通,等有時間試過之后再更新結果。

11.CAD炸開Explode

在使用Explode接口將實體炸開到一個DBObjectCollection中之后,發現不能直接按從尾到頭的順序去遍歷DBObjectCollection,否則會報錯(大致意思是說索引超出邊界或索引不能為負值),但事實上索引值肯定是沒有錯的。

后來發現,如果將使用正向對DBObjectCollection進行一次遍歷,或者按照正向順序取出DBObjectCollection的前兩三個元素(例如DBObject dbo1=dbos[0];DBObject dbo2=dbos[1];先用正向索引讀取一下集合的前幾個元素),

然后再使用倒序方式對DBObjectCollection進行遍歷,就不會再提示錯誤了,這個問題感覺有些不可思議。(在AutoCAD2008中發現的問題,其他版本沒有測試)  

12.CAD圖元編輯

使用各種實體后調用Dispose釋放

在使用各種實體對象之后(如DBObject、Entity、Region、Polyline、DBObjectCollection等),盡量主動調用其Dispose方法進行釋放,否則當你頻繁對一組實體進行重復操作時,可能會引發一些錯誤,甚至引起CAD的崩潰。

面域顏色

如果為面域指定了實體顏色,在此面域和其他面域進行了布爾運算之后(面域相加、相減、合並),面域的顏色會變成ByLayer 。

過濾選擇polyine,類型名LWPolyline

用過濾選擇進行polyine的時候,類型名必須寫成LWPolyline,而要過濾選擇polyline2d對象時,類型名要寫成polyline。

IntersectWith

實體的IntersectWith方法,當參與運算的實體的頂點越多耗時越長,兩個實體,當調用此方法的主實體是頂點數較少的那個實體,則耗時會較短,當調用此方法的主實體是頂點數較多的那個實體,則耗時會較長(使用Stopwatch的ElapsedTicks檢測)。

13.CAD低版本VisualStudio調試

使用VS2010 + AutoCAD2008進行開發時,如果不能調試,可以嘗試修改AutoCAD2008安裝目錄中的acad.exe.config文件:

<configuration>

<startup>

             <!--We always use the latest version of the framework installed on the computer. If youare having problems then explicitly specify .NET 2.0 by uncommenting the following line.
                    <supportedRuntime version="v2.0.50727"/>-->      

                   <supportedRuntime version="v2.0.50727" />

</startup>

</configuration>

使用VS調試AutoCAD 2012-2014版本時,如果出現命中不了斷點,且提示“無可用源”,那么可以嘗試查看AutoCAD的FIBERWORLD變量的值是否為1,如果是1則可以使用NEXTFIBERWORLD命令將其修改為0,修改完成之后再進行調試即可正常命中斷點。(詳情可見這里https://www.cnblogs.com/junqilian/archive/2011/03/18/1988327.html)

14.CAD報錯

eInvalidOpenState錯誤問題

當在事務A中調用GetObject方法獲取了對象E,在事務A結束之后,如果在另一個事務B中調用E的UpgradeOpen時,會出現錯誤提示:eInvalidOpenState,這時候需要在事務B中用GetObject根據E.ObjectId重新獲取E才行。

eWasNotOpenForWrite錯誤問題

同問題情況類似,在事務A中調用GetObject方法獲取了對象E,在事務A結束之后,如果在另一個事務B中調用E的DowngradeOpen方法,則會出現錯誤提示:eWasNotOpenForWrite,這時候需要在事務B中用GetObject根據E.ObjectId重新獲取E。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM