使える!AutoCAD&LTカスタマイズブックの追加情報 (2011. 4. 7 更新)
■2007年に第7章と第8章を執筆させて頂きました。
訂正箇所、追加情報については、下記を参照して下さい。
■訂正箇所
・P244の「サンプルコード(AutoCAD/LT2007以降)」
function ... (const cmd : string ):... の string を widestring に (漢字が送信できないため)
wmes : array[0..255] of ... の 255 を 511 程度に (長い文字列が送信できないため)
※CD-ROMに収録されている Acad8Ctrl.pas も変更して下さい。
・P237の「カスタムプログラムを作る上での注意点」
MessageBox( ... MB_YESNO)=mrYes then の mrYes を IDYES に
■DelphiでActiveXを使う
・Delphi で VarArrayCreate がエラーになる場合は、uses節に Variants を追加してください。(2009.2.28
追加)
■AutoCAD/LT 2011 での挙動 ( 2010.4.20 追加)
AutoCAD/LT にはコマンドラインが2つあります。
テキストウィンドウ(いつもは隠れている履歴ウィンドウ)のコマンドラインと、コマンドウィンドウのコマンドラインです。
AutoCAD/LT 2010 までは、この2つのコマンドライン、コマンド履歴の内容は = (イコール)でしたが、
AutoCAD/LT 2011 から若干挙動が違うものになっています。
『使える・・・』 では、取得しやすいテキストウィンドウから情報を取得していましたが、
コマンドラインの文字列取得は、コマンドウィンドウのコマンドラインから取得。
コマンド履歴の文字列取得は、テキストウィンドウの履歴ウィンドウから取得するようにして下さい。
テキストウィンドウの履歴ウィンドウのハンドルだけ、コマンドウィンドウのコマンドラインウィンドウだけを取得するようにして下さい。
テキストウィンドウが一度も表示されていない状態で、テキストウィンドウのコマンドラインのウィンドウハンドルを取得しにいくのが
まずいようです。また、表示された後でも、取得した文字列はコマンドラインより古いものになっています。
コマンドウィンドウが浮動の時、そのウィンドウはトップレベルになり、固定の時は、メインウィンドウの子ウィンドウになります。
なので、トップレベルのウィンドウを探し、見つからなければ、子ウィンドウを探すことになります。
■Delphi 2009 / 2010 で使う ( 2010.4.20 追加)
Delphi 2009 から String が String/AnsiString から UnicodeString に、Char が AnsiChar
から WideCharに、
PChar が PAnsiChar から PWideChar なっています。
この関係で、P.246 下の 『ウィンドウの文字列を取得』 、P.244 下の 『AutoCADにコマンドを送信』 はうまく動きません。
変更箇所については、メールで問い合わせて下さい。
『自称』 読者 の方であれば、Acad11Ctrl ユニット (鋭意作成中...) を差し上げます。
■Windows 7 及び AutoCAD 62bit 版 ( 2011. 4. 7 変更)
AutoCAD
/ LT (64bit版)のクラス名が異なっています。
かなり乱暴ですが、ウィンドウのキャプションが "AutoCAD " で始まり、クラス名の先頭が
"Afx:" で ":8:" がある、
これで AutoCAD / LT 2004〜2011
(32bit版、64bit版共)までいけました。
Windows 7
でも問題なく動くようです。
■収録されていないがよく使いそうな Win32API
・IsWindowEnabled( h : HWND) ・・・ ウィンドウがユーザーの入力を受け取れるかどうか
AutoCAD のメインウィンドウが False の時は、ダイアログが表示されていると判断できる
例えば、保存しますか?のダイアログにキーを送る場合(2009. 8.15 追加)
procedure TForm1.Button1Click(Sender: TObject);
var
h, hActive : HWND;
begin
//AutoCADのメインウィンドウのハンドルを取得
h :=
GetAcadMainHandle;
//入力を受け取れない = たぶんダイアログが表示中??...
if IsWindowVisible(h) and not IsWindowEnabled(h) then begin
//「保存しますか?」のダイアログを探す
hActive := FindWindow('#32770', 'AutoCAD LT');
//アクティブなウィンドウのオーナーが h であれば
//たぶん間違いないと判断する
if GetWindow(hActive, GW_OWNER) = h then begin
//ダイアログをアクティブにする
SetForegroundWindow(hActive);
//[ESC]キーを押す
keybd_event(VK_ESCAPE, 0, 0, 0);
//[ESC]キーを離す
keybd_event(VK_ESCAPE, 0, KEYEVENTF_KEYUP, 0);
{
//Nキーを押す
keybd_event(Ord('N'), 0, 0, 0);
//Nキーを離す
keybd_event(Ord('N'), 0, KEYEVENTF_KEYUP, 0);
}
end;
end;
end;
例えば、文字編集ダイアログの場合(2009. 8.16 追加)
※同じプログラムからコマンドを送信しているときは、うまく動きません。
procedure TForm1.Button2Click(Sender: TObject);
var
h, hActive, hEdit : HWND;
s : string;
i : integer;
begin
s :=
'TESTてすと';
h := GetAcadMainHandle;
//たぶんダイアログが表示中...
if IsWindowVisible(h) and not IsWindowEnabled(h) then begin
//「文字を編集」のダイアログを探す
hActive :=
FindWindow('#32770', '文字を編集');
//アクティブなウィンドウのオーナーが h であれば
//たぶん間違いないと判断する
if GetWindow(hActive, GW_OWNER) = h then begin
hEdit := FindWindowEx(hActive, 0, 'RichEdit20A', '');
//Editの文字列を取得
Edit1.Text := GetWindowString(hEdit);
//文字の送信
for i := 1 to Length(s) do begin
//1文字送る
SendMessage(hEdit, WM_CHAR, Word(s[i]), 0);
end;
Windows.SetFocus(hEdit);
SetForegroundWindow(hActive);
end;
end;
end;
■Acad8Ctrlユニットで、履歴を行単位で取得する例 (2008.12.28 追加)
procedure TForm1.Button1Click(Sender: TObject);
var
sl : TStringList;
begin
if SetAcadActive then begin
sl := TStringList.Create;
try
sl.Text := GetAcadHistClip;
MessageBox(Handle, PChar('取得した履歴の行数 = ' + IntToStr(sl.Count)), '', MB_OK);
finally
sl.Free;
end;
end;
end;
■C++BuilderでActiveXを使う
・バインドされているかの判断は、ZwCADでのコードを参考にして下さい。
http://izawa-web.com/zwbcbactivex.txt