DelphiでAutoCAD その2

前回の記事でObjectARX側の処理を書きました。今回はDelphi側の処理を書きます。

まずは、前回のARX内のコマンド登録関数の定義。

  function CommandRegister(Group, Cmd: PChar; const CmdFlags: Integer; Func: CMDFUNC): Boolean; stdcall; external ARX名;

上記登録関数を使ってDelphiの関数をAutoCADコマンドとして登録します。
まず、プロジェクトファイル*.dprでARXから呼ばれる関数をエクスポートします。

{$R *.res}
exports
  RegSetup,
  RegInit,
  RegFinal;
begin
end;

次にユニットで、実際の処理を書きます。

// セットアップ
procedure RegSetup(AcadWnd: HWND); stdcall;
// 初期化
procedure RegInit; stdcall;
// 終了処理
procedure RegFinal; stdcall;

procedure cmdTest(pAcadApp: IAcadApplication); stdcall;

implementation

procedure RegSetup(AcadWnd: HWND); stdcall;
const
  GroupName: String = 'TESTARX';
  ACRX_CMD_TRANSPARENT = $00000001;
  ACRX_CMD_USEPICKSET = $00000002;
  CMD_NORMAL_FLAGS: Integer = ACRX_CMD_TRANSPARENT Or ACRX_CMD_USEPICKSET;
begin
  // 下記処理で、AutoCADでTESTコマンドを実行した時に、cmdTest関数が呼び出されます。
  CommandRegister2(PChar(GroupName), PChar('TEST'),  CMD_NORMAL_FLAGS, cmdTest);
end;

procedure RegInit; stdcall;
begin
// データモジュールの構築等の初期化処理を行います
end;

procedure RegFinal; stdcall;
begin
// モーダレスフォーム等の構築したデータを解放する
end;

procedure cmdTest(pAcadApp: IAcadApplication); stdcall;
var
  Pt1, Pt2: Variant;
  Doc: IAcadDocument;
  Line: IAcadLine;
begin
// ここで、コマンドで実行する処理を書く
  Doc := pAcadApp.ActiveDocument;

  Pt1 := VarArrayCreate([0,2], varDouble);
  Pt2 := VarArrayCreate([0,2], varDouble);

  Pt1[0] := 0;
  Pt1[1] := 0;
  Pt1[2] := 0;

  Pt2[0] := 100;
  Pt2[1] := 100;
  Pt2[2] := 0;
//  原点から(100,100,0)の点に直線を引く
  Line := Doc.ModelSpace.AddLine(Pt1, Pt2);
end;

こんな感じでAutoCADにコマンドを登録出来ます。今回と前回のコードはAutoCAD2006とDelphi7でのコードになりますので、今のAutoCAD2012、DelphiXEの場合はそれに合わせて処理を変更する必要があると思います。
注意点としては、このコマンドからモードレスフォームを表示した場合メッセージ処理が上手く処理されないのか少々不具合があります。
Tabキーが処理されないのかTabキーでのフォーカス移動と、TActionのOnUpdateでの有効/無効の切り替えが効きません。この辺りの処理は自前で処理する必要があります。これは、モーダルフォームを表示した場合は問題ありません。
後、モードレスフォームを表示した場合は確実に解放処理を行っておかないとAutoCAD終了時にエラーが起きます。こんな所でしょうか。