レコード型で保持型にTFontとかTBrushとかその下にも細かいプロパティ持ってる
型を設定するのはよくないのでしょうか?
TPrintData = record
Font:TFont;
Brush:TBrush;
Pen:TPen;
などなどしてると、動作が不安定になってしまいます。
やっぱ細かく
TPrintData = record
FontName:String;
FontStyle:TFontStyles;
FontColor:TColor;
BrushColor:TColor;
BrushStyle:TBrushStyle;
したほうがいいんでしょうか。
問題ないはずです。
現状、細かくして保存してるんですが、
最初、動的配列で
SetLength(PrintData,count);
1レコづつ追加してて、
Fontにはフォントダイアログをそのまま突っ込む
PrintData.Font := FontDialog.Font;
てやってから、印刷時に
Canvas.Font := PrintData.Font;
つっこむと、フォント内容がデフォルトの「MSゴシック」に戻ってるんですよね。
あと、実行中にアドレスエラーも起きたりしてたんで、ソースをじっくり眺めたんですが原因分からずにレコード項目を細かくしたんです。
環境は、Del7 + Windows2000です
> PrintData.Font := FontDialog.Font;
PrintDataのFont値が、FontDialogのFontプロパティに置き換わる
当初、PrintData.Font <> FontDialog.Font が成り立っているなら、
PrintData.Font.Assign(FontDialog.Font) とすべき。
> PrintData.Font := FontDialog.Font;
> てやってから、印刷時に
> Canvas.Font := PrintData.Font;
上記理由により、FontDialog が破棄済みだったりすると、アクセス違反の
エラーが発生します。
PrintData.Fontは、FontDialogのFontプロパティのクラスを参照しているため、
Canvas.Fontの設定時に、メモリからなくなった領域を参照することになります。
動的配列で配列数を増やしても、TPrintData.Font のインスタンスを用意してくれません。
そのため、TFont,TBrush等のクラスをCreateしなくてもよいものに変えると
エラーがでなくなるのでしょう。
orz さんと同じですが、
インスタンスを生成してないので、たんなる参照を受け取ってるだけで、内容の
コピーが行われてないんだと思います。
この例のようにクラスをフィールドにする場合は、レコード型ではなく、クラス
にするべきです。コンストラクタでフィールドを生成し、デストラクタで Free
するようにして、リークを防ぐべきです。
ありがとうございます。
なんとなく分かりました。
orzさんが教えてくれたAssignは、配列増やすその都度にCreateして、するべきなんでしょうか?
もちろん配列減らす前に解放してやらないとメモリリークになるんですよね?
> orzさんが教えてくれたAssignは、配列増やすその都度にCreateして、するべきなんでしょうか?
Yes
> もちろん配列減らす前に解放してやらないとメモリリークになるんですよね?
Yes
自分なら、めんどくさいので、Createの必要のない型でレコード型を構成します。
または、TPrintDataをクラス型にし、TList(TObjectList)あたりで管理します。
そうですね。
面倒くさいのでCreateなしでいきます。
ツイート | ![]() |