Grossa Speaks Final

コンピュータに関するテーマを
気の向くまま取り上げています。
(時々雑談...)

DenSin 作成ノート その7

2006年10月20日 | Programming
ようやく、ほぼ完成。ふー。
電気設備設計の仕事が入ったので、少し使って見る。

Delphi6で作成したDenSinのコードは次の通り。

unit UntiDenSin;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComObj, StdCtrls, ExtDlgs, ExtCtrls, FileCtrl, Grids, ImgList,ShellApi;

type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
FileListBox1: TFileListBox;
DirectoryListBox1: TDirectoryListBox;
DriveComboBox1: TDriveComboBox;
Image1: TImage;
Image2: TImage;
Button1: TButton;
Bevel1: TBevel;
procedure FormActivate(Sender: TObject);
procedure DirectoryListBox1Change(Sender: TObject);
procedure DirectoryListBox1Click(Sender: TObject);
procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Button1Click(Sender: TObject);

private
{ Private 宣言 }
public
{ Public 宣言 }
end;

var
Form1: TForm1;
ICAD: OLEVariant;
ICADHWND: HWND;
BlkOutName: string[255]; //外部ブロック(ファイル)
BlkImgName: string[255]; //外部ブロック(イメージファイル)
BlkOnlyName: string[255]; //内部ブロック
BlkX,BlkY: string[255]; //X,Y方向の尺度
//BlkAngle: string[255]; //角度
MyIndex: integer;
USERS1: string[255]; // BlkOutName
USERS2: string[255]; // BlkOnlyName
USERS3: string[255]; // BlkX
USERS4: string[255]; // BlkY
//USERS5: string[255]; // BlkAngle
IsBlkLoad: boolean; //ブロックのイメージがLoadされているか
Images: array[0..29] of TImage; //ブロック表示用
BlkWidth,BlkHeight: integer; //ブロックの大きさ
BlkNumber:integer; //1ディレクリ内の格納ブロック数
CntOld,CntNow: integer; //開かれている図面の数
const BlkNumberMax=30; //1ディレクリ内の最大格納ブロック数
const BlkColumn=5; BlkRow=6; //ブロックのイメージ表示 列数、行数

implementation

{$R *.dfm}

//IntelliCADが起動しているかをチェック
//ブロック挿入用のdensin.lsp(AutoLisp)をロード
//ブロック画像(wmfファイルのみ)を表示するimages(配列)を生成
//ブロック指定用のImage1の設定
//
procedure TForm1.FormActivate(Sender: TObject);
var
x,xi,yi:integer;
begin
ICADHWND := FindWindow('IntelliCADApplicationWindow',nil);

if IsWindow(ICADHWND) then
begin
//IntelliCADを検出
Icad := GetActiveOleObject('ICAD.Application');

//初期設定
IsBlkLoad := False;
BlkWidth := 25;
BlkHeight := 25;
CntOld := 0;
CntNow := 0;

//Imagesを生成 横5個 縦6個 (固定)
xi := 0;
yi := 0;

for x:=0 to BlkNumberMax - 1 do
begin
Images[x]:=TImage.create(Form1);
case x of
0..4: xi := 0;
5..9: xi := 1;
10..14: xi := 2;
15..19: xi := 3;
20..24: xi := 4;
25..29: xi := 5;
end;

case x of
0..4: yi := x;
5..9: yi := x - 5;
10..14: yi := x - 10;
15..19: yi := x - 15;
20..24: yi := x - 20;
25..29: yi := x - 25;
end;

with Images[x] do
begin
parent :=form1;
Stretch := true;
width := BlkWidth;
height := BlkHeight;
top := xi*BlkHeight;
left := yi*BlkWidth;
end;
end;

//ブロック選択用Image1の設定
with Image1 do
begin
width := BlkWidth * BlkColumn;
height := BlkHeight * BlkRow;
top := 0;
left := 0;
Image1.BringToFront;
end;

end
else
begin
ShowMessage('IntelliCADが起動していません。' +#13 + 'DenSinを終了します。');

//アプリケーションの終了
Application.Terminate;
end;

end;

//シングルクリックでディレクトリを開く
//
//
//
//
procedure TForm1.DirectoryListBox1Click(Sender: TObject);
begin
DirectoryListBox1.OpenCurrent;
end;

//wmfファイルを含むフォルダーが変更されたら
//前に選択されて表示したImagesをクリアし
//今回選択されたImagesを読み込む
//
//
procedure TForm1.DirectoryListBox1Change(Sender: TObject);
var
x:integer;
begin
//前のImagesのクリア
IsBlkLoad := False;
for x:=0 to BlkNumberMax - 1 do
begin
with Images[x] do
begin
Picture.Graphic := nil;
end;
end;

//今回のImagesの読み込み
BlkNumber := FileListBox1.Count;
for x:=0 to BlkNumber -1 do
begin
with Images[x] do
begin
Picture.LoadFromFile(FileListBox1.Items.Strings[x]);
IsBlkLoad := True;
end;
end;

Image2.Picture.Graphic := nil;

end;

//マウスでクリックしたブロックイメージを表示
//
//
//
//
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
xi,yi:integer;
begin
xi := 0;
yi := 0;

if IsBlkLoad then
begin
//マウスクリックしたwmfファイル位置の取得
case x of
0..25: xi := 1;
26..50: xi := 2;
51..75: xi := 3;
76..100: xi := 4;
101..125: xi := 5;
end;

case y of
0..25: yi := 1;
26..50: yi := 2;
51..75: yi := 3;
76..100: yi := 4;
101..125: yi := 5;
126..150: yi := 6;
end;

//選択したwmfファイルがファイルリストの何番目かを求める
MyIndex := xi + ((yi - 1) * BlkColumn) ;

if MyIndex > BlkNumber then
begin
//ShowMessage('ブロックが選択されていません。');
Image2.Picture.Graphic := nil;
end
else
begin
//選択したブロックのイメージを表示
Image2.Picture.LoadFromFile(FileListBox1.Items.Strings[MyIndex - 1]);

//wmfファイルの絶対パスを求める
BlkImgName := FileListBox1.Directory + ''
+ FileListBox1.Items.Strings[MyIndex - 1]; //Chogehogehogehoge.wmf

end;
end;

end;

//外部ブロックファイル名に変換
//同上ファイル名を内部ブロック名に変換
//Lispを実行
//
//
procedure TForm1.Button1Click(Sender: TObject);
begin
//現在開かれている図面の数を得る
CntNow := Icad.Documents.Count;
if CntNow = 0 then //図面の数がゼロなら
begin
ShowMessage('開かれている図面がありません。' + 'DenSinを終了します。');
Application.Terminate;
end;

if Image2.Picture.Graphic <> nil then
begin
//wmfファイル名からdwgファイル名を求める
BlkOutName := ChangeFileExt(BlkImgName,'.dwg');//Chogehogehogehoge.dwg

//IntelliCADをアクティブにする
SetForegroundWindow(ICADHWND);

//外部ブロック名の設定(AutoLisp用)
ICAD.ActiveDocument.SetVariable('USERS1',BlkOutName);

//内部ブロック名を求める
BlkOnlyName := ExtractFileName(BlkOutName);//hogehoge.dwg
MyIndex := LastDelimiter('.',BlkOnlyName);
Delete(BlkOnlyName,MyIndex,4);//hogehoge

//内部ブロック名の設定(AutoLisp用)
ICAD.ActiveDocument.SetVariable('USERS2',BlkOnlyName);

//X方向の尺度の設定(AutoLisp用)
BlkX := Edit1.Text;
ICAD.ActiveDocument.SetVariable('USERS3',BlkX);

//Y方向の尺度の設定(AutoLisp用)
BlkY := Edit2.Text;
ICAD.ActiveDocument.SetVariable('USERS4',BlkY);

//角度の設定(AutoLisp用)
//BlkAngle := Edit3.Text;
//ICAD.ActiveDocument.SetVariable('USERS5',BlkAngle);

//Lispをロードする
//A図面のみでインサート  最初のみ Lispをロード
//B図面を開いてインサート 最初のみ Lispをロード
//A図面を閉じてB図面でインサート 最初のみ Lispをロード
if CntNow <> CntOld then //開かれている図面の数に変化があれば
Icad.LoadLisp('densin.lsp'); //Lispをロードする
CntOld := CntNow;

//Lispを実行する
Icad.RunCommand('densin' + #13);
end
else
ShowMessage('ブロックが選択されていません。');

end;

end.

densin.lspのコードは次の通り。

;;File Name "densin.lsp"
;;Command Name "densin"
;;
;;Action "DenSin用ブロック挿入"
;;
;;;;How to Use
;;(1)単体では動作しない
;;(2)DenSin.exeから自動ロード、自動実行
;;(3)現在は操作表示を有効にしている
;;Code Begin----------
;*****エラー処理(数値以外の入力)
(defun *error* (msg)
(princ msg)
(princ)
)
(defun C:densin()

;*****外部ブロック名をDenSinより取得
(setq exblk_name (getvar "USERS1"))

;*****内部ブロック名をDenSinより取得
(setq inblk_name (getvar "USERS2"))

;*****内部ブロック名の確認
(if (tblsearch "block" inblk_name)
(setq ins_name inblk_name)
(setq ins_name exblk_name)
)

;*****直行モードをOFF
(setvar "ORTHOMODE" 0)

;*****X,Y方向の尺度をDenSinより取得
(setq ins_x (getvar "USERS3"))
(setq ins_y (getvar "USERS4"))

;*****表示重視の場合
;DenSin側で選択したブロックが見える(設定した尺度が反映されている)
:IntelliCAD側でEnterまたは右クリックで同じブロックを連続して挿入できない。

;(setq ins_p "0,0,0");;ブロックを原点に挿入
;(setq ins_a "0")
;(command "insert" ins_name ins_p ins_x ins_y ins_a)

;(setq myblock (entlast));;挿入したブロックを選択

;(command "move" myblock "" ins_p );;ブロックを移動
;(setq ins_np (getpoint))
;(command ins_np)

;(setvar "ORTHOMODE" 1);;直行モードをON

;(command "rotate" myblock "" ins_np );;ブロックを回転

;*****操作重視の場合
;IntelliCAD側でクリックするまで、縮尺図面ではブロックが見えない(尺度が1:1)
:IntelliCAD側でEnterまたは右クリックで同じブロックを連続して挿入できる。

(command "insert" ins_name)
(setq ins_p (getpoint))
(setvar "ORTHOMODE" 1);;直行モードをON
(command ins_p ins_x ins_y)

)
;;Code End-------------

最新の画像もっと見る

コメントを投稿