Revit二次開發——非模態窗口的事件處理


一.起因   

       自己在寫revit二開時,有一個Winform窗體按鈕點擊事件需要 觸發調用事務進行處理,結果出現“異常“Starting a transaction from an external application running outside of API context is not allowe“”

       其實這是 上面異常是Revit的一種保護機制,創建的非模態對話框Form1后,在Form1未關閉的狀態下,Revit認為是處於非API的上下文環境,所以異常彈出來了。

       在非模態對話框打開的狀態下,調用Transaction必須通過Idling或者ExternalEvent API進行相關代碼調用;在SDK Sample安裝包下面,有個例子程序叫ModelessDialog詳細介紹了Idling及ExternalEvent的調用機制。

       在Revit 2014之前的版本,當非模態對話框打開的狀態,調用Transaction是可以的,但是從Revit 2014之后因為考慮安全等方面被禁止了。

二.解決辦法與代碼

       非模態窗口有一個好處,就是可以一直停留在程序之前,然后持續完成操作。但是在Revit二次開發中,非模態窗口也有幾個注意事項。

              1、需要在文檔關閉的時候,把非模態窗口也關閉掉,不然會導致文檔關閉,窗口還在這樣奇怪的Bug。

              2、非模態的窗口的事件需要在IExternalCommand里注冊。

              3、每個操作必須在外部事件里進行。

      2.1 第一步:注冊外部事件

                             

              2.2 第二步:Form內使用

                         

               在Form構造函數或者Load事件內:

                          

               我Form窗體內有一個TreeList控件,控件鼠標點擊事件觸發 外部事件:

                            

            GetSelectedDistributionProLevel()為獲取當前TreeList鼠標選中的Node信息,DistributionProjectLevelData為自己定義的Class

            m_elecGridLayingOpe.SetGridLineElementSelected(app, node.LevelUniqueID)里面的代碼如下:

            

             其中UniqueId為Element的UniqueId.

三.焦點(關鍵點)          

       在Revit二次開發中,如果使用了非模態窗體,設置好參數輸入后,點擊按鈕命令后,Revit沒有立刻進入到激活狀態,當前的窗體仍然是非模態窗體。以前我會在點擊按鈕中加入一句:this.Close(),直接關閉非模態窗體,這種方式太粗暴

       究其原因:在做的非模態窗體在執行相應命令后,窗體並沒有關閉或是隱藏,就一直處於激活狀態,導致Rveit不能立刻激活或者取到焦點。解決辦法:使用WindowsAPI下的兩個函數 GetActiveWindow(),SetActiveWindow(IntPtr hwnd),一個是獲得當前系統獲得焦點的窗體句柄,一個是設置當前系統某個窗體獲得焦點。

       為獲得Rveit的窗體句柄,需要添加引用:AdWIndows.dll

      代碼如下:

               

     在Form構造函數內:

               

     在TreeList鼠標點擊事件函數內:

                  

 


免責聲明!

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



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