【正文】
殼鉤子可以監(jiān)視各種 Shell 事件消息。 這些鉤子,幾乎可以覆蓋了所有的 Windows 操作。因此,技術(shù)方面所帶來(lái)的風(fēng)險(xiǎn)其實(shí)是相當(dāng)大的。 經(jīng)常使用到的 ObjectARX 反應(yīng)器主要有以下幾種類型: (1)數(shù)據(jù)庫(kù)反應(yīng)器 AcDbDatabaseReactor: 數(shù)據(jù)庫(kù)反應(yīng)器監(jiān)視在 AutoCAD數(shù)據(jù)庫(kù)范圍內(nèi)的事件,例如添加或去除實(shí)體。文檔管理反應(yīng)器監(jiān)視 在 MDI模式下圖形文檔窗口事件,例如打開、關(guān)閉、切換圖形文檔等等。但是碰到一些比較復(fù)雜的事件,我們就需要去了解這個(gè)軟件本身的流程,因此我們可能需要進(jìn)行十分復(fù)雜的編程才能實(shí)現(xiàn)我們所需要的功能。因此要構(gòu)造一個(gè)反應(yīng)器,僅僅需要對(duì)一個(gè)類型反應(yīng)器的父類進(jìn)行繼承,然后對(duì)方法進(jìn)行重寫。一類是直接傳遞命令的操作,比如另存為,這種操作是直接在當(dāng)前窗口進(jìn)行操作。 哈爾濱工業(yè)大學(xué)本科畢業(yè)設(shè)計(jì)(論文) 11 創(chuàng) 建 反 應(yīng) 器截 獲 用 戶 命 令判 斷 類 型調(diào) 用 文 檔 管理 反 應(yīng) 器調(diào) 用 編 輯反 應(yīng) 器調(diào) 用 其 它相 關(guān) 模 塊開 始結(jié) 束 圖 31 用戶監(jiān)控模塊流程 編輯反應(yīng)器 AcDbEditorReactor用于 監(jiān)視在用戶編輯圖形文件時(shí)發(fā)生的事件,例如發(fā)出命令 修改一個(gè)圖形元素 ,或關(guān)閉一個(gè)當(dāng)前的活動(dòng)。 類圖如圖 32所示 。 AcEditorReactor類用于創(chuàng)建一個(gè)編輯反應(yīng)器。 AcApDocManagerReactor類用于創(chuàng)建一個(gè)文檔管理反應(yīng)器。 首先 通過(guò) AutoCAD 命令 appload 加載生成的 ARX 文件。 加載完畢后,就可以監(jiān)控用戶所作出的動(dòng)作。 圖 34 進(jìn)行另存為操作時(shí)的后臺(tái)顯示 其中命令 saveas 是 AutoCAD 自帶命令,代表對(duì)文件進(jìn)行另存為操作。 當(dāng)要關(guān)閉軟件時(shí),應(yīng)當(dāng)對(duì)反應(yīng)器進(jìn)行卸載,同樣通過(guò) appload 命令來(lái)進(jìn)行,卸載結(jié)果如圖 35 所示。該模塊是實(shí)現(xiàn)整個(gè)系統(tǒng)的一個(gè)基礎(chǔ),為以后的工作 提供了很多必要的支持。 圖 形 處 理點(diǎn) 處 理 長(zhǎng) 度 處 理進(jìn) 行 實(shí) 體 分 組標(biāo) 注 處 理 文 字 處 理存 儲(chǔ) 信 息提 取 實(shí) 體 信 息開 始結(jié) 束 圖 41 實(shí)體置亂模塊流程 哈爾濱工業(yè)大學(xué)本科畢業(yè)設(shè)計(jì)(論文) 16 提取出實(shí)體并進(jìn)行分類后,對(duì)于不同類型的實(shí)體,處理方式以及處理難度都有所不同。通過(guò)對(duì)矩陣進(jìn)行數(shù)學(xué)運(yùn)算,進(jìn)一步對(duì)實(shí)現(xiàn)置亂功能。只要對(duì)線的起始點(diǎn)和終止點(diǎn)的坐標(biāo)進(jìn)行變換,就可以實(shí)現(xiàn)線的變換。雖然在實(shí)際運(yùn)行中,出現(xiàn)這種情況的概率還是比較小的,但是我們?nèi)匀挥斜匾獙?duì)這類情況進(jìn)行處理。但是,在文件中,其存儲(chǔ)的并不是一條線和一個(gè)方向,而是存儲(chǔ)了 4 個(gè)點(diǎn)。當(dāng)然,這樣做無(wú)法避免一個(gè)數(shù)字精度的問(wèn)題,或多或少會(huì)出現(xiàn)一定的數(shù)字誤差,但是這個(gè)問(wèn)題在計(jì)算機(jī)中始終是無(wú)法避免的,包括通過(guò) AutoCAD 直接進(jìn)行畫圖。 塊的處理 在 AutoCAD 中,存在一類特殊的元素 —— 塊,塊就是把幾個(gè)簡(jiǎn)單實(shí)體集合到一起,形成一個(gè)新的實(shí)體。實(shí)際上,用戶在 AutoCAD中定義塊相當(dāng)于增加了一個(gè)塊表記錄,塊表記錄的名稱就是塊定義的名稱。 通過(guò)圖 45,可以較直觀地理解塊參照和塊定義的關(guān)系。 做為一個(gè)實(shí)體,我們可以同處理其他實(shí)體的方式一樣,在遍歷塊表的時(shí)候,可以讀取到塊參照,這時(shí)候,就可以對(duì)塊進(jìn)行置亂處理。 線 圓 塊參照 線 塊參照 圓 圓 塊參照 塊參照 …… 塊定義 1 線 圓 弧線 …… 塊定義 2 圓 線 弧線 …… 哈爾濱工業(yè)大學(xué)本科畢業(yè)設(shè)計(jì)(論文) 20 提 取 塊 信 息從 塊 中 提 取實(shí) 體 信 息點(diǎn) 處 理 線 處 理 圖 形 處 理 文 字 處 理將 各 個(gè) 實(shí) 體 重新 結(jié) 合 成 塊處 理 塊 整 體開 始結(jié) 束 圖 46 塊處理 流程 在實(shí)際開發(fā)過(guò)程中還存在一個(gè)問(wèn)題,塊定義作為一個(gè)塊表記錄存在,里面可以包含許多實(shí)體,那么應(yīng)該也是可以包含塊參照,這樣就出現(xiàn)了塊中間還有一個(gè)塊。當(dāng)我們對(duì)坐標(biāo)進(jìn)行變換完畢后,我們還需要對(duì)坐標(biāo)進(jìn)行判斷,是否超出了圖紙的邊界,如果超過(guò)了邊界,那么也是不允許的。有些情況下,這些屬性也可能泄露出一些比較重要的信息,因此在這些情況下,應(yīng)該可以對(duì)這些屬性也進(jìn)行保護(hù)。 其中 DisorderApp 類用于程序的初始化以及卸載,當(dāng)程序被 AutoCAD 軟件載入的時(shí)候,調(diào)用 initApp()方法,對(duì)各個(gè)置亂類進(jìn)行初始化,在軟件中注冊(cè)命令等操作。其中 getBlockTable()方法用于獲得并創(chuàng)建一個(gè)實(shí)體列表,以供其它置亂類使用。 order()方法用于對(duì)獲得的線進(jìn)行分組。 ArcDisorder 類用于對(duì)弧線進(jìn)行置亂操作。同樣我們需要調(diào)用 close()方法,將打開的弧線進(jìn)行關(guān)閉,以釋放資源。 PolyDisorder 類實(shí)現(xiàn)對(duì)多邊形的處理,其中 setPoint 方法用于計(jì)算各個(gè)點(diǎn)的坐標(biāo)。其中 blockTableRecord()方法用于獲取塊所指向的記錄集,并對(duì)指向的記錄集中的實(shí)體進(jìn)行置亂操作,AcDbBlockReference()方法用于獲得塊參照信息。 圖 48 置亂前的 CAD 文檔 然后我們對(duì)這個(gè)文檔進(jìn)行保存操作。 實(shí)體恢復(fù)模塊的設(shè)計(jì) 實(shí)體 恢復(fù)模塊是實(shí)體置亂模塊的逆過(guò)程。 哈爾濱工業(yè)大學(xué)本科畢業(yè)設(shè)計(jì)(論文) 25 圖 形 恢 復(fù)點(diǎn) 恢 復(fù) 長(zhǎng) 度 恢 復(fù)獲 取 加 密 信 息標(biāo) 注 恢 復(fù) 文 字 恢 復(fù)存 儲(chǔ) 信 息提 取 實(shí) 體 信 息開 始結(jié) 束 圖 410 實(shí)體 恢復(fù)模塊流程 首先從文件中提取出實(shí)體信息和加密信息,然后針對(duì)不同的實(shí)體,進(jìn)行加密操作的逆運(yùn)算,例如對(duì)點(diǎn)坐標(biāo)乘上逆矩陣。分組完成后,形成矩陣,通過(guò)矩陣恢復(fù)算法,將這個(gè)矩陣恢復(fù)成原來(lái)的矩陣。 線的恢復(fù) 在線的恢復(fù)上,是比較簡(jiǎn)單的?;謴?fù)完成后,將 16 個(gè)元素分配到 4 條線段中,就可以回復(fù)到正確的圖形。然后依次對(duì)點(diǎn),長(zhǎng)度,角度進(jìn)行恢復(fù),恢復(fù)完成后,通過(guò)多邊形的形狀,利用數(shù)學(xué)計(jì)算,得到其他點(diǎn)的坐標(biāo)。 + i n i t A p p ( )+ u n l o a d A p p ( )+ a c r x E n t r y P o i n t ( )o r d e r A p+ g e t E n t i t y ( )+ g e t B l o c k T a b l e ( )O p e n D+ i s K i n d O f ( )+ d i s o r d e r ( )+ u n e n c r y p t ( )+ a p p e n d A c D b E n t i t y ( )+ c l o s e ( )L i n e O r d e+ i s K i n d O f ( )+ u n e n c r y p t ( )+ r e s e t C e n t e r ( )+ r e s e t R a d i u s ( )+ r e s e t S t a r t A n g l e ( )。 獲 取 基 點(diǎn) 坐 標(biāo)恢 復(fù) 坐 標(biāo)獲 取 邊 長(zhǎng)和 角 度計(jì) 算 其 余各 點(diǎn) 坐 標(biāo)儲(chǔ) 存 各 點(diǎn) 坐 標(biāo)開 始 結(jié) 束 圖 413 多邊形恢復(fù) 流程 實(shí)體恢復(fù)模塊的實(shí)現(xiàn) 由于本模塊是實(shí)體置亂模塊的一個(gè)逆過(guò)程,在實(shí)體置亂模塊已經(jīng)實(shí)現(xiàn)的基礎(chǔ)上, 要實(shí)現(xiàn)恢復(fù)模塊是比較容易的,主要需要考慮的是如何提取出相應(yīng)的加密信息,以及如何對(duì)一些特殊情況進(jìn)行處理。 哈爾濱工業(yè)大學(xué)本科畢業(yè)設(shè)計(jì)(論文) 27 提 取 線段 坐 標(biāo)數(shù) 據(jù) 分 組數(shù) 據(jù) 恢 復(fù)存 儲(chǔ) 坐 標(biāo)是 否 有 進(jìn) 行特 殊 處 理進(jìn) 行 恢 復(fù)是否開 始結(jié) 束 圖 412 線恢復(fù) 流程 線的恢復(fù) 在對(duì)多邊形的恢復(fù)上,首先,我們需要獲取到圖形是以哪個(gè)頂點(diǎn)進(jìn)行計(jì)算的。同樣提取出線段實(shí)體后,對(duì)于已經(jīng)進(jìn)行特殊處理的線段,我們需要根據(jù)其處理方式先把它恢復(fù)。流程如圖 411 所示。 哈爾濱工業(yè)大學(xué)本科畢業(yè)設(shè)計(jì)(論文) 26 點(diǎn)的恢復(fù) 在 AutoCAD 中 ,各個(gè)實(shí)體是按照順序儲(chǔ)存的。在文檔恢復(fù)模塊中,我們需要通過(guò)這些加密信息,對(duì)每一個(gè)實(shí)體進(jìn)行恢復(fù)。 哈爾濱工業(yè)大學(xué)本科畢業(yè)設(shè)計(jì)(論文) 24 圖 49 置亂后的 CAD 文檔 通過(guò)程序的運(yùn)行結(jié)果,我們可以發(fā)現(xiàn),當(dāng)用戶直接對(duì)程序進(jìn)行保存后,將會(huì)得到一個(gè)跟原來(lái)文檔完全不一樣的一個(gè)結(jié)果,這樣,即使這個(gè)文檔通過(guò)某種人為的方式泄露出去,也不會(huì)造成巨大的損失。 文檔置亂模塊運(yùn)行結(jié)果 首先,打開 AutoCAD 軟件,使用 appload 命令載入我們的應(yīng)用程序。appendAcDbEntity()方法用于把置亂后的線段數(shù)據(jù)更 新到 CAD 文檔中。同樣,我們調(diào)用 isKindOff()和哈爾濱工業(yè)大學(xué)本科畢業(yè)設(shè)計(jì)(論文) 23 encrypt()方法進(jìn)行實(shí)體確認(rèn)和算法調(diào)用。 encrypt()方法用于調(diào)用置亂算法。appendAcDbEntity()方法用于把置亂后的線段數(shù)據(jù)更新到 CAD 文檔中。 哈爾濱工業(yè)大學(xué)本科畢業(yè)設(shè)計(jì)(論文) 22 + i n i t A p p ( )+ u n l o a d A p p ( )+ a c r x E n t r y P o i n t ( )D i s O r d e r A p p+ g e t E n t i t y ( )+ g e t B l o c k T a b l e ( )O p e n D B+ i s K i n d O f ( )+ o r d e r ( )+ e n c r y p t ( i n p a s s w o r d : i n t )+ a p p e n d A c D b E n t i t y ( )+ c l o s e ( )L i n e D i s o r d e r+ i s K i n d O f ( )+ e n c r y p t ( )+ s e t C e n t e r ( )+ s e t R a d i u s ( )+ a p p e n d A c D b E n t i t y ( )+ c l o s e ( )C i r c l e D i s o r d e r+ s e t T e x t S t r i n g ( )+ a p p e n d A c D b E n t i t y ( )+ c l o s e ( )+ i s K i n d O f ( )+ e n c r y p t ( )T e x t D i s o r d e r+ A c D b B l o c k R e f e r e n c e ( )+ s e t P o s i t i o n ( )+ b l o c k T a b l e R e c o r d ( )+ e n c y r p t ( )+ i s K i n d O f ( )B l o c k D i s o r d e r+ s e t P o i n t A t ( )+ a p p e n d A c D b E n t i t y ( )+ c l o s e ( )+ i s K i n d O f ( )+ e n c r y p t ( )P o l y O r d e r+ i s K i n d O f ( )+ e n c r y p t ( )+ s e t C e n t e r ( )+ s e t R a d i u s ( )+ s e t S t a r t A n g l e ( )+ s e t E n d A n g l e ( )+ c l o s e ( )A r c D i s o r d e r 圖 47 實(shí)體 置亂模塊類圖 LineDisorder 類實(shí)現(xiàn)了對(duì)線的置亂。acrxEntryPoint()方法用于對(duì)實(shí)體進(jìn)行定位。 實(shí)體 置亂模塊的實(shí)現(xiàn) 實(shí)體 置亂模塊的程序?qū)崿F(xiàn) 實(shí)體 置亂模塊是整個(gè)系統(tǒng)的重點(diǎn),也是最大的難點(diǎn),在實(shí)現(xiàn)的過(guò)程中,我們付出了很大的努力。幸好,通過(guò)算法上的優(yōu)化,可以最大限度上來(lái)避免數(shù)字過(guò)大而超過(guò)邊界的情況出現(xiàn)因此我們可以通過(guò)進(jìn)行一次新的置亂過(guò)程來(lái)處理??梢允褂眠f歸的方式來(lái)處理。然后,將這些實(shí)體再次集合成一個(gè)塊,然后對(duì)塊的整體進(jìn)行處理。塊參照指向一個(gè)塊定義,塊定義以一個(gè)塊表記錄的形式存在里面包含了實(shí)體的集合。塊定義不是一個(gè)實(shí)體,而是一種對(duì)實(shí)體的描述,通過(guò)定義塊獲得;塊參照則是一種實(shí)體,圖形窗口中顯示的“塊”都是塊參照,通過(guò)插入塊獲得。 塊定義就是一個(gè)塊的實(shí)際存在。具體流程如圖 44 所示。 因此,在處理這類圖形的時(shí)候,需要保持圖形的原有性質(zhì),系統(tǒng)才不會(huì)出現(xiàn)錯(cuò)誤。 提 取 頂 點(diǎn) 坐 標(biāo)調(diào) 用 點(diǎn) 處 理分 配 點(diǎn) 坐 標(biāo)判 斷 坐 標(biāo) 是否 符 合 規(guī) 定存 儲(chǔ) 坐 標(biāo)對(duì) 坐 標(biāo) 進(jìn)一