質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
COM

COM(Component Object Model)はMicrosoftによるコンポーネントテクノロジーであり、 ソフトウェアの再利用を目的とした技術を指します。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

1回答

4811閲覧

BricsCADのCOM参照におけるActiveDocumentプロパティの取得方法

yukibeatles

総合スコア12

COM

COM(Component Object Model)はMicrosoftによるコンポーネントテクノロジーであり、 ソフトウェアの再利用を目的とした技術を指します。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2019/08/06 08:35

編集2019/08/06 08:40

前提・実現したいこと

C#プログラムからCOM参照により起動したBricsCADで、アクティブとなっている図面のプロパティにアクセスしたい。

発生している問題・エラーメッセージ

BricsCADアプリケーションをCreateObjectメソッドで起動し、
Openメソッド(Documentsクラス)でアクセスしたい図面を開き、
ActiveDocumentよりModelSpace, ActiveLayerプロパティにアクセスした際、以下のエラーが発生する。

"インターフェイスが登録されていません (HRESULT からの例外:0x80040155)"

該当のソースコード

以下のような、BricsCADを起動 → 既存図面を開く → 図面プロパティにアクセス する関数を作成しました。
BricscadApp Type Library,BricscadDB Type Libraryの参照設定は行っています。
コードはこちらを参考にしました。

C#

1 // ファイル名でdwgを開く 2 public static void OpenDrawing(string fileName) 3 { 4 AcadApplication acAppComObj = null; 5 const string strProgId = "BricscadApp.AcadApplication"; 6 7 try 8 { 9 // BricsCADアプリケーションの取得 10 acAppComObj = (AcadApplication)Marshal.GetActiveObject(strProgId); 11 12 } 13 catch 14 { 15 try 16 { 17 // BricsCADアプリケーションの起動 18 acAppComObj = (AcadApplication)Activator.CreateInstance(Type.GetTypeFromProgID(strProgId), true); 19 } 20 catch 21 { 22 return; 23 } 24 } 25 26 // BricsCADを可視化 27 acAppComObj.Visible = true; 28 29 // 図面を読み込み 30 acAppComObj.Documents.Open(fileName);               // ←BricsCADが起動し図面が実際に開く 31 32 // アクティブドキュメントを取得 33 AcadDocument acDocComObj = acAppComObj.ActiveDocument; // ←ここでModelSpaceが取得できていない 34 BricscadDb.AcadModelSpace BcadMs = acDocComObj.ModelSpace; 35 }

試したこと

・AutoCADで同様にコーディングを行った場合は、正しくModelSpaceを取得できました。AutoCADと参照すべきクラスが異なることによるエラーと思われますが、具体的な修正方法が分からずにいます。

・別途.NET APIとCOM参照を組み合わせたプログラムにて同様のアプリケーションを作成してみようと試みましたが、こちらは関数を呼び出す段階で、以下のエラーが発生しました。

型 'System.IO.FileNotFoundException' のハンドルされていない例外が ConsoleBricsCAD_TEST.exe で発生しました 追加情報:ファイルまたはアセンブリ 'BrxMgd, Version=19.2.0.13510, Culture=neutral, PublicKeyToken=null'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。

実装を試みた関数は以下の通りです。
参照設定にBrxMgd.dll, TD_Mgd.dllを追加しています。
コードはこちらを参考にしました。

C#

1 // ファイル名でdwgを開く ←この関数を呼び出したタイミングでエラー 2 public static void OpenDrawing(string fileName) 3 { 4 // BricsCADアプリケーションの取得 5 BricscadApp.AcadApplication app = Bricscad.ApplicationServices.Application.AcadApplication as BricscadApp.AcadApplication; 6 // dwgを開く 7 BricscadApp.AcadDocument doc = app.Documents.Open(fileName, false, null); 8 // 開いたdwgをアクティブに 9 if (doc != null) 10 { 11 app.ActiveDocument = doc; 12 } 13 }

BrxMgd.dllが参照しているライブラリが無いことによるエラーと認識していますが、別途何かインストールが必要なのでしょうか。
以上、BricsCADに関して、同じような手段でプログラムを実装されている方がおられれば、ご教示よろしくお願い致します。

補足情報(FW/ツールのバージョンなど)

開発環境は、Visual Studio2013です。
BricsCADは、V19(体験版)、AutoCADは2015バージョンです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

外していたらすみません。
BricsCADというのを知らなかったので調べてみましたが、AutoCAD互換のCADなんんですね。ただ、互換というのが、データ互換のみの場合COMインターフェースまで共通とは限らないのではないでしょうか。

Visual Studio 2013に付属しているかちょっと自信がないのですが、Visual StudioにOLE-COM Object Viewerというツールがあります。これを使って、対象のオブジェクト(BricscadApp.AcadApplication)がどういうインターフェースを持っているか調べることができます。仮に同じ名前のインターフェースが存在する場合でも引数の型が違ったりすると、それだけで呼び出しに失敗するので、目的のインターフェースが存在するのか、呼び出し形式は間違っていないか調査されることをお勧めします。

もしインターフェースが全然違うようでしたら、名前から機能を推測するしかないので、目的達成のハードルは上がりそうです。

投稿2019/08/06 13:06

KoichiSugiyama

総合スコア3041

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yukibeatles

2019/08/07 05:35

詳細にご回答頂き、ありがとうございます。 まず、インターフェイスに関して、無知だったため、調べた上で以下のように認識しました。 COMオブジェクト(今であればBricscadApp.AcadApplicationクラスのインスタンスacAppComObj)の機能(今であればActiveDocument)にアクセスする際には、そのCOMオブジェクトをサポートするインターフェイス(今であればIAcadApplication)を利用している。 そこで、OLE-COM Object Viewerで、BricscadApp Type LibraryのCoClasses内のAcadApplicationクラスのIAcadApplicationインターフェイスのActiveDocumentメソッドを確認したところ2つあり、 1つ目が、 [id(0x00000005), propget, helpstring("Specifies the active document (drawing file)")] IAcadDocument* ActiveDocument(); 2つ目が、 [id(0x00000005), propput, helpstring("Specifies the active document (drawing file)")] void ActiveDocument([in] IAcadDocument* rhs); でした。 今回の使用では、値の取得なので、1つ目のメソッドが該当していると考えました。 同様にAutoCAD Type LibraryのAcadApplicationクラスのIAcadApplicationインターフェイスのActiveDocumentメソッドは、 1つ目が、 [id(0x00000005), propget, helpcontext(0x00010241)] IAcadDocument* ActiveDocument(); 2つ目が、 [id(0x00000005), propput, helpcontext(0x00010241)] void ActiveDocument([in] IAcadDocument* rhs); でしたので、1つ目のメソッドが該当していると考えました。 上記2段目が関数定義と想定すると、呼び出し形式は同じ、かつ、 AutoCADと同様のインターフェイスがBricsCAD側にも存在している、 という認識で正しいでしょうか。
KoichiSugiyama

2019/08/07 06:42

そうですね。その認識でよいとは思いますが、次はBricscadAppで呼び出したIAcadDocumentがどのようなインターフェースやプロパティを持っているか調べていく必要があるのではないかと思います。 そうやって順繰りに呼び出したオブジェクトについて調べることで必要な情報を取得できるかどうかが判ってくると思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問