Delphi Personal+XPで始めた者ですがお願いします。
下記のような方法で必要な数だけのImage、ShapeなどをCreateで作て上手くいっていたのですが他と同じ方法でMemoを作ってみましたがMemoにTextが書き込めない、という問題が出てしまいました。どこに問題があるのか、ヒントなど教えてください。Fontの色を変えてみたりRefreshをかけてみたりしましたがわかりませんので宜しくお願いします。
/// MemoをCreate
for i := 1 to nStudent do begin
ScoreBox[i] := TMemo.Create(self);
with ScoreBox[i] do
begin
height:=12;
width:=25;
//enabled:=true;
alignment:=taCenter;
Left := 232;
Top := i * 14;
tag:=i;
Parent :=form1.pnlClass;
//font.color:=rgb(0,0,0);
// text:='AAAA';
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ScoreBox[1].text:='225';
end;
> Parent :=form1.pnlClass;
・form1.pnlClass.Visible = False
・form1 ≠ Self
いきなり複雑なものをコーディングしてデバッグするより、
シンプルなものを完成させつつ、複雑にして行くのがいいかと思います。
var
ScoreBox : TMemo;
procedure TForm1.Button2Click(Sender: TObject);
begin
/// MemoをCreate
// for i := 1 to nStudent do begin
ScoreBox := TMemo.Create(self); // 寿命の管理
with ScoreBox do
begin
height:=120;
width:=250;
//enabled:=true;
alignment:=taCenter;
Left := 0;
// Top := i * 14; tag:=i;
Parent :=form1;//.pnlClass; // どのコンポーネント上に配置するか。
//font.color:=rgb(0,0,0);
// text:='AAAA';
end;
// end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ScoreBox.text:='225';
end;
ん?様、何時もお世話になります。
ScoreBox[i] := TMemo.Create(self); のSelfをForm1にしてみましたが駄目でした。pnlClassはVisibleにしてありpnlClassもScoreBox(Memo)も見えています。がTextが現れません。ParentをForm1にしたりしましたがTextが表示されません。
理屈も分からずに何とか3500行程度まで進みましたがやはりこれでは駄目なので「作りながら」勉強させていただきたくよろしくお願いします。
マリン様、アドバイスをありがとうございます。
確かにシンプルなものでテストしてから実装するべきと早速配列なしでやりOK。配列化してOK。そして実装したら駄目でした。CreateしたばかりのMemoに’AAAA'を書かせてるテストもしましたが(最初の質問のText:='AAAA')それすら表示されないという現象です。他のボタンから書かせるコマンドを送っても同様です。VarのチェックもしましたがOKだと思います。(他の同様な方法で作られたものは全てOKなので基本的なものは他の殆ど同じコードの流用です) 何か気付かない致命的な落とし穴にはまっているのではないかと思います。何か手懸り、ご経験などお気づきの点があったらアドバイスをよろしくお願いします。
もしかしたら、
Lines.Clear;
Lines.Add('aaaa');
or
Lines.Text := 'aaaa';
では?
ScoreBoxの配列の宣言ってどうなっているんですか?
コレ自体が怪しい気がする。
TListあたりを使ったほうが良いと思うんですが。
それもめんどくさいので、Componentsを使ってみよう。
どうせ動的につくるなら、継承しても問題ありませんよね。
TForm1.Components[]とComponentCountを使って
TMemoから派生して、TScoreBoxMemoで識別できるようにして
利用してみよう。
interface 部
type
//TForm1の上ぐらいに書く。
TScoreBoxMemo = class( TMemo)
end;
//(TMemoと全く同じように使えますが、
//TScoreBoxMemoというクラス名で識別できるようになります。
//もちろん派生なのでTMemoとしても識別できます。)
TForm1 = class( TForm)
//省略
protected
function GetScoreBox( aTag: integer): TScoreBoxMemo; virtual;
public
property ScoreBox[index: integer]: TScoreBoxMemo read GetScoreBox;
end;
implementation 部
//のどこかのブロック(不明)。
//を配列を使わないように変更
for i:= 1 to nStudent do
begin
with TScoreBoxMemo.Create( Self) do
begin
Left := 232;
top := i * 14;
width := 250;
//height 小さいと見えないかもしれません。
height:= 120;
alignment:= taCenter;
tag:= i;
//Form1は内部からの呼び出しなら、Form1は不要かもしれない。
//あってもまあいい。TForm1のインスタンスが複数ある場合、
//特定の1つを指すようになるので注意が必要。
//Parent:= Form1.pnlClass;
Parent:= pnlClass;
//これが問題ということはありえないと思うんだけどなぁ。
Text:= 'AAAA';
end;
//再構築などを自分で行わないのであれば
//TScoreBoxMemoの開放は TForm1に、任せて OK。
//なので配列は基本的に不要。
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ScoreBox[1].Text:='225';
// 1 という値が無効な場合、EAccessViolationが出ます。
//例外はそのまま放置し、バグ発見に役立てたほうがよいですよ。
end;
function TForm1.GetScoreBox( aTag: integer): TScoreBoxMemo;
var
tmp: TComponent;
begin
Result:=nil;
for i:=0 to ComponentCount-1 do
begin
tmp:= Components[i];
if tmp is TScoreBoxMemo then
begin
if tmp.Tag=aTag then
begin
Result:= tmp;
Exit;
end;
end;
end;
end;
MemoにTextが書き込めないではなく、
> height:=12;
だと文字が描画出来ないのでは?
ScoreBox[i].Height か ScoreBox[i].Font.Height の
どちらかの値を変える必要があると思います。
igy様、f様、Basser様ありがとうございました。不具合の原因は枠のサイズ(height)にあり、これを変更したら解決できました。お礼申し上げます。
Lines.Addは試しましたが上手く行かず、またConponents[]は初心者につき理解できずに色々調べていましたがなかなか理解できなくておりました。
他にも同じ方法で各種のコントロールをCreateしていますので何とかMemoも同じスタイルで解決したいと悩んでいましたがHeightを少しづつ増加していきましたらHeight:=15;で表示されました。方法自体に問題があるとしたらこのテクニックは今後安心して使えないかと疑っていましたがプロパティーの設定が問題であったことがわかり今後も自信を持って使えるものと安心しました。
僅かな作業に思わぬ時間が掛かってしまいましたが皆様の暖かいアドバイスのおかげで解決に至り大変感謝しております。 ありがとうございました。
ツイート | ![]() |