CreateしたMemoに書き込めない

解決


サンデープログラマー  2006-05-30 02:59:34  No: 21901

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;


ん?  2006-05-30 03:09:07  No: 21902

> Parent :=form1.pnlClass;

・form1.pnlClass.Visible = False
・form1 ≠ Self


マリン  2006-05-30 03:31:58  No: 21903

いきなり複雑なものをコーディングしてデバッグするより、
シンプルなものを完成させつつ、複雑にして行くのがいいかと思います。

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;


サンデープログラマー  2006-05-30 03:43:41  No: 21904

ん?様、何時もお世話になります。

ScoreBox[i] := TMemo.Create(self);  のSelfをForm1にしてみましたが駄目でした。pnlClassはVisibleにしてありpnlClassもScoreBox(Memo)も見えています。がTextが現れません。ParentをForm1にしたりしましたがTextが表示されません。
理屈も分からずに何とか3500行程度まで進みましたがやはりこれでは駄目なので「作りながら」勉強させていただきたくよろしくお願いします。


サンデープログラマー  2006-05-30 04:45:37  No: 21905

マリン様、アドバイスをありがとうございます。

確かにシンプルなものでテストしてから実装するべきと早速配列なしでやりOK。配列化してOK。そして実装したら駄目でした。CreateしたばかりのMemoに’AAAA'を書かせてるテストもしましたが(最初の質問のText:='AAAA')それすら表示されないという現象です。他のボタンから書かせるコマンドを送っても同様です。VarのチェックもしましたがOKだと思います。(他の同様な方法で作られたものは全てOKなので基本的なものは他の殆ど同じコードの流用です)  何か気付かない致命的な落とし穴にはまっているのではないかと思います。何か手懸り、ご経験などお気づきの点があったらアドバイスをよろしくお願いします。


igy  2006-05-30 06:05:23  No: 21906

もしかしたら、
 Lines.Clear;
 Lines.Add('aaaa');
or 
 Lines.Text := 'aaaa';
では?


f  2006-05-30 17:34:41  No: 21907

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;


Basser  2006-05-30 19:00:57  No: 21908

MemoにTextが書き込めないではなく、

>        height:=12;

だと文字が描画出来ないのでは?

ScoreBox[i].Height か ScoreBox[i].Font.Height の
どちらかの値を変える必要があると思います。


サンデープログラマー  2006-05-31 04:31:22  No: 21909

igy様、f様、Basser様ありがとうございました。不具合の原因は枠のサイズ(height)にあり、これを変更したら解決できました。お礼申し上げます。
  
Lines.Addは試しましたが上手く行かず、またConponents[]は初心者につき理解できずに色々調べていましたがなかなか理解できなくておりました。
他にも同じ方法で各種のコントロールをCreateしていますので何とかMemoも同じスタイルで解決したいと悩んでいましたがHeightを少しづつ増加していきましたらHeight:=15;で表示されました。方法自体に問題があるとしたらこのテクニックは今後安心して使えないかと疑っていましたがプロパティーの設定が問題であったことがわかり今後も自信を持って使えるものと安心しました。
僅かな作業に思わぬ時間が掛かってしまいましたが皆様の暖かいアドバイスのおかげで解決に至り大変感謝しております。  ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加