☆JWWファイルの超簡易表示 その3
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, ComCtrls; type TForm1 = class(TForm) PaintBox1: TPaintBox; TreeView1: TTreeView; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormMouseWheelDown(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean); procedure FormMouseWheelUp(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean); procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure PaintBox1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure PaintBox1Paint(Sender: TObject); procedure FormResize(Sender: TObject); procedure TreeView1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); private ox, oy: Integer; // 原点 ImageWidth,ImageHeight: Integer; // 画面ドットサイズ = PaintBox1のサイズ PaperWidth, PaperHeight: Double; // 用紙サイズ mm_dot: Double; // mm_dot比 view_x1, view_y1, view_x2, view_y2: Double; //ビューエリア DragStart_X, DragStart_Y: Integer; // ドラッグ開始点 DragEnd_X, DragEnd_Y: Integer; // ドラッグ終了点 DragModeKind : Integer; // ドラッグモード 0:移動 1:拡大 2:縮小 DraggingNow : Boolean; // ドラッグ中かどうかのフラグ RubberBandShow : Boolean; // ラバーバンド表示フラグ procedure Calc_mm_dot; // mm_dot比の計算 procedure Calc_ViewArea; // ビューエリアの計算 procedure CLS; // 画面を消す procedure Draw_Paper_Frame; // 用紙枠の描画 procedure Drawdata; // 図面の描画 procedure RubberBand(x1, y1, x2, y2:Integer); // ラバーバンドの描画 procedure SetPaperSize(PaperSize: Integer); // 用紙サイズの設定 procedure SetLayerName; // レイヤー名の設定 public { Public 宣言 } end; var Form1: TForm1; implementation {$R *.dfm} uses Commctrl, jwwunit; const TVIS_CHECKED = $2000; // 初期設定 procedure TForm1.FormCreate(Sender: TObject); var FileName: String; WindowStyles: Integer; begin // TreeViewにCheckBoxを表示させます。 WindowStyles := GetWindowLong(TreeView1.Handle, GWL_STYLE); SetWindowLong(TreeView1.Handle, GWL_STYLE, WindowStyles or TVS_CHECKBOXES); // 初期化 DraggingNow := False; RubberBandShow := False; // ファイルの読み込み FileName := 'c:\jww\Aマンション平面例.jww'; JWWBlockList := TJWWBlockList.Create; // JWWファイル読込み jwwRead(FileName); // 用紙サイズの設定 SetPaperSize(JWWHd.m_nZumen); // mm_dot比の計算 Calc_mm_dot; // ビューエリアの計算 Calc_ViewArea; // レイヤー名及び表示/非表示の設定 SetLayerName; end; // 終了処理 procedure TForm1.FormDestroy(Sender: TObject); begin JWWBlockList.Free; end; procedure TForm1.FormResize(Sender: TObject); begin // mm_dot比の計算 Calc_mm_dot; // ビューエリアの計算 Calc_ViewArea; end; // 用紙サイズの設定 { Paramater 用紙サイズ 0-A0 1-A1 2-A2 3-A3 4-A4 上記以外は、A0サイズとする。サイズを調べるのが面倒だから(^^; } procedure TForm1.SetPaperSize(PaperSize: Integer); // 用紙サイズの設定 begin case PaperSize of 0: begin //A0 PaperWidth :=1189; PaperHeight := 841; end; 1: begin //A1 PaperWidth := 841; PaperHeight := 594; end; 2: begin //A2 PaperWidth := 594; PaperHeight := 420; end; 3: begin //A3 PaperWidth := 420; PaperHeight := 297; end; 4: begin //A4 PaperWidth := 297; PaperHeight := 210; end; else PaperWidth :=1189; PaperHeight := 841; end; end; // mm_dot比の計算 procedure TForm1.Calc_mm_dot; var P1, P2: Double; begin ImageWidth := PaintBox1.Width; ImageHeight := PaintBox1.Height; P1 := ImageWidth / PaperWidth; P2 := ImageHeight / PaperHeight; if (P1 < P2) then mm_dot := P1 else mm_dot := P2; end; // ビューエリアの計算 procedure TForm1.Calc_ViewArea; begin view_x1 := - (ImageWidth / 2.0) / mm_dot; view_y1 := - (ImageHeight / 2.0) / mm_dot; view_x2 := (ImageWidth / 2.0) / mm_dot; view_y2 := (ImageHeight / 2.0) / mm_dot; end; //画面の消去 procedure TForm1.CLS; begin PaintBox1.Canvas.Pen.Mode := pmCopy; PaintBox1.Canvas.Pen.Color := clWhite; PaintBox1.Canvas.Pen.Style := psSolid; PaintBox1.Canvas.Pen.Width := 1; PaintBox1.Canvas.Brush.Color := clWhite; PaintBox1.Canvas.Brush.Style := bsSolid; PaintBox1.Canvas.Rectangle(0, 0, ImageWidth, ImageHeight); end; //用紙枠の描画 procedure TForm1.Draw_Paper_Frame; var x1, y1, x2, y2: Integer; begin // 原点の計算 ox := Round( (0.0 - view_x1) * mm_dot); oy := Round(-(0.0 - view_y2) * mm_dot); // 画面の消去 CLS; // 用紙枠の描画 x1 := Round( (-PaperWidth /2 - view_x1) * mm_dot); y1 := Round(-(-PaperHeight/2 - view_y2) * mm_dot); x2 := Round( ( PaperWidth /2 - view_x1) * mm_dot); y2 := Round(-( PaperHeight/2 - view_y2) * mm_dot); PaintBox1.Canvas.Pen.Color := clBlue; PaintBox1.Canvas.Brush.Style := bsClear; PaintBox1.Canvas.Rectangle(x1, y1, x2, y2); end; procedure TForm1.FormMouseWheelDown(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean); var cx, cy: Double; dx, dy: Double; var Pt: TPoint; begin GetCursorPos(Pt); Pt := ScreenToClient(Pt); if ((Pt.X > 0) and (Pt.X < PaintBox1.Width)) and ((Pt.Y > 0) and (Pt.Y < PaintBox1.Height)) then begin Handled := True; //2倍に拡大 cx := (view_x1 + view_x2) / 2.0; // ビュー中央のX座標 cy := (view_y1 + view_y2) / 2.0; // ビュー中央のY座標 dx := Abs(view_x2 - view_x1); dy := Abs(view_y2 - view_y1); mm_dot := mm_dot * 2.0; view_x1 := cx - (dx / 4.0); view_y1 := cy - (dy / 4.0); view_x2 := cx + (dx / 4.0); view_y2 := cy + (dy / 4.0); Drawdata; end; end; procedure TForm1.FormMouseWheelUp(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean); var cx, cy: Double; dx, dy: Double; var Pt: TPoint; begin GetCursorPos(Pt); Pt := ScreenToClient(Pt); if ((Pt.X > 0) and (Pt.X < PaintBox1.Width)) and ((Pt.Y > 0) and (Pt.Y < PaintBox1.Height)) then begin Handled := True; // 1/2倍に縮小 cx := (view_x1 + view_x2) / 2.0; // ビュー中央のX座標 cy := (view_y1 + view_y2) / 2.0; // ビュー中央のY座標 dx := Abs(view_x2 - view_x1); dy := Abs(view_y2 - view_y1); mm_dot := mm_dot * 0.5; view_x1 := cx - dx; view_y1 := cy - dy; view_x2 := cx + dx; view_y2 := cy + dy; Drawdata; end; end; procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if (ssLeft in Shift) or (ssRight in Shift) then begin DraggingNow := True; DragStart_X := X; DragStart_Y := Y; RubberBandShow := False; DragEnd_X := 0; DragEnd_Y := 0; if (ssLeft in Shift) then DragEnd_X := 1; if (ssRight in Shift) then DragEnd_Y := 1; end; end; procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if (DraggingNow) then begin if (RubberBandShow) then RubberBand(DragStart_X, DragStart_Y, DragEnd_X, DragEnd_Y); if (ssLeft in Shift) and (ssRight in Shift) then begin RubberBand(DragStart_X, DragStart_Y, X, Y); RubberBandShow := True; DragEnd_X := X; DragEnd_Y := Y; end; end; end; procedure TForm1.PaintBox1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var x1, y1, x2, y2: Double; cx, cy: Double; dx, dy: Double; bx, by: Double; P1, P2: Double; begin if (DraggingNow) then begin // ドラッグ処理の終了 DraggingNow := False; if (RubberBandShow) then RubberBand(DragStart_X, DragStart_Y, DragEnd_X, DragEnd_Y); if (Abs(DragStart_X - X) <= 5) and (Abs(DragStart_Y - Y) <= 5) then DragModeKind := 0 // 移動 else begin if (DragStart_X <= X) then DragModeKind := 1 // 拡大 else DragModeKind := 2; // 縮小 end; x1 := view_x1 + (DragStart_X / mm_dot); y1 := view_y2 - (DragStart_Y / mm_dot); x2 := view_x1 + (X / mm_dot); y2 := view_y2 - (Y / mm_dot); dx := Abs(view_x2 - view_x1); dy := Abs(view_y2 - view_y1); bx := Abs(x1 - x2); by := Abs(y1 - y2); cx := (x1 + x2) / 2.0; cy := (y1 + y2) / 2.0; case (DragModeKind) of 0: begin // 移動 cx := (view_x1 +view_x2) / 2.0; cy := (view_y1 +view_y2) / 2.0; dx := x2 - cx; dy := y2 - cy; view_x1 := view_x1 + dx; view_y1 := view_y1 + dy; view_x2 := view_x2 + dx; view_y2 := view_y2 + dy; end; 1: begin // 拡大 P1 := dx / bx; P2 := dy / by; if (P1 < P2) then mm_dot := mm_dot * P1 else mm_dot := mm_dot * P2; view_x1 := cx - ((ImageWidth / 2.0) / mm_dot); view_y1 := cy - ((ImageHeight / 2.0) / mm_dot); view_x2 := cx + ((ImageWidth / 2.0) / mm_dot); view_y2 := cy + ((ImageHeight / 2.0) / mm_dot); end; 2: begin // 縮小 P1 := bx / dx; P2 := by / dy; if (P1 > P2) then mm_dot := mm_dot * P1 else mm_dot := mm_dot * P2; view_x1 := cx - ((ImageWidth / 2.0) / mm_dot); view_y1 := cy - ((ImageHeight / 2.0) / mm_dot); view_x2 := cx + ((ImageWidth / 2.0) / mm_dot); view_y2 := cy + ((ImageHeight / 2.0) / mm_dot); end; end; Drawdata; end end; procedure TForm1.PaintBox1Paint(Sender: TObject); begin Drawdata; end; // ラバーバンド長方形描画 procedure TForm1.RubberBand(x1, y1, x2, y2:Integer); begin PaintBox1.Canvas.Pen.Mode := pmXor; PaintBox1.Canvas.Pen.Color := clAqua; PaintBox1.Canvas.Pen.Width := 0; PaintBox1.Canvas.Pen.Style := psSolid; PaintBox1.Canvas.Brush.Style := bsClear; PaintBox1.Canvas.Rectangle(x1,y1,x2,y2); end; // CADデータの描画 procedure TForm1.Drawdata; // 座標を変換 procedure Change_mm_dot(x1, x2, y1, y2: Double; var ix1, ix2, iy1, iy2: Integer); begin ix1 := Round( x1 * mm_dot + ox ); iy1 := Round(-y1 * mm_dot + oy ); ix2 := Round( x2 * mm_dot + ox ); iy2 := Round(-y2 * mm_dot + oy ); end; // 線及び円弧の線種・線色の設定 procedure LineSetting(Root: CData); begin // ペンの太さ PaintBox1.Canvas.Pen.width := 0; // ペンのスタイル case Root.m_nPenStyle of 1: PaintBox1.Canvas.Pen.Style := psSolid; 2,3,4,9: PaintBox1.Canvas.Pen.Style := psDot; 5,6,7,8: PaintBox1.Canvas.Pen.Style := psDashDot; end; // ペンの色 case Root.m_nPenColor of 1: PaintBox1.Canvas.Pen.Color := RGB(0,192,192); 2: PaintBox1.Canvas.Pen.Color := clBlack; 3: PaintBox1.Canvas.Pen.Color := RGB(0,192,0); 4: PaintBox1.Canvas.Pen.Color := RGB(192,192,0); 5: PaintBox1.Canvas.Pen.Color := RGB(192,0,192); 6: PaintBox1.Canvas.Pen.Color := RGB(0,0,255); 7: PaintBox1.Canvas.Pen.Color := RGB(0,128,128); 8: PaintBox1.Canvas.Pen.Color := RGB(255,0,128); 9: PaintBox1.Canvas.Pen.Color := RGB(255,128,255); end; end; // フォントの設定 procedure FontSetting(ACDataMoji: CDataMoji); begin // フォント名 PaintBox1.Canvas.Font.Name := ACDataMoji.m_strFontName; // フォントの高さ PaintBox1.Canvas.Font.Height := Round(ACDataMoji.m_dSizeY * mm_dot); // フォントの色 case JWWHd.m_Moji[ACDataMoji.m_nMojiShu].m_anMojiCol of 1: PaintBox1.Canvas.Font.Color := RGB(0,192,192); 2: PaintBox1.Canvas.Font.Color := clBlack; 3: PaintBox1.Canvas.Font.Color := RGB(0,192,0); 4: PaintBox1.Canvas.Font.Color := RGB(192,192,0); 5: PaintBox1.Canvas.Font.Color := RGB(192,0,192); 6: PaintBox1.Canvas.Font.Color := RGB(0,0,255); 7: PaintBox1.Canvas.Font.Color := RGB(0,128,128); 8: PaintBox1.Canvas.Font.Color := RGB(255,0,128); 9: PaintBox1.Canvas.Font.Color := RGB(255,128,255); end; end; // レイヤーの表示/非表示 function LayerCheck(Root: CData): Boolean; var I, J: Integer; F1, F2: Boolean; begin I := Root.m_nGLayer; // レイヤーグループ J := Root.m_nLayer; // レイヤー F1 := JWWHd.GLay[I].m_anGLay <> 0; F2 := JWWHd.GLay[I].m_nLay[J].m_aanLay <> 0; Result := F1 and F2; end; // 補助線かどうか function IsSupportLine(Root: CData): Boolean; begin Result := (Root.m_nPenStyle = 9); end; var I: Integer; x1, x2, y1, y2, Hankei: Double; ix1, ix2, iy1, iy2: Integer; Moji: String; Hajime, Owari: Double; wx1,wy1,wx2,wy2 : Double ; ax3,ay3,ax4,ay4 : integer ; LF: TLogFont; begin // 用紙枠の描画 Draw_Paper_Frame; // 線の描画 PaintBox1.Canvas.Pen.Color := clBlack; for I := Low(JWWSen) to High(JWWSen) do begin if (not IsSupportLine(JWWSen[I].Root)) and LayerCheck(JWWSen[I].Root) then begin x1 := JWWSen[I].m_start_x; y1 := JWWSen[I].m_start_y; x2 := JWWSen[I].m_end_x; y2 := JWWSen[I].m_end_y; // mm→dot変換 Change_mm_dot(x1, x2, y1, y2, ix1, ix2, iy1, iy2); // 線の設定 LineSetting(JWWSen[I].Root); //線の描画 PaintBox1.Canvas.MoveTo(ix1, iy1); PaintBox1.Canvas.LineTo(ix2, iy2); end; end; // 円弧の描画 for I := Low(JWWEnko) to High(JWWEnko) do begin if (not IsSupportLine(JWWEnko[I].Root)) and LayerCheck(JWWEnko[I].Root) then begin x1 := JWWEnko[I].m_start_x; y1 := JWWEnko[I].m_start_y; Hankei := JWWEnko[I].m_dHankei; Hajime := JWWEnko[I].m_radKaishiKaku + JWWEnko[I].m_radKatamukiKaku; Owari := JWWEnko[I].m_radKaishiKaku + JWWEnko[I].m_radEnkoKaku + JWWEnko[I].m_radKatamukiKaku; if JWWEnko[I].m_radKatamukiKaku < 0 then begin wx1 := X1-Hankei*JWWEnko[I].m_dHenpeiRitsu; wy1 := Y1-Hankei; wx2 := X1+Hankei*JWWEnko[I].m_dHenpeiRitsu; wy2 := Y1+Hankei; end else begin wx1 := X1-Hankei; wy1 := Y1-Hankei*JWWEnko[I].m_dHenpeiRitsu; wx2 := X1+Hankei; wy2 := Y1+Hankei*JWWEnko[I].m_dHenpeiRitsu; end; // 円弧の設定 LineSetting(JWWEnko[I].Root); // mm→dot変換 Change_mm_dot(wx1, wx2, wy1, wy2, ix1, ix2, iy1, iy2); // 円弧の描画 if JWWEnko[I].m_bZenEnFlg = 1 then PaintBox1.Canvas.Ellipse(ix1, iy1,ix2,iy2) //円 else begin ax3 := Round( ((x1+Hankei*Cos(Hajime)))*MM_dot+ox); ay3 := Round(-((y1+Hankei*Sin(Hajime)))*MM_dot+oy); ax4 := Round( ((x1+Hankei*Cos(Owari )))*MM_dot+ox); ay4 := Round(-((y1+Hankei*Sin(Owari )))*MM_dot+oy); if (ax3 <> ax4) or (ay3 <> ay4) then begin if (JWWEnko[I].m_radEnkoKaku < 0) then PaintBox1.Canvas.Arc(ix1,iy1,ix2,iy2,ax4,ay4,ax3,ay3) else PaintBox1.Canvas.Arc(ix1,iy1,ix2,iy2,ax3,ay3,ax4,ay4); end; end; end; end; // 文字の描画 for I := Low(JWWMoji) to High(JWWMoji) do begin if LayerCheck(JWWMoji[I].Root) then begin x1 := JWWMoji[I].m_start_x; y1 := JWWMoji[I].m_start_y; x2 := JWWMoji[I].m_end_x; y2 := JWWMoji[I].m_end_y; Moji := JWWMoji[I].m_string; // mm→dot変換 Change_mm_dot(x1, x2, y1, y2, ix1, ix2, iy1, iy2); // フォントの設定 FontSetting(JWWMoji[I]); // 文字の描画 GetObject(PaintBox1.Canvas.Font.Handle, SizeOf(LF), @LF); SetTextAlign(PaintBox1.Canvas.Handle,TA_LEFT or TA_BOTTOM); LF.lfEscapement := Round(JWWMoji[I].m_degKakudo*10); PaintBox1.Canvas.Font.Handle := CreateFontIndirect(LF); PaintBox1.Canvas.TextOut(ix1,iy1,moji); end; end; end; // レイヤー名及び表示/非表示の設定 procedure TForm1.SetLayerName; // ノードのチェックボックス設定 procedure NodeCheckBox(Node: TTreeNode; F: Boolean); var TvItem: TTVItem; begin TvItem.hItem := Node.ItemId; TvItem.stateMask := TVIS_STATEIMAGEMASK; TvItem.mask := TVIF_HANDLE or TVIF_STATE; TvItem.state := TVIS_CHECKED; TreeView_SetItem(TreeView1.Handle, TvItem); end; // 太字設定 procedure SetBold(Node: TTreeNode); var TvItem: TTVItem; begin TvItem.hItem := Node.ItemId; TvItem.stateMask := TVIS_BOLD; TvItem.mask := TVIF_HANDLE or TVIF_STATE; TvItem.state := TVIS_BOLD; TreeView_SetItem(TreeView1.Handle, TvItem); end; var I, J, K, SNo, ENo: Integer; NodeA, NodeB: TTreeNode; LayerNo, Scale, LayerName: String; F: Boolean; begin TreeView1.Items.BeginUpdate; try TreeView1.Items.Clear; // レイヤーグループの設定 for I := Low(JWWHd.m_aStrGLayName) to High(JWWHd.m_aStrGLayName) do begin // レイヤーグループ番号 LayerNo := '[' + IntToHex(I, 1) +'] '; // 縮尺 if JWWHd.GLay[I].m_adScale < 1 then Scale := IntToStr(Round(1 / JWWHd.GLay[I].m_adScale)) + '/1' else Scale := '1/'+ IntToStr(Trunc(JWWHd.GLay[I].m_adScale)); // レイヤーグループ名 LayerName := ' ' + JWWHd.m_aStrGLayName[I]; // ノードの追加及び表示/非表示の設定 NodeA := TreeView1.Items.Add(nil, LayerNo + Scale + LayerName); F := JWWHd.GLay[I].m_anGLay <> 0; NodeCheckBox(NodeA, F); SetBold(NodeA); // レイヤーの設定 SNo := I * 16; // 読み取り開始番号 ENo := SNo + 15; // 読み取り終了番号 for J := SNo to ENo do begin K := J - SNo; LayerNo := '[' + IntToHex(K, 1) +'] '; // レイヤーグループ番号 LayerName := ' ' + JWWHd.m_aStrLayName[J]; // レイヤー名 // ノードの追加及び表示/非表示の設定 NodeB := TreeView1.Items.AddChild(NodeA, LayerNo + LayerName); F := JWWHd.GLay[I].m_nLay[K].m_aanLay <> 0; NodeCheckBox(NodeB, F); end; end; finally TreeView1.Items.EndUpdate; end; end; procedure TForm1.TreeView1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var lpht: TTVHitTestInfo; Node: TTreeNode; I,J, K: Integer; begin // クリックした位置のノードを取得します。 Node := TreeView1.GetNodeAt(X, Y); if Node = nil then Exit; // クリックした位置がチェックボックス上からどうかを調べます。 lpht.pt.x := X; lpht.pt.y := Y; TreeView_HitTest(TreeView1.Handle, lpht); if lpht.flags = TVHT_ONITEMSTATEICON then begin if TreeView_GetCheckState(TreeView1.Handle, Node.ItemId) > 0 then K := 1 else K := 0; if Node.Level = 0 then begin I := Node.AbsoluteIndex mod 16; JWWHd.GLay[I].m_anGLay := K; end else begin I := Node.Parent.AbsoluteIndex mod 16; J := Node.Index; JWWHd.GLay[I].m_nLay[J].m_aanLay := K; end; PaintBox1.Invalidate; end; end; end.
[20071210NodeCheckBox手続きを訂正]
今、ふと見るとパラメーターFが無視されてました。下記のように訂正します。
// ノードのチェックボックス設定 procedure NodeCheckBox(Node: TTreeNode; F: Boolean); var TvItem: TTVItem; begin TvItem.hItem := Node.ItemId; TvItem.stateMask := TVIS_STATEIMAGEMASK; TvItem.mask := TVIF_HANDLE or TVIF_STATE; if F then TvItem.state := TVIS_CHECKED else TvItem.state := TVIS_CHECKED shr 1; TreeView_SetItem(TreeView1.Handle, TvItem); end;あるいは、パラメーターFを削除して、レイヤーを表示する場合のみ呼び出した方がいいのかも知れませんね。 (チェックボックスを設定した時には、チェックが外れているから)
| 固定リンク