DelphiでAutoCAD LTのカスタマイズ(余話)最終更新日:1999.12.04

ことの始まり(LTLinkとの出会い)

 ことの始まりはLTLink.DLL。
 mura(村上良一)さんが公開されていたAutoCADとのリンク用ライブラリ、LTLink.DLLをダウンロードしたのがことの始まりです。
 DLLなんて私に使いこなせるのかなと思いながらダウンロードしてみると、なんとDelphi用のサンプルプログラムが入っていました。
 で、試しに動かしてみると、何とAutoCADにコマンドが送れる。コマンドラインの文字が取れる。これには、おどろきました。
 サンプルプログラムをちょこちょこっと変えて動かしてみる。おお、動いてる!AutoCADが動いている!
 感激のあまり、すぐにmuraさんにメールを出したものです。
 フリーウェアをダウンロードして作者あてにメールを出したのは、これがはじめてのことでした。
 同じ頃にごんたさんも「AcadUnit」というDelphi専用のを公開されていたのですが、AcadUnitには「ユーザー入力待ち」というのが無かった。
 当時の私にとっては、これがかなりの障害でした。この頃は、コマンド履歴の変化を監視するという発想自体できなかったのです。

 LTLinkを使った第1作が、LTにページ機能を付加するという「GW98.exe」という自分専用アプリです。
 図枠が25個ぴょこぴょことAutoCADの画面上に並んだ時は、さすがにうれしかったです。
 毎日、会社でデモをやっていました。
 大胆にも、ニフティーADESKJPに「プライベートバージョン」として1ヶ月ほどアップロードしていました。
 当時の私としては、画期的な発想だと思っていたのですが、今思うと何と恥ずかしいことをしていたのか。
 
 こんなきっかけでカスタマイズの面白さに取り付かれたわけです。
 いまでは、開発以外ではほとんどAutoCADを触わっていません。カスタマイズのためのAutoCADとなってしまいました。
  

カスタマイズに対する考え方

 基本的には、AutoCAD LTがユーザーに開放しているメニューマクロ、DIESEL式等により、使用者自らが自分用にカスタマイズすることが最良であると考えています。
 同じような考え方から、カスタマイズツールを公開されているサイト(mura's Home Page)もあります。
 マクロで済むことはマクロで組むのが安全で、しかも速いとも考えています。
 また、マクロはAutoCADのツールボタンに簡単に割り付ることができます。私から見ると、これが最大の魅力です。

 それでは、何故、わざわざ外部プログラムとなるDelphiを使ってAutoCAD LTを操作するのでしょうか。
 もちろん、マクロ以上のこと、LISPに近いことが実現できるからですが、それ以上にカスタマイズの柔軟性があるからです。
 ただ、LISPが使えない分、LISPに近づけるには、かなりの努力と根性と「こだわり」が必要です。

 「使用者自らがカスタマイズする・・・」、言葉としてはきれいで良いのですが、いざ自分でマクロを作ろうとすると、なかなかしんどいものです。
 できる人が特殊(少数)で、できない人の方が普通(多数)なのでは?と思っています。
 マクロが使える人はマクロで。LISPが使えるひとはどうぞLISPで。
 どちらもできないけど、とりあえず楽したい人のために、当サイトはDelphiで作ったアプリを公開しているわけです。

公開についての考え方

 公開を始めた頃は、「プライベートバージョン」という名のもとに、完全とは言い切れないものを宣伝(検索サイトYAHOOに登録)までして公開して良いのだろうかと、よく自分なりに考えたものでした。「フリーウェア」だからといってバグが許されるわけではないというようなことも。
 その頃に、考えた最低限の「公開の思想」。
 1.他人の環境をいじらない。(MNUファイルとかを書き換えない)
 2.使ってみて気に入らなければすぐに消せる。
 基本的には、この2点。

 最近は、それに加えて 
 3.決して自己満足ではない一定のレベルに達したものを提供する。
 を、心がけています。

 ダウンロードサイト「Vector」に登録しようかと思ったこともあるのですが、このサイトに来て頂いて、ここを見て頂いて、ここのにおいを感じ取って頂いて、ここからダウンロードしてもらうのが一番良いと考えなおして、登録しませんでした。ユーザーを求めているのではなく、何らかのつながりを持った理解者、協力者を求めているからです。
(不完全なものを世間の冷たい風雨にさらすのは、作者として心もとないという気持ちもありますが。)
   

外部プログラムであることのメリット

 当サイトで公開しているフリーウェアは、すべて外部プログラムです。さて、そのメリットとは・・・・
 持ち運びできる。これが最大です。
 AutoCAD LTがインストールされている環境であれば、MNUファイルとかをいちいち書き換えなくてもすぐに同じ環境ができあがります。
 ユーザーは何も考えずに解凍、exeをクリック。これだけで良いのです。
 気に入らなければすぐに消せます。また、他人様の環境の書き換えを最小限にできます。これは、安全です。
 私のようにアプリを公開するものにとっては、非常に都合が良いのです。
 

外部プログラムであることのデメリット
 
 外部プログラムであることのデメリット。それは、外部プログラムであること。
 つまり、いちいち起動、終了させないといけないということです。これは、邪魔くさいです。
 この辺は、プログラムの組み方で、アプリからAutoCADを起動、AutoCADが終了したらアプリも終了、アプリ終了時はAutoCADも終了、ということである程度の回避はできますが。(TAC Userで公開しているLT_Execではそういうことをやっています)

 AutoCADのツールボタンからは起動できません。これが最大のデメリットだと思っています。
 このことから、マクロでできるものはマクロで、という考えかたにもなるわけです。

Delphiを使うことのメリット

 単体で動くプログラムファイル(EXE)が簡単に作れる。つまり、あらかじめ別の共用ファイルをインストールしておかなくても良いのです。
 それ故に、必ずインストーラーを作らなくても良い。これは、作り手にとって作業が簡単です
 プログラムをアップロードするまでには、ヘルプ作成、圧縮という手間がかかります。なるべく、作業は減らしたいのです。

 もちろん、Windowsプログラムが簡単に作成できるというDelphiの恩恵も大きなメリットです。
 (VBを持っていない・・・ということもありますが)

AcadTooを選んだ理由

 当サイトで公開しているプログラムは、すべて「ごんた★ワールド」で公開されている「AutoCAD Custmize Tool」を使用しています。
 他にもフリーウェアのリンク用ツールは公開されているのですが、そのAcadToolのメリットは、
 Delphi専用のコンポーネントで、ひとつのEXEファイルの中に入ってしまう。
 故に、あらかじめActiveX等をインストールしておくという手間も要らないからです。
 当たり前ですが、自前でリンクプログラムをつくるより、洗練され、安定している。しかも実績がある。

 AcadToolを使う前はLTLink.DLLを使っていました。プログラムファイルと同じフォルダにほりこんでおけばそれでOK。手間要らずでした。
 今は、バージョンアップしてAclinksXというActiveXになっています。

外部からAutoCADを操作する

 幸いにもAutoCADは、ほとんどの操作がコマンドラインから行えます。(AcadToolを使えば、簡単に文字列をコマンドラインへ送れます。)
 (このことが、私のような邪道なカスタマイザーをはびこらせる原因にもなっているとか・・・)
 外部からコマンドラインに文字列を送れば、キーボードから文字を入力するのと同じ様にAutoCADを操作できるわけです。
 言い換えれば、AutoCADに対してコマンドラインでできないことは、Delphiと言えども実現できないということになります。
 この辺に、外部から操作することの限界があります。
 もちろん、より高度なテクニックで可能となることもありますが。(例えば、ダイログの内容をむりやり書きかえるとか。誰かやっていたなぁ)

外部から操作することの限界

 悲しいことにSELECTコマンドでは、画面に隠れている図形は選択でき無いのです。このことを忘れて、あれ?とプログラムを見直したことが、何回あったことか。
 (SELECT ALLの場合は画面に隠れていても、すべてが選択されます。)
 故に、一度ZOOM ALLさせてからSELECTし、ZOOM Preで元の画面に戻すことになります。
 この間、画面が切り替わりあまり気持ち良くありません。

 また、オブジェクトの特定ができません。(LISPではできるらしい。)

 オブジェクトそのものを変更できない。
 DXFファイルを書き換えて、それを読み込むという手である程度のことはできますが、かなり危ないことをやっているような気がします。
 

コマンド、システム変数の研究

 これは、マクロでも同じ(たぶんLISPでも同じ)ですが、開発はひたすらコマンドラインの変化とシステム変数の研究になります。
 例えば、TEXTコマンドの場合、スタイル設定で文字高さが設定されていると、文字高さを聞いてきません。
 また、ーSTYLEコマンドでは、縦書きできるスタイルの場合は「縦書き?」を聞いてきますが、欧文では聞いてきません。
 この辺をいちいちプログラム上で対応する必要がでてきます。

 あらかじめ、設定できることは設定しておいて、なるべくコマンドラインとは対話しないほうが安心です。
 たとえば、ブロック挿入(INSERT)。
 通常であれば、挿入点指示→大きさ→回転等になりますが、あらかじめオプションで大きさ、回転角度を指定しておけば、後は挿入点指示だけで済みます。
 コマンドラインをずっと監視する必要が無くなり、プログラムとしては非常に簡単になります。

 また、LTのバージョンによりコマンドラインが少しずつ違っています。
 LT97/98専用とうたっているのは、この辺を考慮していないからです。

Delphiカスタマイズが得意とする分野
 
 一方的にコマンドを送る自動作図、連続処理のようなものには十分通用すると思っています。
 AcadToolも最初はそのために作られたようですから。
 外部から操作する弱点は、一旦描かれたものを書き換えることが並大抵ではできないということです。
 危険を承知でDXFファイルの書換えをするか、消去して書き直すしか手がないのです。

ダイログを表示させない工夫

 コマンドラインから操作する関係上、ダイログが出てしまってはお手上げです。
 そのためか、AcadToolには、ダイアログをキャンセルクローズする関数も用意されています。

 ファイルダイアログはシステム変数FILEDIA、印刷、その他のダイアログはCMDDIAの値を書き換えてダイログ表示をコントロールします。
 また、コマンドにより頭に「−」を付けるとコマンドラインで使えるコマンドもあります。
 LT95,97/98,2000と「−」の付くコマンドは少しずつ増えてきています。

タイミングの問題

 環境により、コマンドを送るタイミング、コマンド履歴を取るタイミングが合わない時があります。
 開発を始めた頃(LTLinkを使っていた頃)は、これでかなりてこずりました。
 タイマーを入れて回避という手もありますが、如何ほどが最適なのか判断できませんし、長すぎれば待ち時間が勿体無いです。
 タイマーイベントを使って1000分の何秒かに1回、コマンドラインを監視し、希望の文字であれば次の処理に進むというのが正解のようです。
 こういう手法を教えてもらうまでは、WHILEループでひたすらコマンドラインを監視していました。その方が、プログラムとしては非常にわかりやすいですが、かなり危ないことのようです。
 
 AcadToolには、「指定の文字列が現れたら」、「コマンド待ちになったら」などのイベントも用意されています。
 また、イベントタイマーもAutoCADが処理中は、イベントを発生させないという専用のものが用意されています。
 安定して動かすには、イベントタイマーなどをうまく使うのがその最大のテクニックのようです。

オブジェクトの情報を取得する(1)
 
 簡単には、LISTコマンドで情報をテキストスクリーンに表示させ、コマンド履歴からそれを取得します。
 コマンド履歴はAcadToolで簡単に取得できます。
 LISTの場合、ある行数で「続行する場合は、ENTERキー・・・」の表示が出て、コマンド待ち状態になります。
 これに対して確実に「ENTER」を送る必要があります。
 これには、AcadToolの「ある特定の文字列がコマンドラインに現れたら・・・」というのを使っています。
 
 取得されるコマンド履歴は、テキストスクリーンのように行ごとに分かれておらず、すべての文字がつながった状態で取得されます。
 このつながった文字列の中から情報を取得するのは、かなり厄介なことになります。

 テキストスクリーンをクリップボード経由でDelphiのStringsにコピーするとすると、テキストスクリーンと同じように行単位で取得できます。
 (DelphiでのサンプルはSHELL FACTORYに公開されています。行単位で取得するには文字列をCRLFで切り分ける必要があります)
 
 コマンド履歴、テキストスクリーンの容量は限られているようで、たくさんの情報を一度に得るには、LOGFILEを使います。
 LOGFILE名はユーザーの環境によって違います。また、どのフォルダに作成されるかも一概に決められないようです。
 このため、一時LOGFILE名を待避させ、絶対パスを指定したユニークなファイル名で作成するほうが安全です。

オブジェクトの情報を取得する(2)

 DXFファイルを使えば、すべての情報が取得できます。座標値等の取得精度も最大16桁までいけます。
 DXFOUTのオプションで、オブジェクト、バージョン、精度を指定できます。

 AcadToolにも専用の関数が用意されています。

登録されているレイヤ、スタイル情報等を取得する

 これは、一覧を使うのが簡単で速いようです。たとえば、レイヤであれば、「-LAYER ? * 」。
 その後、コマンド履歴か、テキストスクリーンから情報を取得します。

 DXFファイルを使う場合、オブジェクト選択では、そのオブジェクトに関係する情報しか取得できません。
 すべてを選択する必要があります。故に、ファイルサイズによって時間がかかることも考えられます。

テキストスクリーンを消す

 LISTコマンドを実行すると必ずテキストスクリーンがアクティブになります。
 画面がチラチラするわけです。
 これを回避するには、テキストスクリーンの大きさを一時最小にしておき、処理終了後元に戻す必要があります。
 プログラムで大きさを変更するより、ユーザー側で手動で小さくしてもらったほうが、「テキストスクリーンが無くなった・・・」と
 大騒ぎにならなくて良いかもしれません。

 AcadToolには、AutoCADに限らずWindowの大きさを取得、変更する関数も用意されています。

取得精度について

 LISTでの座標精度はLUPRECを最大にしても小数点以下の桁数8桁です。
 精度が必要な場合は、必然的にDXFファイル(小数点以下の桁数最大16桁)に書き出すことになります。 
 特に、取得座標を元に、作図を行う場合は、DXFファイルを使ったほうが良いです。

 簡単な作図なら精度は必要無いと考えがちですが、座標値の取得時点で数値が丸められているとになかなか気づきません。
 取得線分の端点からプログラムで線を引いたとしても、拡大してみると端点はつながっていません。
 DXFファイルの小数点以下16桁精度で取得した場合は、確実につながります。

図形の属性を変更する

 一番簡単なのが「−CH」(CHANGE)コマンドです。
 例えば、文字列の場合、ーCH単独では、高さ、回転角度、文字ぐらいしかの変更しかできませんが、「−STYLE」コマンドとうまく組み合わせれば、ほとんどの属性が変更できます。(たぶん、そこまでする人はいないと思う)

 ダミーでオブジェクトを描いて、ペインター(PAINTER)でその属性をコピーという手も考えられますが、ダイログのオプションをどうやって書きかえるのか?

 CHANGEコマンド等で変更できないものは、一度選択図形をDXFOUTし、それを書き換えて読み込むという手法になります。
 R12JタイプのDXFファイルならそのまま読み込めるというのがヒントです。もちろん、 これはAutoDeskが認めている方法ではありません。
 DXFファイルの知識が無いとかなり危ないことになります。書き換えは非常に危険です。
 引出線(LEADER)の注釈文字の属性を強引に書き換えて失敗した経験があります。
 DXFファイルは情報取得用、または新たな作図用に使うべきという考えになりつつあります。
 

省略コマンド、省略オプションは使わない。

 たとえば、「ZOOM Pre」。これは「Z P 」でも同じ「前画面表示」ですが、何かのタイミングでコマンドラインが崩れた時、「P 」だけがコマンドラインに入力され、AutoCADには「PAN 」コマンドだと解釈されてしまいます。
 確実な方法は「ZOOM Previous 」。コマンドラインの問いに「Y 」「N 」で答える場合も「Yes 」「No 」の方が確実です。
 ちなみに短縮コマンド「N」はNEW(新規図面作成)です。
 ほとんどのオプションが単語そのものでいけるみたいです。(TEXTコマンドの位置指定オプションJはJustのようです。)

スクリプトファイルを使う

 コマンドラインから多くのコマンドを実行する場合、プログラムであらかじめスクリプトファイルを作っておき、それを実行させるのが定石らしいです。
 多くの優秀なプログラマがそうしています。
 コマンドラインでは、一度に多くの文字列を送れないというのと、AutoCADが複数あった場合アクティブなAutoCADが変わると文字列の送り先も変わってしまうというのがその理由らしいです。(らしい、らしい・・・と続くのは使ったことが無いためです。坂井さんの受け売り)
 そんな理由でAcadTooにもスクリプト作成、実行(RunScript)という関数があるみたいです。
l

何故、LISPを使わないのか

 答えはひとつ。LT97ではLISPが使えないからです。誰もがLISPを使える環境ではないからです。

 LISPが使えるIntelliCAD2000日本語版に期待をしています。
 と言いながら、禁断のDelphiカスタマイズはなかなか止められません。
 と言いながら、IntelliCAD2000のVBAにかなりの興味を持っています。i
  

最高のカスタマイズ環境
 
 LT97/98で考えるなら、LISP(ACE−LT)でコマンドを作り、Delphiで取りまとめするのが最高だと思っています。
 AutoCADをガンガンいじくりまわせます。が、しかし、ACE−LTは無い。
  

所詮一過性のもの

 LT97/98をターゲットにカスタマイズを行ってきたのですが、LT2000の登場と共に不要となったものが多くあります。
 やっとLTを理解しカスタマイズが終わってきた頃にLTがバージョンアップ。どうもこれの繰り返しのようです。
 私が作っているものは、所詮一過性のもの。ふと、何のために多くの時間を費やして来たんだろう・・・と思ってしまいます。
 いつまで経ってもやめられない、いつまで経っても終わらないカスタマイズ。何ごとも程々に・・・自戒をこめて。