いつもお世話になります。
現在は、下記のようなソースで、ラベルを配列で定義し、
for ループで動的にラベルを作成し、
for ループで処理し(省略)、
for ループで解放しています。
・問題点
予め、配列の最大値を array で定義している。
→ 配列の最大値がもっと必要な場合が発生した場合どうするのか
実際にそんなに配列が必要なくても、余裕を持った配列の定義が必要
・質問内容
(1)配列そのものを動的に作成できないのか?
(2)ラベルの配列を[0..10000]とか指定したらメモリ等を圧迫しないのか?
(3)別の方法で実現できないのか?
※ComponentList を使用すれば出来そうらしいのですが、
検索方法が悪いらしく、それらしいHELPが見つかりません。
HELPの場所または使用方法を教えていただけないでしょうか?
以上、よろしくお願いいたします。
※以下、現在のソース(概要)です。
var
Form1: TForm1;
arLabel : array [0..100] of TLabel;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
for i := 1 to 10 do
begin
arLabel[i] := TLabel.Create(self);
arLabel[i].Parent := self;
arLabel[i].Left := i * 20;
arLabel[i].Top := i * 20;
arLabel[i].Caption := 'Label' + IntToStr(i);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
i: Integer;
begin
for i := 1 to 10 do
arLabel[i].Free;
end;
・質問内容
(1)動的配列で調べてみましょう。
(2)オブジェクトの配列はポインタ(4バイト)の配列と同じなので配列を宣言しただけでメモリを圧迫することは無いでしょう。(10000*4≒40KB)
(3)リストで管理するのが定石でしょう。TListについて知らない様なのでヘルプで調べてみましょう。TListの使い方が分かればTComponentListの使い方も自ずと分かるはずです。
それと、ヘルプでクラスを調べるときはComponentListとするのではなく、TComponentListというように頭にTをつけて検索すれば見つかります。
めるめるさん、こんにちは。
コードはお世辞にもいいとは言えませんが、以下のページが参考にならないてしょうか。
http://homepage2.nifty.com/Mr_XRAY/Delphi/plSamples/T_SaveComponentList1.htm
http://homepage2.nifty.com/Mr_XRAY/Delphi/plSamples/T_SaveComponentList2.htm
http://homepage2.nifty.com/Mr_XRAY/Delphi/plSamples/T_CreateComponent.htm
> (1)配列そのものを動的に作成できないのか?
Delphi4 以降であれば,SetLength()が使えます。 (Delphi3 以前ならGetMem()を使用)
var
arLabel: array of TLabel;
MaxCount: Integer;
procedure TForm1.Button1Click(Sender: TObject);
begin
MaxCount := 必要な配列数を得る。
SetLength(arLabel, MaxCount);
for i := 0 to MaxCount - 1 do // 0 から始めたほうが無難。
begin
arLabel[i] := TLabel.Create(self);
arLabel[i].Parent := self;
arLabel[i].Left := i * 20;
arLabel[i].Top := i * 20;
arLabel[i].Caption := 'Label' + IntToStr(i);
// (2)の質問で追加
end;
end;
> (2)ラベルの配列を[0..10000]とか指定したらメモリ等を圧迫しないのか?
> オブジェクトの配列はポインタ(4バイト)の配列と同じなので配列を宣言しただけでメモリを圧迫することは無いでしょう。
Button1ClickでTLabel.Createした段階では考慮が必要です。
TLabelならまず心配はないでしょうが,TBitmapの配列だとBitmapのサイズによっては簡単にメモリを使い切ってしまいます。
var
AvailPhys: Integer;
MemoryStatus: TMemoryStatus;
begin
for i := 0 to MaxCount - 1 do
begin
// 「(2)の質問で追加」の部分
GlobalMemoryStatus(MemoryStatus); // メモリ情報を得る
// 空きメモリを得る
// MemoryStatus.dwAvailPhysで直接得られるはずだが,経験上信用できない。
AvailPhys := MemoryStatus.dwTotalPhys div 100 * MemoryStatus.dwMemoryLoad;
// 100%使い切るのは危険, 100MBにしたのは例えばの例
if AvailPhys < 100000000 then
begin
MaxCount := i;
Break;
end;
end;
end;
> for i := 1 to 10 do
> arLabel[i].Free;
// Createは昇順, Freeは降順が無難。
for i := 9 downto 0 do
// Nilも必ず設定する癖をつけたほうが良い。
if Assigned(arLabel[i]) then // arLabel[i]にnilが設定されていなければ
FreeAndNil(arLabel[i]);
> (3)別の方法で実現できないのか?
Mr.XRAYさんの回答で解決しますよね。
追伸
上記例は,作成されるTLabel等のサイズが事前に決定できない場合の例です。
このコードだと,処理速度がかなりかかります。
TLabel等のサイズあるいは限度サイズが事前に決定できる場合には,先に使用可能メモリサイズを得て作成数を決めるようにすると良いでしょう。
Mr.XRAY 様、さどやま 様、ありがとうございます。
何とか、希望通りのものが出来そうです。
ソース・コードを提示して頂き、とても助かりました。
今後ともよろしくお願いいたします。
親切心で答えたのに無視されるとは切ないですね・・・
ヘルプに載っていますよというのは、答えにならないのでしょうか?
ヘルプやドキュメントの見方が分かるって言うのも一つのスキルだと思うんですけどね、最近は何でもかんでも掲示板で聞けばすむと言う風潮のようですが・・・
掲示板で聞くよりもヘルプを見たほうがよっぽど早いし正確な情報が乗っています(Delphiのヘルプは若干日本語おかしいですが)
あとは、google等を使って調べ物をする技術も最近では一つのスキルと見なされるようですね。
ヘルプの見方を覚えましょう 様
ご指摘ありがとうございます。
その通りだと思います。
確かに、ある程度、予備知識があって、ちょっとわからない事は、
ヘルプは助かります。
ただ、まったく予備知識がないと、ヘルプを見ても具体的な使用例がない
と、どのようにとりかかってよいのかが、よくわからなかったのです。
従って、とりかかりの具体的なサンプル・ソースがあると、あとは
もっと実用的に使うためのヘルプはとても役に立ちました。
無視したつもりではなかったのですが、ご気分を害されたのであれば、
私の不徳のいたすところです。
申し訳ありませんでした。
いたらない点、多々あるとは思いますが、今後ともよろしくお願い
いたします。
ツイート | ![]() |