コンポーネントのTImageの使い方


こまったちゃん  2005-02-24 20:20:03  No: 13408  IP: [192.*.*.*]

こんにちは

コンポーネントを作っています.
派生元を TPanel にして TPanelEx を作成しています。
その上に TImage を貼り付けています。

コンストラクタは
inherited Create(Owner);
BorderWidth := 4;
Image := TImage.Create(Self);
Image.Parent := Self;
Image.Align := alClient;

ここまで設定して、アプリフォーム上に貼り付けると、
Image の点線が TPanelEx の内側最大に広がっています。
ここまでは、OKです。

次に、メソッドで Clear ( procedure Clear; )を public に追加しました。
中身は以下です。
  Image.Canvas.Brush.Color := clWhite;
  Image.Canvas.FillRect( Rect( 0, 0, Image.Width, Image.Height ) );

しかし、Image.Width, Image.Height の値は 105 です。
どうすれば、Image 内全てを真っ白なキャンバスに
できるのでしょうか?



TBoard = class(TPanel)

編集    削除
りおりお  2005-02-24 20:31:35  No: 13409  IP: [192.*.*.*]

なにが問題なのかよくわかりませんが

Image.Canvas.FillRect(Image.ClientRect);

ではダメですか?

編集    削除
こまったちゃん  2005-02-24 22:33:44  No: 13410  IP: [192.*.*.*]

りおりおさんいつもお世話になっています。

ごめんなさい.
問題点わかんないですよね.

問題点は
>Image.Width, Image.Height の値は 105 です。
なんです。

つまり、フォームにこのコンポーネントをのっけて
サイズを変更した場合、もちろん 105 ではないです。
例えば、コンポーネントのサイズを
Width := 400;
Height := 300;
としてフォーム上に貼り付けたとすると
Image.Width → 390; (BorderWidth = 4 のため10小さい)
Image.Height→ 290;
となっていれば、Image の Canvas が白く塗られるのですが、
なぜか Image.Width,Image.Height とも 105 に固定されるのです.
そのため、白くなるのは貼り付けたコンポーネントの
左上の 105×105 の領域だけになってしまいます。

もちろんフォーム上のコンポーネントの中に
表示される点線(Image の範囲だと思うのですが・・・)は
コンポーネントのサイズによって最大のエリアで
表示されています。

なぜ、固定になるのでしょうか?
また、どうすれば Image.Width,Image.Height の
意図した値を取得できるのか教えてください。
よろしくお願いします.

編集    削除
りおりお  2005-02-24 23:47:36  No: 13411  IP: [192.*.*.*]

確認しました。

type
TPanelEx = class(TPanel)
private
  FImage:TImage;
public
  constructor Create(AOwner: TComponent); override;
  procedure Clear;
end;

  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    PanelEx:TPanelEx;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

constructor TPanelEx.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  BorderWidth := 4;
  FImage := TImage.Create(self);
  FImage.Parent := Self;
  FImage.Align := alClient;
end;

procedure TPanelEx.Clear;
begin
  FImage.Canvas.Brush.Color := clLime;
  FImage.Canvas.FillRect(FImage.ClientRect);
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
  PanelEx := TPanelEx.Create(self);
  with PanelEx do
  begin
    Parent := Form1;
    Top := 10;
    Left := 10;
    Height := 200;
    Width := 200;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  PanelEx.Clear;
end;

として Button1Click を実行するとなんの問題もありません。しかし、

procedure TForm1.FormCreate(Sender: TObject);
begin
  PanelEx := TPanelEx.Create(self);
  with PanelEx do
  begin
    Parent := Form1;
    Top := 10;
    Left := 10;
    Height := 200;
    Width := 200;
    Clear;
  end;
end;

として、初期化のなかで Clear を実行すると以後サイズの制御が出来なくなり
ますね。alClient が効いてない感じです。

うーむ、すみませんがソースを追えないのでわたしには回避策は分かりません。

編集    削除
HOta  2005-02-25 00:39:56  No: 13412  IP: [192.*.*.*]

Picture.Bitmapのサイズも変更します。
Image.Picture.Bitmap.Width :=
Image.Picture.Bitmap.Height:=

編集    削除
こまったちゃん  2005-02-25 00:49:26  No: 13413  IP: [192.*.*.*]

HOta さんどうもです。

コンポーネントでは
TPanel 上の TImage は常に Align = alClient;
で使用し、キャンバスのクリアをしておきたいというものです.

現状では
TPanel の Create で
Align = alClient としたときの
TImage の Width,Height が取得できないことが問題なので
Image.Picture.Bitmap.Width,Image.Picture.Bitmap.Height に
いれるべき値を取得できないという状況です。
よろしくお願いします.

編集    削除
HOta  2005-02-25 00:59:54  No: 13414  IP: [192.*.*.*]

FormのOnActiveとかに、
Image.Picture.Bitmap.Width := Panel1.ClientRect.Right - 
                              Panel1.ClientRect.Left;
Image.Picture.Bitmap.Height:= Panel1.ClientRect.Bottom -
                              Panel1.ClientRect.Top;

編集    削除
Basser  2005-02-25 02:03:46  No: 13415  IP: [192.*.*.*]

Clearメソッドに1行追加して下さい。

  Image.Picture.Graphic:= nil; // ←追加行
  Image.Canvas.Brush.Color := clWhite;
  Image.Canvas.FillRect( Rect( 0, 0, Image.Width, Image.Height ) );

編集    削除
こまったちゃん  2005-02-25 03:43:41  No: 13416  IP: [192.*.*.*]

Basser さん
ありがとうございます.

Clear が動作するようになりました。
Form の Create で Clear を呼ぶことでなんとか
目的が達成できます.

できれば、
Form の Create で Clear しなくても
最初から Clear できる状態になればもっと良いですが
可能でしょうか?
  constructor TPanelEx.Create(AOwner: TComponent);
  begin
    inherited Create(AOwner);
    BorderWidth := 4;
    FImage := TImage.Create(self);
    FImage.Parent := Self;
    FImage.Align := alClient;
    Clear;                          //←これを追加する
  end;


それから、
>Image.Picture.Graphic:= nil; 
についてですが、現在の Image.Picture.Graphic を強制的に
Nil にするってのはメモリリークが起こりそうな気がするのですが
問題ないのでしょうか?

編集    削除
Basser  2005-02-25 04:20:13  No: 13417  IP: [192.*.*.*]

>Form の Create で Clear しなくても
>最初から Clear できる状態になればもっと良いですが
>可能でしょうか?

TImageの生成時はClearの必要はないのでは?
Graphicプロパティの初期値は nil ですから...

>それから、
>>Image.Picture.Graphic:= nil; 
>についてですが、現在の Image.Picture.Graphic を強制的に
>Nil にするってのはメモリリークが起こりそうな気がするのですが
>問題ないのでしょうか?

TImage.SetGraphic の中で一旦、解放が行なわれています。

編集    削除
Basser  2005-02-25 08:47:51  No: 13418  IP: [192.*.*.*]

訂正です。

TImage.SetGraphic ×
TPicture.SetGraphic ○

編集    削除