AutoCAD の LISP でダイアログの UI を作るのは面倒
AutoCAD で簡単なツールを作るのに便利なのが AutoLISP ですが、ユーザとの入出力は、作図領域かコマンドライン領域で行う事が殆どです。
一応、ファイル選択ダイアログは用意されていますし、簡単なメッセージなら、(alert "出来た!")
とかアラートダイアログで表示できます。
しかし、
- メッセージを表示して、ユーザーに「OK」か「Cancel」を選択させる (VBA で言う MsgBox)
- メッセージを表示して、ユーザーに文字を入力させる (VBA で言う InputBox)
という、ごく単純なダイアログが欲しい時があります。
LISP でダイアログを表示するには、DCL を使う
LISP でダイアログを表示するには、DCL (ダイアログ・コントロール・ランゲージ) で記述されたファイルを用意し、それを LISP からロードして使います。
しかし、MsgBox や InputBox を使うためだけに、都度 DCL ファイルを用意するのは馬鹿らしいわけです。
別途 DCL ファイルを用意せずに、MsgBox や InputBox を使えるようにする
というわけで、関数内で DCL を生成し、目的を果たしたら DCL を消すような関数を作ればよいわけです。
MsgBox もどき
;;;***************************************************
;;;
;;; MsgBox関数
;;;
;;;***************************************************
(defun msg_box(
str_label
/
dcl_file
dcl_fnum
ret_val
ret_num
)
;dclファイル名生成
(setq ret_val "" dcl_file (vl-filename-mktemp "input_box.dcl"))
;dclファイル作成
(setq dcl_fnum (open dcl_file "w"))
(foreach str_tmp
(list
"inputbox : dialog"
"{"
" label = \"InputBox\";"
" : text {"
(strcat " label = \"" str_label "\";")
" }"
" ok_cancel;"
"}"
);list
(write-line str_tmp dcl_fnum)
);foreach
(close dcl_fnum)
;ダイアログをロードする
(setq dcl_fnum (load_dialog dcl_file))
(if (new_dialog "inputbox" dcl_fnum)
(progn
(action_tile "accept" "(done_dialog 1)")
(action_tile "cancel" "(done_dialog 0)")
(setq ret_num (start_dialog))
(unload_dialog dcl_fnum)
(if (zerop ret_num)
(setq ret_val nil)
(setq ret_val T)
);if
);progn
);if
;dclファイルの削除
(vl-file-delete dcl_file)
(progn ret_val)
);defun
MsgBox 表示の用の DCL ファイルを作成・ロードし、引数で渡したメッセージを表示します。
「OK」が押されたら真、「Cancel」が押されたら偽が返ります。
注意点は、引数の文字列には\n
の改行は使えません。
InputBox もどき
;;;***************************************************
;;;
;;; InputBox関数
;;;
;;;***************************************************
(defun input_box(
str_label
str_edit
/
dcl_file
dcl_fnum
str_tmp
ret_val
ret_num
)
;dclファイル名生成
(setq ret_val "" dcl_file (vl-filename-mktemp "input_box.dcl"))
;dclファイル作成
(setq dcl_fnum (open dcl_file "w"))
(foreach str_tmp
(list
"inputbox : dialog"
"{"
" label = \"InputBox\";"
" : text {"
(strcat " label = \"" str_label "\";")
" }"
" : edit_box {"
" key = \"input_text\";"
" edit_width = 50;"
" }"
" ok_cancel;"
"}"
);list
(write-line str_tmp dcl_fnum)
);foreach
(close dcl_fnum)
;ダイアログをロードする
(setq dcl_fnum (load_dialog dcl_file))
(if (new_dialog "inputbox" dcl_fnum)
(progn
(action_tile "accept" "(setq ret_val (get_tile \"input_text\"))(done_dialog 1)")
(action_tile "cancel" "(done_dialog 0)")
(set_tile "input_text" str_edit)
(setq ret_num (start_dialog))
(unload_dialog dcl_fnum)
(if (zerop (* ret_num (strlen ret_val)))
(setq ret_val nil)
);if
);progn
);if
;dclファイルの削除
(vl-file-delete dcl_file)
(progn ret_val)
);defun
InputBox 表示の用の DCL ファイルを作成・ロードし、ダイアログを表示します。
引数の内容は下記の通り。
- 第一引数は、TextBox の上部に表示されるメッセージ(
\n
不可) - 第二引数は、TexyBox 内に記入される文字(
\n
不可)
「OK」を押下時に TextBox 内に文字が記載されていれば、その文字が返ります。
「Cancel」が押されるか、「OK」押下時に TextBox の内容が空なら、偽が返ります。
コマンドラインへの入力に対して、この InputBox を用いる利点は、"
や\
を直接入力できることです。
コマンドラインに記載するときは、\"
や\\
と記載しなければならないのですが、それを考慮しなくてよくなります。
マルチテキスト(MTEXT) の書式コード付き文字を直接編集する
AutoCAD のマルチテキストオブジェクトは、一つの文字オブジェクト内で改行したり、文字の大きさを変えたり、文字に色を付けたりと、文字の書式を変更できるのが便利なのですが、プロパティを見ると分かる通り、文字に付与された書式情報は書式コード文字列として付与される形になっています。
モノとして近いのは、Rich Text Format でしょうか? { }
で囲う所とか、仕様も近いと思われます。
マルチテキストの標準エディタ「マルチテキストエディタ」で編集する際には、書式コードが見えない状態での編集になりますが、マルチテキストのエディタを外部エディタに変更すると、この書式コードを直接編集できます。
しかし、書式コードは可読性は低いため、普段は標準の「マルチテキストエディタ」を使用したいけど、細かい調整時に直接書式コードを編集したい場合は、その都度エディタの切り替えを行うのも面倒です。
そこで、先刻の InputBox ルーチンを使用して、MTEXT の書式コード付き文字列を直接編集するコマンドを作成してみましょう。
;マルチテキストの装飾文字付文字列を、そのまま充てるコマンド(要 input_box)
(defun C:EDIT_MTEXT_VALUE (
/
ename
elist
str_text
ret_val
)
(if
(and
(setq ename (entsel "MTEXTオブジェクトを選択"))
(setq ename (car ename))
(setq elist (entget ename))
(equal "MTEXT" (cdr (assoc 0 elist)))
);and
(progn
(setq str_text (cdr (assoc 1 elist)))
(setq ret_val (input_box "MTEXTの文字を編集" str_text))
(if ret_val
(entmod (subst (cons 1 ret_val) (assoc 1 elist) elist))
);if
);progn
);if
(princ)
);defun
マルチテキストの「文字内容」は、何故プロパティから編集できない?
Autodesk は、何故プロパティの「文字内容」を直接編集できないようにしたんでしょうか?
矛盾した書式コードを記載する事で、データが破損する可能性があるからでしょうか?
しかし、下記の Autodesk のヘルプの様に、外部エディタで書式コードを直接記入する事を、拒んでいるわけではなさそうです。
データ破損の件で言えば、TrustedDWG の話を思い出します。
Autodesk 社以外のアプリが作成したDWG ファイルには、TrustedDWG のフラグが立っていない為、Autodesk 社のアプリで開くと警告が出るようになっています。
Autodesk 曰く非TrustedDWG はファイルとしての互換性が保証されないので、最悪破損してしまう可能性もあるとの事ですが、TrustedDWG のフラグが出来る前のバージョンの AutoCAD アプリケーション(確か 2004) で、LISP 等のツールを使用せずに、通常オペレーションだけで作成した DWG ファイルが、AutoCAD から開けなくなり、ダメもとで互換 CAD で開いて保存し直したら、再び AutoCAD から開けるようになった経験がある私としては、Autodesk 社のアプリが作る DWG だから大丈夫とは、とても言えないんじゃないかなぁ、と思ってしまう訳です。
しらんけど。