天天看點

CATIA多版本/程序對象處理

方法來源:https://stackoverflow.com/questions/17658425/getting-a-specific-instance-of-com-object-in-vb-net#

當CATIA打開多個程序或同時啟動多個版本CATIA時,通過getobject隻能擷取到第一個啟動的CATIA對象。

通過GetRunningObjectTable擷取對象,然後進一步擷取CATIA對象時,可以發現,存在2個CATIA對象,但這兩個對象依舊對應第一個啟動的CATIA對象。

搜尋的結果基本是,這是達索的鍋,沒有辦法擷取指定的CATIA對象。除了上面連結的那位老兄。

以下是這位大神老兄的方法原文:

Make a dll with two functions:
    HRESULT __stdcall CoMarshalToFile(IUnknown* punk, const char* const filePath)
    /* uses `::CreateStreamOnHGlobal`, `::CoMarshalInterface`, `::CoGetMarshalSizeMax`,
     and `::GetHGlobalFromStream` to marshal the IUnknown to the specified file.
    */
    HRESULT __stdcall CoMarshalFromFile(IUnknown** ppunk, const char* const filePath)
    /* uses `::CreateStreamOnHGlobal` and `::CoUnmarshalInterface` to marshal
     from the file to an IUnknown pointer.
    */

 In CATIA:
  Note: this only needs to be done on the development computer.
  Make a new "VBA projects" macro library. 
    Add "declare" statements for:
        "LoadLibrary" (Windows API)
        "CoMarshalToFile" (DLL specified above)
    Add a function 
        Public Function MarshalCatiaToFile _
            (marshalInstanceFilePath As String, _
                marshalDllFolder As String) As Long

    MarshalCatiaToFile calls "LoadLibrary" to load the C++ DLL
    and then calls CoMarshalToFile (in DLL) to marshal the CATIA instance
    to a file.

  Remove the macro library from CATIA's list of macro libraries.

 Create a file:
    "C:\Temp\CatiaOnTheFlyCatScripts\OnTheFlyCatScript.catvbs"
  The file can be empty.

 In CATIA:
      Note: this must be done for *each* user of CATIA on *each* computer used.
      It may be possible to make this available to all users without individual
      setup required: it is saved in "FrameUserAliases.CATSettings"
      It may also be possible to reverse engineer the settings file and set up
      the needed data from outside CATIA.

    Add "C:\Temp\CatiaOnTheFlyCatScripts\" as a new "Directories" macro library.
    Make the added library "current"
    Use "Tools --> Customize --> Commands --> Macros" to assign a
      "User Alias:" to the "OnTheFlyCatScript.catvbs" script file.
      Name the alias "ExecuteOnTheFlyCatScript".
    Remove the macro library from CATIA's list of macro libraries.
    Close CATIA at this point to force the changes to be saved.

 VB.net / C# program:
      Add the DLL (from step ) and the CatVBA macro library (from step ) as
      "Embedded Resource" to the project. 

      During program execution:
        Extract the DLL and macro library to an appropriate location. 
        Load the DLL into session using "LoadLibrary".
        Create the file:
          "C:\Temp\CatiaOnTheFlyCatScripts\OnTheFlyCatScript.catvbs"

        The "OnTheFlyCatScript.catvbs" will be executed in CATIA. It
          uses CATIA.SystemService.ExecuteScript to execute the 
          "MarshalCatiaToFile" function in the CatVBA macro library.
          Add method of choice to this file to indicate success/failure.
          I use a dialog box with the appropriate title.

        To execute the "OnTheFlyCatScript.catvbs":
          Using the Windows API functions, get the window handle for the
            "Power Input" box at the bottom right of the "desired" 
            CATIA window.
          Using the Windows API functions (*NOT* "SendKeys") send 
            "c:ExecuteOnTheFlyCatScript" + {Enter} to the "Power Input".
          Wait for the "completion" signal from the script. If you used
            a dialog box, use the Windows API function to close it.

        Assuming the script succeeded in marshaling the CATIA instance to
          a file, call the DLL function CoMarshalFromFile to get the CATIA
          instance.

           

相當繁瑣,最後作者保證了該方式是能夠正确操作多個CATIA對象,以下是該方法的個人了解。

關鍵點:CATIA内部VBA對象,CATIA指令行執行宏。

在CATIA的VBA編輯器中,自帶了CATIA對象。多個CATIA程序時,VBA中的CATIA對象依然能夠正常操縱對應的CATIA。是以隻要能夠擷取到這個對象,就可以操作指定的CATIA了。

是以,調用CATIA宏,通過宏把對象傳遞至外部程式即可。

接下來就是處理調用宏了,因為不能直接擷取指定的CATIA對象,是以不能通過CATIA對象執行宏,原文作者采用了一種機智的辦法,通過Windows API向CATIA的指令行發送消息。CATIA中指令行執行宏需要在 “Tools –> Customize –> Commands –> Macros” 中進行設定。之後通過相應的指令就可以直接在CATIA指令行中執行宏了。

總結:

該方法的主要過程是:

1、編寫能夠傳遞CATIA對象的宏;

2、為該宏定義快捷方式;

3、向CATIA視窗的指令行發送消息,執行宏,通過宏擷取CATIA對象。

至于跨程序擷取對象,網上能夠找到很多相關資料,但是大部分都是對可序列化的對象進行的操作,對于這裡的問題,隻能是……我也不會,求助專業人士吧。

最後,該方法雖然能夠實作多CATIA程序操作,但如果沒有辦法通過代碼自動實作定義宏在CATIA中的快捷方式的話,對于二次開發而言,意義不是很大。