« 2007年10月 | トップページ | 2007年12月 »

☆JWWファイルの超簡易表示 その2

以前、☆JWWファイルの超簡易表示 という記事で書いたコードのDrawdata手続きを更新しましたので載せておきますね。

Sample


前回は線と文字を適当に表示するだけでしたが、線、円・楕円・円弧、文字をもう少し それっぽく表示するようにしました。(レイヤー、ソリッドやSXFなどは全く考慮していませんけどね。)
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: PaintBox1.Canvas.Pen.Style := psDot;
      3: PaintBox1.Canvas.Pen.Style := psDot;
      4: PaintBox1.Canvas.Pen.Style := psDot;
      5: PaintBox1.Canvas.Pen.Style := psDashDot;
      6: PaintBox1.Canvas.Pen.Style := psDashDot;
      7: PaintBox1.Canvas.Pen.Style := psDashDotDot;
      8: PaintBox1.Canvas.Pen.Style := psDashDotDot;
      9: PaintBox1.Canvas.Pen.Style := psDot;
    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;

var
  I, ax3, ay3, ax4, ay4: Integer;
  x1, x2, y1, y2, Hankei: Double;
  ix1, ix2, iy1, iy2: Integer;
  Moji: String;
  Hajime, Owari: Double;
  wx1,wy1,wx2,wy2: Double;
  LF: TLogFont;
begin
  // 用紙枠の描画
  Draw_Paper_Frame;

  // 線の描画
  PaintBox1.Canvas.Pen.Color := clBlack;
  for I := Low(JWWSen) to High(JWWSen) do
  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;

  // 円弧の描画
  for I := Low(JWWEnko) to High(JWWEnko) do
  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;

  // 文字の描画
  for I := Low(JWWMoji) to High(JWWMoji) do
  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;

指定フォルダから検索文字を含むJWWファイル一覧を作成し、 そのファイル名をクリックすると、検索文字を目立つように描画させて、 VE等の内容がきちんと訂正されているかをチェックするのに使っています。

|

■Microsoft Visual Studio 2008 Express Editions

最近仕事が忙しくて、なかなかプログラムをする時間も取れず、ブログの更新もままならないのですが、 Microsoft Visual Studio 2008 Express Editions(英語版) が公開されたということで、
 ・Microsoft Visual C# 2008 Express Edition(英語版)
 ・Microsoft Visual C++ 2008 Express Edition(英語版)
 ・Microsoft Visual Web Developer 2008 Express Edition(英語版)
を早速インストールしました。

そしてC#で.NET Framework 3.5の新機能 --- .NET LINQを少しだけ試してみました。
汎用クエリ機能と呼ばれるように、データベースだけではなく、XMLや配列データにも使えるようです。 .NET LINQが初めての私にとっては中途半端なSQLのような感じで少し抵抗がありますが、 どのようなデータに対しても同じようにアクセスできるのはきっと便利なのでしょうね。
次世代のDelphiには、同様の機能が実装されるのかな?


Visual Studio 2008 Express Developer Center
http://www.microsoft.com/express/

MSDN
LINQ: .NET 統合言語クエリ
http://www.microsoft.com/japan/msdn/net/bb308959.aspx

|

■初級シスアド試験

みんなから、「一級建築士がそんなん取ってどうするの?」とか 「それ持ってるとどうなるの?」とかさんざん言われながらも受けた初級シスアド試験。
試験前にもかかわらず「近い将来、他に統合されてなくなる」という親切な報道があってから、 全くやる気をなくしたもののなんとか合格してました。
多くの人から「そんなの受かって当然」と言われていたので、内心ほっとしています(笑)

基本情報技術者試験というのもあるんですね。初級シスアドの合格発表時に初めて知りました。
時間があったら、今度はこれに挑戦かな(^^;

|

■RAD Studio ヘルプアップデート 1

Release Notesによるとアップデートの対象は次の製品です。
・CodeGear RAD Studio 2007
・C++Builder 2007 Update 3
・Delphi 2007 for Win32 Update 3

私も早速インストールしようとしたのですが、次のようなメッセージが表示されて当初ダウンロード できませんでした。

Help

このメッセージは、私が使っている@niftyのセキュリティ24からのものです。
Delphi使いの皆さんなら惑わされることはないでしょうけど、 PCのことあまり知らない人だと「CodeGearってけしからん!」ってことになるのでしょうか(笑)
「ウィルスが発見されたため」ではなく「大きなサイズのファイルだけどいいの?」と いうメッセージを表示して頂きたいものです。
(当然ですがダウンロードしたファイルをチェックしてもウィルスは未検出でした)

あっ、肝心なヘルプの内容については、あまり確認できていません(^^;


Team Japan
CodeGearの日本人スタッフによるブログ
RAD Studio ヘルプアップデート 1 をリリースしました http://blogs.codegear.com/teamj/2007/11/16/48/

|

☆HTMLのソースを取得する。

HTMLのソースを取得するには、TWebBrowserやIndyを使ったりしていますが、 NewsGroupsでWinInetを使ったコードのリンク先が紹介されていたので試してみました。

procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.Lines.Text := Utf8ToAnsi(DownloadFile('http://hiderin.air-nifty.com/delphi/'));
end;
※DownloadFile関数は、下記サイトにコードがあります。

WinInetなんて使うのは、かなり久しぶりです。wininet.dllって、確かIEの付属dllだったような 記憶があるのですが、IE7になっても健在なんですね(^^;


Scalabium Software
#80:How can I download a file from Internet by link?
http://www.scalabium.com/faq/dct0080.htm

[NewsGroupsの記事]
borland.public.delphi.language.delphi.general
AutoUpdate - Best way to read a file off the web?

|

☆デスクトップに定規を・・・。

細かいマトリックス表をDocuworksで編集していると、行や列がわからなくなるので わざわざ三角スケールを画面に当てて作業している人がいました。 液晶画面が傷つきそうなので、次のようなものを作ってみました。 (定規と書いていますが、測定するためのものではないです)

Docu

(この画像では、2つ起動させ、それぞれを縦と横に設定して使っています。)

次の通り仕組みは簡単です。ポイントとしては、キャプションのないフォームを移動させる 処理かな。
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Buttons, ExtCtrls, StdCtrls, Menus;

type
  TForm1 = class(TForm)
    PopupMenu1: TPopupMenu;
    N1: TMenuItem;
    N2: TMenuItem;
    N3: TMenuItem;
    N4: TMenuItem;
    procedure N1Click(Sender: TObject);
    procedure N2Click(Sender: TObject);
    procedure N3Click(Sender: TObject);
    procedure N4Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    procedure WMNCHitTest(var Msg : TWMNchitTest); Message WM_NCHITTEST;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
  DefaultSize = 25;

procedure TForm1.FormCreate(Sender: TObject);
begin
  BorderStyle := bsNone;
  AlphaBlend := True;
  AlphaBlendValue := 200;
  Color := clBlack;
  N2Click(Self);
end;

procedure TForm1.N1Click(Sender: TObject);
begin
  Close;
end;

// 横
procedure TForm1.N2Click(Sender: TObject);
var
  ARect: TRect;
begin
  SystemParametersInfo(SPI_GETWORKAREA, 0, @ARect, 0);
  Height := DefaultSize;
  Width := Screen.Width * 3;
  Left := -Screen.Width;
  Top := ARect.Bottom-(ARect.Top+DefaultSize);
end;

// 縦
procedure TForm1.N3Click(Sender: TObject);
var
  ARect: TRect;
begin
  SystemParametersInfo(SPI_GETWORKAREA, 0, @ARect, 0);
  Width := DefaultSize;
  Height := Screen.Height * 3;
  Top := -Screen.Height;
  Left := ARect.Right-DefaultSize;
end;

// 隅へ移動
procedure TForm1.N4Click(Sender: TObject);
var
 ARect: TRect;
begin
  SystemParametersInfo(SPI_GETWORKAREA, 0, @ARect, 0);
  Width := DefaultSize;
  Height := DefaultSize;
  Top := ARect.Bottom-(ARect.Top+DefaultSize);
  Left := ARect.Right-DefaultSize;
end;

procedure TForm1.WMNCHitTest(var Msg: TWMNchitTest);
const
  Offset = 3;
var
  P: TPoint;
begin
  P := ScreenToClient(Point(Msg.XPos, Msg.YPos));

  if (P.X > Width-Offset) and (P.Y > Height-Offset) then
    Msg.Result := HTBOTTOMRIGHT
  else if (P.X > Width-Offset) and (P.Y < Offset) then
    Msg.Result := HTTOPRIGHT
  else if (P.X < Offset) and (P.Y > Height-Offset) then
    Msg.Result := HTBOTTOMLEFT
  else if (P.X < Offset) and (P.Y < Offset) then
    Msg.Result := HTTOPLEFT
  else if (P.X < Offset) then
    Msg.Result := HTLEFT
  else if (P.X > Width-Offset) then
    Msg.Result := HTRIGHT
  else if (P.Y < Offset) then
    Msg.Result := HTTOP
  else if (P.Y > Height-Offset) then
    Msg.Result := HTBOTTOM
  else if (GetAsyncKeyState(VK_LBUTTON) < 0) then
    Msg.Result := HTCAPTION
  else
    Msg.Result := HTCLIENT;
end;

end.

|

☆FormのOnMouseWheelDown(Up)

CAD Viewerを作っていて、FormのOnMouseWheelDown(Up)で問題が発生しました。 CADではコードがややこしいので、下記のような簡単なもので考えてみることにします。 問題点としては、PaintBoxに描画したものをマウスホイールにより拡大縮小する 仕様なのですが、この動作によりListBoxがスクロールしてしまうことです。

Cad


問題のあるコード
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    PaintBox1: TPaintBox;
    procedure PaintBox1Paint(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 FormCreate(Sender: TObject);
  private
    P: Integer;
    procedure DrawData;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
begin
  P := 0;
  Form1.OnResize := PaintBox1Paint;
  for I := 0 to 99  do
    ListBox1.Items.Add(IntToStr(I));
end;

procedure TForm1.DrawData;
var
  Rect: TRect;
begin
  // Clear
  Rect.Top := PaintBox1.Top;
  Rect.Left := PaintBox1.Left;
  Rect.Bottom := PaintBox1.Height;
  Rect.Right := PaintBox1.Width;
  // Rectangle
  PaintBox1.Canvas.FillRect(Rect);
  Rect.Top := (PaintBox1.Top + P);
  Rect.Left := PaintBox1.Left + P;
  Rect.Bottom := PaintBox1.Height - P;
  Rect.Right := PaintBox1.Width - P;
  PaintBox1.Canvas.Rectangle(Rect);
end;

procedure TForm1.FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
begin
  Dec(P,5);
  DrawData;
end;

procedure TForm1.FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
begin
  Inc(P,5);
  DrawData;
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  DrawData;
end;

end.


対策後のコード
MouseWheelDown(Up)をそれぞれ下記のようにしました。
procedure TForm1.FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
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;
    Dec(P,5);
    DrawData;
  end;
end;

procedure TForm1.FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
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;
    Inc(P,5);
    DrawData;
  end;
end;

これによりPaintBox1上にマウスがある場合のみPaintBox1にマウスホイールが働きます。 ListBox1をスクロールするには、ListBox1上にマウスを移動させます。

|

☆TStringGridでの縦書き(日本語)

マトリックス表を作るときに、横書きでは、幅が広くなりすぎて見づらいので、 縦書きを試してみました。アルファベット(RENAULT)が反対向いていますが、 今回、処理したかったのは日本語なので良しとしておきます(^^;
(BMWは全角で入力しています)

Tate


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids;

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
const
  S1 = ',トヨタ,日産,マツダ,ホンダ,スズキ,スバル,三菱';
  S2 = ',ダイハツ,いすゞ,BMW,RENAULT,フォード';
var
  I, J: Integer;
  SL: TStringList;
begin
  // サンプルデータの設定
  SL:= TStringList.Create;
  try
    SL.CommaText := S1+S2;
    J := SL.Count;
    StringGrid1.ColCount := J;
    StringGrid1.Rows[0].Assign(SL);

    StringGrid1.RowCount := 3;
    StringGrid1.FixedCols := 1;
    StringGrid1.FixedRows := 1;
    StringGrid1.RowHeights[0] := 80;
    for I := 0 to J -1 do
      StringGrid1.ColWidths[I] := 25;
  finally
    SL.Free;
  end;
end;

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);

  // 縦書きの描画
  procedure VerticalTextDraw(S: String);
  var
    LF: TLogFont;
    I: Integer;
  begin
    StringGrid1.Canvas.Font.Height := 12;
    StringGrid1.Canvas.Font.Name := '@MS UI Gothic';

    GetObject(StringGrid1.Canvas.Font.Handle,SizeOf(LF), @LF);

    LF.lfEscapement := -900;
    StringGrid1.Canvas.Font.Handle := CreateFontIndirect(LF);
    I := ((Rect.Right - Rect.Left) div 2 + StringGrid1.Canvas.TextWidth('W'));
    StringGrid1.Canvas.TextOut(Rect.Left + I, Rect.Top + 5, S);
  end;

begin
  if (ARow = 0) then
  begin
    StringGrid1.Canvas.FillRect(Rect);
    VerticalTextDraw(StringGrid1.Cells[ACol,ARow]);
  end;
end;

end.

|

« 2007年10月 | トップページ | 2007年12月 »