2010年5月28日金曜日

.NET の勉強 「画層状態を復元するサンプル」(AutoCAD 2011)

なんか最近 .NET が続いてますが、覚え始めでおもしろくて、ちょっとはまってきたかも。
ということで、今日も .NET です。


acad_mdg.chm「AutoCAD .NET デベロッパ ガイド」のサンプルに画層状態を復元するものがあったので試してみました。

サンプルにあったコードはこんな内容です。
<CommandMethod("RestoreLayerState")> _
Public Sub RestoreLayerState()
  '' Get the current document
  Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument

  Dim acLyrStMan As LayerStateManager
  acLyrStMan = acDoc.Database.LayerStateManager

  Dim sLyrStName As String = "ColorLinetype"

  If acLyrStMan.HasLayerState(sLyrStName) = True Then
      acLyrStMan.RestoreLayerState(sLyrStName, _
                                   ObjectId.Null, _
                                   1, _
                                   LayerStateMasks.Color + _
                                   LayerStateMasks.LineType)
  End If
End Sub

で、昨日つくったやつでは、ACVD_LayerState っていう画層状態に保存するようにしたので、ACVD_LayerState があれば、その状態を復元するように変更してみました。

変更後のコードはこんな感じです。

        ' ACVD_LayerState という画層状態が存在すれば、それを復元するサンプル(acad_mdg.chm「AutoCAD .NET デベロッパ ガイド」のサンプルを元に作成)
        <CommandMethod("ACVD_Blog", "_ACVD_RestoreLayerState", "ACVD_RestoreLayerState", CommandFlags.Modal)> _
        Public Sub ACVD_RestoreLayerState()
            '' Get the current document
            Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
            Dim ed As Editor = acDoc.Editor

            Dim acLyrStMan As LayerStateManager
            acLyrStMan = acDoc.Database.LayerStateManager

            Dim sLyrStName As String = "ACVD_LayerState"

            Try
                If acLyrStMan.HasLayerState(sLyrStName) = True Then

                    ' 本当に画層状態を復元するかどうかの確認を求める
                    Dim pr As PromptResult
                    Dim pko As PromptKeywordOptions = New PromptKeywordOptions("")
                    pko.Message = vbLf & "画層状態を復元しますか?"
                    pko.Keywords.Add("Yes", "Yes", "はい(Y)")
                    pko.Keywords.Add("No", "No", "いいえ(N)")
                    pko.AllowNone = False
                    pr = ed.GetKeywords(pko)
                    If pr.Status <> PromptStatus.OK Then
                        Return
                    End If

                    ' 画層状態の復元
                    If pr.StringResult.ToString = "Yes" Then
                        acLyrStMan.RestoreLayerState(sLyrStName, _
                                                     ObjectId.Null, _
                                                     1, _
                                                     LayerStateMasks.On + _
                                                     LayerStateMasks.Frozen + _
                                                     LayerStateMasks.Locked + _
                                                     LayerStateMasks.Plot + _
                                                     LayerStateMasks.Color + _
                                                     LayerStateMasks.LineType + _
                                                     LayerStateMasks.LineWeight + _
                                                     LayerStateMasks.Transparency + _
                                                     LayerStateMasks.PlotStyle + _
                                                     LayerStateMasks.NewViewport)
                    Else
                        Return
                    End If
                Else
                    Application.ShowAlertDialog("ACVD_LayerState という画層状態が存在しないため、画層状態を復元できません。")
                End If
            Catch ex As Autodesk.AutoCAD.Runtime.Exception
                MsgBox(ex.ToString)
            End Try
        End Sub



間違えてコマンドを実行してしまうとまずいので、「画層状態を復元しますか?」と表示して はい(Y) か いいえ(N) を選ぶように追加してみました。
GetKeywords っていうのをこんな感じかなと思って入れてみたのですが、とりあえずこれで試してみたら、一応ちゃんと動きました。
ビルドした DLL ファイルは こちら です。

NETLOAD コマンドで ACAD Video Blog.dll をロードして、ACVD_RestoreLayerState コマンドを実行すると、ACVD_LayerState という画層状態が存在すれば、それが復元されます。

2010年5月27日木曜日

.NET の勉強 「画層状態を保存するサンプル」(AutoCAD 2011)

acad_mdg.chm「AutoCAD .NET デベロッパ ガイド」のサンプルに画層状態を保存するものがあったので試してみました。

サンプルにあったコードはこんな内容です。
<CommandMethod("RestoreLayerState")> _
Public Sub RestoreLayerState()
'' Get the current document
Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument

Dim acLyrStMan As LayerStateManager
acLyrStMan = acDoc.Database.LayerStateManager

Dim sLyrStName As String = "ColorLinetype"

If acLyrStMan.HasLayerState(sLyrStName) = True Then
acLyrStMan.RestoreLayerState(sLyrStName, _
ObjectId.Null, _
1, _
LayerStateMasks.Color + _
LayerStateMasks.LineType)
End If
End Sub

保存するのは、色と線種だけみたいなので、その他の設定も保存するように変更してみました。

また、既に同じ名前の画層状態があったら、何もしてくれないので、既に同じ名前の画層状態があったら、削除して作りなおすようにしてみました。

それと、Try~Catch も入れてみました。こんな使い方でいいのかなぁ…

変更後のコードはこんな感じです。

        ' 画層状態の保存のサンプル(acad_mdg.chm「AutoCAD .NET デベロッパ ガイド」のサンプルを元に作成)
        <CommandMethod("ACVD_Blog", "_ACVD_CreateLayerState", "ACVD_CreateLayerState", CommandFlags.Modal)> _
        Public Sub ACVD_CreateLayerState()
            '' Get the current document
            Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument

            Dim acLyrStMan As LayerStateManager
            acLyrStMan = acDoc.Database.LayerStateManager

            Dim sLyrStName As String = "ACVD_LayerState"

            Try
                ' もし、既に同じ名前の画層状態があったら削除する
                If acLyrStMan.HasLayerState(sLyrStName) = True Then
                    acLyrStMan.DeleteLayerState(sLyrStName)
                End If

                ' 画層状態を保存する
                acLyrStMan.SaveLayerState(sLyrStName, _
                                          LayerStateMasks.On + _
                                          LayerStateMasks.Frozen + _
                                          LayerStateMasks.Locked + _
                                          LayerStateMasks.Plot + _
                                          LayerStateMasks.Color + _
                                          LayerStateMasks.LineType + _
                                          LayerStateMasks.LineWeight + _
                                          LayerStateMasks.Transparency + _
                                          LayerStateMasks.PlotStyle + _
                                          LayerStateMasks.NewViewport, _
                                          ObjectId.Null)
            Catch ex As Autodesk.AutoCAD.Runtime.Exception
                MsgBox(ex.ToString)
            End Try
          
        End Sub


これで試してみたら、一応ちゃんと動きました。
ビルドした DLL ファイルは こちら です。

NETLOAD コマンドで ACAD Video Blog.dll をロードして、ACVD_CreateLayerState コマンドを実行すると、現在の画層状態が ACVD_LayerState という名前で保存されます。

2010年5月26日水曜日

.NET の勉強 「役立つ動画がオートデスクの Web サイトに…」(AutoCAD 2011)

今まで、オンライン ヘルプのサンプルとかを見ながら .NET の勉強をしていましたが、なんと オートデスクの Web サイトに動画で説明している資料がありました。知らなかった…


ここ にある AutoCAD 2010 .NET Wizard(誤) DevTV (DeveloperTV)(正) がそれです。(間違えてたので修正しました。2010/05/27 管理人)

ここでは、以下の内容が、実際にコードを書きながら説明されています。

  • 簡単なアプリケーションの作成
  • 図形を図面に追加
  • 図形の編集
  • アプリケーションのデータ保存
  • イベント監視
動画を見ながら自分でもコードを書いて試せるので、とても便利です。


オンライン ヘルプのサンプルでは、Using ~ という記述になってるところがここでは、Try ~Catch という記述になってますね。

エラーの処理ができるので、きっとこっちの方がいいのでしょう。
ということで、今後はこっちで行こうかと思います。

2010年5月21日金曜日

AutoCAD 2011 .Net Wizards を使用して .NET プロジェクトを作成(AutoCAD 2011)

今日は、AutoCAD Managed VB Application Wizard っていうのを使用して .NET プロジェクトを作成できるようなので、それを試してみた結果を書こうかと思います。

まずは、Developer Center にある 「AutoCAD 2011 .Net Wizards.zip」 をダウンロードして、それに含まれる AutoCAD 2011 dotNET Wizards.msi を実行してインストールです。

すると、こんなメッセージがでて、ちゃんとインストールできませんでした。

管理者権限で、Windows 7 にログインしてるんですけど。。。

ぶつぶつ言ってもしょうがないので、コマンド プロンプトを 「管理者として実行」 で起動して、そこから AutoCAD 2011 dotNET Wizards.msi を実行してみました。

すると、今度は問題なくインストールが完了しました。


ということで、早速 Visual Studio 2008 を起動です。


[ファイル] - [新しいプロジェクト] で [新しいプロジェクト] ダイアログを表示して、[Vusual Basic] を選択すると、[AutoCAD 2011 plug-in] というテンプレートがでてきたので、これを選んで OK です。

そうすると、[AutoCAD .NET Wizard Configurator] ダイアログが表示されるので、[Spacify the location of the ...] のことろに ObjectARX 2011 の inc フォルダを指定して Ok です。

これで、プロジェクトが開かれるのですが、ここでは既に参照設定に AcDbMgd と AcMgd が追加されているので、参照設定は何もする必要がないみたいです。

で、MyCommands.vb っていうのがあったので、これを見てみると、こんな記述がありました。
<CommandMethod("MyGroup", "MyCommand", "MyCommandLocal", CommandFlags.Modal)> _
Public Sub MyCommand() ' This method can have any name
    ' Put your command code here
End Sub
ここに、自分で作ったコマンドを入れるってことですね。

ということで、まずはコマンドの定義のところを以下のように変更しました。
<CommandMethod("acadvideo", "test0521", "MyCommandLocal", CommandFlags.Modal)> _
Public Sub test0521() ' This method can have any name

また、ソリューション エクスプローラにある myCommands.res をダブルクリックして myCommands.res を表示して、MyCommand を test0521 に変更しました。


そして、「' Put your command code here」の下に以下を記述してみました。

'' Get the current document and database
Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
Dim acCurDb As Database = acDoc.Database

'' Start a transaction
Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()

    '' Open the Block table for read
    Dim acBlkTbl As BlockTable
    acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead)

    '' Open the Block table record Model space for write
    Dim acBlkTblRec As BlockTableRecord
    acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite)

    '' Create a line that starts at 5,5 and ends at 12,3    Dim acLine As Line = New Line(New Point3d(5, 5, 0), New Point3d(12, 3, 0))    acLine.SetDatabaseDefaults()

    '' Add the new object to the block table record and the transaction
    acBlkTblRec.AppendEntity(acLine)
    acTrans.AddNewlyCreatedDBObject(acLine, True)

    '' Save the new object to the database
    acTrans.Commit()
End Using

AutoCAD にロードして test0521 コマンドを実行してみたところ、問題なく線分が作成されました。

このテンプレートを使えば、簡単に作れますよってことですね。

2010年5月14日金曜日

.NET の勉強 「画層の作成」(AutoCAD 2011)

金曜日恒例の .NET の勉強です。
今日は、画層を作成してみました。


ヘルプでサンプルを探して、サンプルの余分なところを削除して、こんなコードを書きました。


Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.DatabaseServices

Public Class Class1
    <CommandMethod("CreateLayer")> _
    Public Sub CreateLayer()
        Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
        Dim acCurDb As Database = acDoc.Database

        Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
            Dim acLyrTbl As LayerTable
            acLyrTbl = acTrans.GetObject(acCurDb.LayerTableId, OpenMode.ForRead)

            Dim sLayerName As String = "テスト"

            If acLyrTbl.Has(sLayerName) = False Then
                Dim acLyrTblRec As LayerTableRecord = New LayerTableRecord()

                acLyrTblRec.Name = sLayerName

                acLyrTbl.UpgradeOpen()

                acLyrTbl.Add(acLyrTblRec)
                acTrans.AddNewlyCreatedDBObject(acLyrTblRec, True)
            End If
            acTrans.Commit()
        End Using
    End Sub
End Class


で、実際に実行してみると、めでたく 「テスト」 という名前の画層が作成されました。


また、ついでに色と線種の設定も試してみました。
以下の内容を acLyrTblRec.Name = sLayerName の後に書いたら、うまく色と線種の設定もできました。


acLyrTblRec.Color = Color.FromColorIndex(ColorMethod.ByAci, 1)
acLyrTblRec.LineWeight = LineWeight.LineWeight020


(Imports Autodesk.AutoCAD.Colors も追加しました。)

2010年5月7日金曜日

.NET の勉強 「ダイアログを表示してコマンド実行」(AutoCAD 2011)

金曜日恒例の .NET の勉強をしました。


今までいくつかサンプルを見ながら試してきましたが、そろそろダイアログを出してみたくなってきたので、試してみました。


arxmgd.chm の [Autodesk.AutoCAD.ApplicationServices Namespace] - [Application Class] に ShowModalDialog Method と ShowModelessDialog というのがあるので、きっとこれですね。


まずは、フォームの作成
まずは、Form1.vb (Windows フォーム)を作成して、ボタンをひとつ追加しました。
で、そのボタンをクリックすると、前回の試してみた円を作成して ZOOM を行う、以下の内容が実行されるように記述しました。

Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Runtime

Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument

        acDoc.SendStringToExecute("._circle 2,2,0 4 ", True, False, False)
        acDoc.SendStringToExecute("._zoom _extents ", True, False, False)
    End Sub
End Class



ダイアログの表示
あとは、Form1 を表示するように ShowModalDialog Method または ShowModelessDialog を使えばいいみたいです。

Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Runtime

Public Class Class1

    <CommandMethod("test")> _
    Public Sub test()
        Dim f As New Form1()
        Application.ShowModelessDialog(f)
    End Sub
End Class



これで test コマンド実行してみると、ちゃんとダイアログが表示され、ボタンをクリックすると円が作成されて ZOOM が実行されました。


ただし、もう一回 test コマンドを実行すると、またダイアログが表示されました。
コマンドを実行するたびにダイアログが表示されてしまいます。


そこで、ダイアログを表示するところを以下のようにしてみたのですが、ダメでした。

If f.Visible = False Then
    Application.ShowModelessDialog(f)
End If


残念ながら現時点では、どうすればダイアログが既に表示されているかどうかを判断できるかは不明です???


モーダル ダイアログにすれば、ダイアログを閉じないと AutoCAD に戻れないので複数ダイアログが表示されることはないので、とりあえず今回は以下のようにモーダル ダイアログにしてみます。

Application.ShowModalDialog(f)

ただしこのとき、モーダル ダイアログにしたのでダイアログを閉じるコードを Form1.vb の最後に記述しておかないと、ダイアログが自動的に閉じてくれません。
そのため、Form1.vb に以下を追加しました。

 Me.Close()