مكون دلفي آلية قراءة وكتابة (ط)
1. مقدمة في الكائنات المتدفقة (تدفقات) وكائنات القراءة والكتابة (المرشحين)
في البرمجة الموجهة للكائنات ، تحتل إدارة البيانات المستندة إلى الكائنات موقفًا مهمًا للغاية. في دلفي ، تعد طريقة دعم إدارة البيانات المستندة إلى الكائنات واحدة من ميزاتها الرئيسية.
Delphi هي بيئة تطوير متكاملة تجمع بين التصميم المرئي الموجهة للكائنات واللغات الموجهة للكائنات. جوهر دلفي هو المكونات. المكونات هي نوع من الكائن. يتم إنشاء تطبيقات Delphi بالكامل بواسطة مكونات ، وبالتالي فإن تطوير تطبيقات Delphi عالية الأداء سيتضمن حتماً تقنية إدارة البيانات القائمة على الكائنات.
تتضمن إدارة البيانات المستندة إلى الكائنات جانبين:
● استخدم الكائنات لإدارة البيانات
● إدارة كائنات البيانات المختلفة (بما في ذلك الكائنات والمكونات)
Delphi يعزى فئات إدارة البيانات المستندة إلى الكائن لدفق الكائنات (دفق) وكائنات Filer (المرشحين) ، وتطبقها على جميع جوانب مكتبة فئة المكون المرئي (VCL). أنها توفر وظائف غنية لإدارة الكائنات في الذاكرة والذاكرة الخارجية وموارد Windows.
كائن الدفق ، المعروف أيضًا باسم كائن البث ، هو مصطلح عام لـ tstream و thandlestream و tfilestream و tmemorystream و tresourcestream و tblobstream. وهي تمثل القدرة على تخزين البيانات على مختلف الوسائط ، وتجريد عمليات الإدارة لأنواع مختلفة من البيانات (بما في ذلك الكائنات والمكونات) في الذاكرة ، وملفات الذاكرة ، وحقول قاعدة البيانات في طرق الكائنات ، والاستفادة الكاملة من مزايا التكنولوجيا الموجهة للكائنات من هذا ، يمكن للتطبيقات نسخ البيانات في مختلف كائنات الدفق بسهولة إلى حد ما.
قراءة وكتابة الكائنات (المرشحين) تشمل كائنات tfiler وكائنات treader وكائنات twriter. كائن Tfiler هو الكائن الأساسي لقراءة الملفات والكتابة ، والاستخدامات الرئيسية لـ Treader و Twriter في التطبيقات. كل من كائنات treader و twriter موروثة مباشرة من كائنات tfiler. يحدد كائن Tfiler الخصائص الأساسية وطرق كائن Filer.
تؤدي كائنات Fileer بشكل أساسي وظيفتين رئيسيتين:
● الوصول إلى ملفات ومكونات النماذج في ملفات النماذج
● توفير التخزين المؤقت للبيانات لتسريع عمليات قراءة البيانات وكتابةها
من أجل أن يكون لديك فهم إدراكي للكائنات البث وقراءة وكتابة الكائنات ، دعنا نلقي نظرة أولاً على مثال.
أ) اكتب ملف
الإجراء TFOMR1.Writedata (المرسل: TOBJECT) ؛
var
Filestream: tfilestream ؛
MyWriter: Twriter ؛
أنا: عدد صحيح
يبدأ
filestream: = tfilestream.create ('c: /test.txt'،fmopenwrite) ؛ // إنشاء كائن دفق الملف
MyWriter: = Twriter.Create (FileStream ، 1024) ؛
mywriter.writelistbegin ؛
لأني: = 0 إلى memo1.lines.count-1 تفعل
myWriter.WriteString (memo1.lines [i]) ؛
mywriter.writelistend ؛
filestream.keek (0 ، sofrompeginning) ؛
mywriter.free ؛
Filestream.free ؛
نهاية؛
ب) اقرأ الملف
الإجراء tform1.ReadData (المرسل: tobject) ؛
var
Filestream: tfilestream ؛
Myreader: Treader ؛
يبدأ
filestream: = tfilestream.create ('c: /test.txt'،fmopenread) ؛
MyReader: = trreader.create (FileStream ، 1024) ؛
MyReader.ReadListbegin ؛
memo1.lines.clear ؛
بينما لا myreader.endoflist do // لاحظ طريقة treader: endoflist
يبدأ
memo1.lines.add (MyReader.ReadString) ؛
نهاية؛
MyReader.ReadListend ؛
myreader.free ؛
Filestream.free ؛
نهاية؛
العمليتان أعلاه هما واحدة لعملية الكتابة والآخر لعملية القراءة. تستخدم عملية الكتابة twriter لحفظ المحتوى (معلومات النص) في مذكرة كملف ثنائي تم حفظه على القرص باستخدام tfilestream. عملية القراءة هي مجرد عكس عملية الكتابة. يمكن أن يرى تشغيل البرنامج أن عملية القراءة تعيد بإخلاص المعلومات المحفوظة في عملية الكتابة.
يصف الشكل التالي العلاقة بين كائنات البيانات (بما في ذلك الكائنات والمكونات) ، وتدفق الكائنات ، وقراءة وكتابة الكائنات.
الشكل (1)
تجدر الإشارة إلى أن كائنات القراءة والكتابة مثل كائنات tfiler وكائنات treader وكائنات twriter تسمى مباشرة من قبل كتاب التطبيق. وكتابة آلية المكون.
بالنسبة لدفق الكائنات ، يتم تقديم العديد من المواد المرجعية بالتفصيل ، في حين أن المواد المرجعية لكائنات tfiler وكائنات Treader وكائنات twriter ، وخاصة آليات قراءة المكون نادرة. .
2. كائنات القراءة والكتابة (FILER) وآلية القراءة والكتابة المكونة
يستخدم كائن Fileer بشكل أساسي للوصول إلى ملفات ومكونات نموذج Delphi في ملفات النماذج.
يتم استخدام ملفات DFM لنماذج تخزين Delphi. النماذج هي جوهر البرمجة البصرية دلفي. يتوافق النموذج مع النافذة في تطبيق Delphi ، والمكونات المرئية في النموذج تتوافق مع عناصر الواجهة في النافذة ، والمكونات غير المرئية مثل Timerer و Topendialog ، والتي تتوافق مع وظيفة معينة من تطبيق Delphi. يتركز تصميم تطبيق Delphi بالفعل على تصميم النموذج. لذلك ، تشغل ملفات DFM أيضًا موقعًا مهمًا للغاية في تصميم تطبيق Delphi. يتم تضمين جميع العناصر في النموذج ، بما في ذلك خصائص النموذج ، في ملف DFM.
في نافذة تطبيق Delphi ، يتم ربط عناصر الواجهة من خلال علاقات الملكية ، وبالتالي فإن هيكل الشجرة هو التعبير الأكثر طبيعية ؛ يتم تخزين ملفات DFM فعليًا في النص (تم تخزينها مسبقًا كملفات ثنائية في Delphi2.0) ، ومن المنطقي ، ترتيب علاقات كل مكون في بنية شجرة. من هذا النص ، يمكنك رؤية بنية شجرة النموذج. فيما يلي محتوى ملف DFM:
نموذج الكائن 1: tform1
اليسار = 197
أعلى = 124
...
Pixelsperinch = 96
Textheight = 13
كائن Button1: Tbutton
اليسار = 272
...
Caption = 'button1'
taborder = 0
نهاية
لوحة الكائن 1: tpanel
اليسار = 120
...
Caption = 'Panel1'
taborder = 1
مربع الاختيار كائن 1: tcheckbox
اليسار = 104
...
Caption = 'checkbox1'
taborder = 0
نهاية
نهاية
نهاية
يتم إنشاء ملف DFM بواسطة TWRITER من خلال دفق كائن الدفق. .
عند بدء تشغيل البرنامج ، يقرأ Treader النموذج والمكونات من خلال دفق كائن الدفق ، لأنه عندما يقوم Delphi بتجميع البرنامج ، فإنه يستخدم تعليمات التجميع {$ r *.dfm} لتجميع معلومات ملف DFM في الملف القابل للتنفيذ باستخدام المترجم التعليمات {$ r *.dfm}.
لا يمكن لـ Treader و Twriter قراءة وكتابة معظم أنواع البيانات القياسية فقط في كائن Pascal ، ولكن أيضًا قراءة وكتابة أنواع متقدمة مثل القائمة والمتغير ، وحتى قراءة وكتابة المكونات والمكونات. ومع ذلك ، يوفر Treader و Twriter أنفسهم وظائف محدودة للغاية ، ويتم معظم العمل الفعلي بواسطة Tstream ، فئة قوية للغاية. بمعنى آخر ، يعد Treader و Twriter مجرد أدوات ، وهي مسؤولة فقط عن كيفية قراءة المكونات وكتابةها.
نظرًا لأن Tfiler عبارة عن فئة من أجداد الأسلاف العامة من Treader و Twriter ، لفهم Treader و Twriter ، ابدأ بـ Tfiler.
tfiler
دعونا أولاً نلقي نظرة على تعريف فئة Tfiler:
tfiler = فئة (TOBJECT)
خاص
fstream: tstream ؛
fbuffer: مؤشر ؛
fbufsize: عدد صحيح ؛
fbufpos: عدد صحيح ؛
fbufend: عدد صحيح ؛
Froot: tcomponent ؛
flookuproot: tcomponent ؛
فانكستور: tperSentive ؛
Fignorechildren: Boolean ؛
محمية
setRoot الإجراء (القيمة: tcomponent) ؛
عام
إنشاء مُنشئ (تيار: tstream ؛ bufsize: integer) ؛
المدمرة تدمير.
الإجراء DEFINEPROPERTY (اسم const: سلسلة ؛
ReadData: TreaderProc ؛
Hasdata: Boolean) ؛
الإجراء defineBinaryProperty (اسم const: سلسلة ؛
ReadData ، writedata: tstreamproc ؛
Hasdata: Boolean) ؛
الإجراء Flushbuffer
خاصية جذر: tcomponent قراءة froot كتابة setRoot ؛
Property Lookuproot: Tcomponent Read Flookuproot ؛
سلف الممتلكات: tpersistent قراءة فانكستور كتابة فانكستور ؛
الممتلكات الجاهلية: قراءة المنطقية Fignorechildren كتابة Fignorechildren ؛
نهاية؛
كائن Tfiler هو فئة مجردة من Treader و Twriter ، والتي تحدد الخصائص والطرق الأساسية المستخدمة لتخزين المكونات. يحدد جذر الجذر. صنع من قبل كائن الدفق. لذلك ، طالما أن الوسائط التي يمكن الوصول إليها في كائن الدفق ، يمكن الوصول إلى المكون بواسطة كائن Filer.
يوفر كائن Tfiler أيضًا طريقتين عامتين يحددان الخصائص: تعريف property و definebinaryproperty ، والتي تمكن الكائن من قراءة وكتابة الخصائص التي لم يتم تعريفها في الجزء المنشور من المكون. دعونا نركز على هاتين الطريقتين أدناه.
يتم استخدام طريقة DefineProperty () لاستمرار أنواع البيانات القياسية مثل الأوتار ، الأعداد الصحيحة ، المنطقية ، الشخصيات ، النقاط العائمة ، والتعداد.
في طريقة defineProperty. تحدد المعلمة الاسم اسم السمة التي يجب كتابتها إلى ملف DFM ، والذي لم يتم تعريفه في الجزء المنشور من الفصل.
تحدد معلمات ReadData و Writedata طريقة قراءة البيانات المطلوبة وكتابةها عند الوصول إلى كائن. أنواع المعلمات ReadData ومعلمات writedata هي treaderproc و twriterproc على التوالي. تم إعلان هذين النوعين هكذا:
TreaderProc = الإجراء (القارئ: Treader) للكائن ؛
twriterproc = الإجراء (الكاتب: twriter) للكائن ؛
تحدد معلمة HASDATA ما إذا كان لدى الخاصية البيانات التي سيتم تخزينها في وقت التشغيل.
تحتوي طريقة Definebinaryproperty على العديد من أوجه التشابه مع DefineProperty.
دعنا نوضح استخدامات هاتين الطريقتين أدناه.
وضعنا مكونًا غير مرئي مثل Timter على النموذج. ؟
افتح ملف DFM لهذا النموذج ويمكنك رؤية عدة أسطر مماثلة لما يلي:
كائن Timer1: Timerer
اليسار = 184
أعلى = 149
نهاية
لا يمكن لنظام دفق دلفي حفظ البيانات المنشورة إلا ، لكن Timper لم يتم نشر سمات اليسرى والأعلى ، فكيف يتم حفظ هذه البيانات؟
تتيمر فئة مشتقة من TCOMPONENT.
الإجراء tcomponent.defineProperties (filer: tfiler) ؛
var
الأجداد: tcomponent ؛
معلومات: Longint ؛
يبدأ
معلومات: = 0 ؛
الأجداد: = tcomponent (filer.ancestor) ؛
إذا كان الأجداد <> nil ثم المعلومات: = Ancestor.FdesignInfo ؛
filer.defineProperty ('Left' ، readleft ، writeleft ،
Longrec (fdesigninfo) .lo <> longrec (info) .lo) ؛
filer.defineProperty ('top' ، readtop ، writetop ،
Longrec (fdesigninfo) .hi <> longrec (info) .hi) ؛
نهاية؛
DefineProperties من TComponent هي طريقة افتراضية تكتب فوق فئة أسلافها tpersenterge ، وفي فئة tpersientent هذه الطريقة هي طريقة افتراضية فارغة.
في طريقة DefineProperties ، يمكننا أن نرى أن هناك كائن Fileer كمعلمة. قيمة. ويطلق على طريقة تعريف Tfiler ويحدد أساليب readleft و writeleft و readtop و writeTop لقراءة والكتابة الممتلكات اليسرى والأعلى.
لذلك ، فإن أي مكون مشتق من TComponent ، حتى لو لم يكن لديه سمات اليسار والأعلى ، سيكون لها خصائص من هذا القبيل عند التدفق إلى ملف DFM.
في عملية البحث عن البيانات ، وجد أن القليل من البيانات تتضمن آليات قراءة وكتابة المكونات. نظرًا لأن عملية كتابة المكونات قد اكتملت بواسطة IDE Delphi أثناء مرحلة التصميم ، فلا يمكن تتبعها لعملية التشغيل. لذلك ، يدرك المؤلف آلية قراءة المكون من خلال تتبع رمز VCL الأصلي أثناء تشغيل البرنامج ، ويحلل آلية كتابة المكون من خلال آلية القراءة و Twriter. لذلك ، سيشرح ما يلي آلية قراءة المكون والكتابة وفقًا لعملية التفكير هذه ، أولاً يتحدث عن Treader ، ثم Twriter.
تريدر
انظر أولاً إلى ملفات مشروع Delphi وستجد بضعة أسطر من التعليمات البرمجية مثل هذا:
يبدأ
application.initialize ؛
application.createform (tform1 ، form1) ؛
application.run ؛
نهاية.
هذا هو مدخل برنامج دلفي. ببساطة وضع هذه الخطوط من الكود: تنفيذ بعض أعمال التهيئة اللازمة في بداية التطبيقات. .
أكثر ما نهتم به الآن هو جملة إنشاء نموذج. كيف يتم إنشاء النماذج والمكونات على النماذج؟ كما ذكرنا سابقًا: يتم تضمين جميع المكونات في النموذج ، بما في ذلك خصائص النموذج نفسه في ملف DFM. في الملف القابل للتنفيذ. لذلك ، يمكن أن نستنتج أنه عند إنشاء نموذج ، تحتاج إلى قراءة معلومات DFM.
من خلال اتباع البرنامج خطوة بخطوة ، يمكنك العثور على أن البرنامج يستدعي طريقة ReadRootComponent لـ Treader أثناء إنشاء النموذج. الغرض من هذه الطريقة هو قراءة مكون الجذر وجميع المكونات التي لديها. دعونا نلقي نظرة على تنفيذ هذه الطريقة:
دالة treader.readrootcomponent (الجذر: tcomponent): tcomponent ؛
...
يبدأ
readsignature.
النتيجة: = لا شيء ؛
GlobalNamespace.beginwrite ؛
يحاول
يحاول
ReadPrefix (أعلام ، i) ؛
إذا الجذر = لا شيء ثم
يبدأ
النتيجة: = tcomponentClass (findClass (readSt). إنشاء (NIL) ؛
result.name: = readstr ؛
إنهاء آخر
يبدأ
النتائج: = الجذر ؛
readstr ؛
إذا كان csDesigning في result.componentState ثم
readstr آخر
يبدأ
تشمل (result.fcomponentState ، csloading) ؛
تشمل (result.fcomponentState ، CSReading) ؛
result.name: = findUniquename (readStr) ؛
نهاية؛
نهاية؛
فروت: = النتائج ؛
ffinder: = tclassfinder.create (tperSistentClass (result.clasStype) ، true) ؛
يحاول
flookuproot: = النتائج ؛
G: = Globalloaded ؛
إذا كان g <> nil ثم
مُعادف: = ز آخر
floaded: = tlist.create ؛
يحاول
إذا floaded.indexof (froot) <0 ثم
floaded.add (froot) ؛
fowner: = froot ؛
تشمل (froot.fcomponentState ، csloading) ؛
تشمل (froot.fcomponentState ، CSReading) ؛
froot.ReadState (الذات) ؛
Explude (froot.fcomponentState ، CSReading) ؛
إذا كان g = nil ثم
بالنسبة إلى i: = 0 to floaded.count - 1 do tcomponent (floaded [i]).
أخيراً
إذا g = nil ثم floaded.free ؛
floaded: = nil ؛
نهاية؛
أخيراً
ffinder.free ؛
نهاية؛
...
أخيراً
GlobalNamespace.endwrite ؛
نهاية؛
نهاية؛
READROOTCOMPONENT FIRRALENT READSIGNATURE لقراءة علامة كائن FILER ('TPF0'). يمكن أن يؤدي اكتشاف العلامات قبل تحميل الكائنات إلى منع الإهمال وقراءة البيانات غير الفعالة أو القديمة.
دعنا نلقي نظرة على ReadPrefix (أعلام ، i). عندما يكتب كائن الكتابة مكونًا إلى دفق ، يشير إلى وجود قيمتين تشير القيمة الثانية إلى الترتيب الذي تم إنشاؤه في شكل الأجداد.
ثم ، إذا كانت المعلمة الجذرية لا شيء ، يتم إنشاء مكون جديد مع اسم الفصل بواسطة ReadStr ، ويتم قراءة خاصية اسم المكون من الدفق ؛ .
froot.ReadState (الذات) ؛
هذه جملة حاسمة للغاية. على الرغم من أن طريقة READSTATE هذه هي طريقة TCOMPONENT ، إلا أنه يمكن العثور على مزيد من التتبع بأنها في الواقع تقع على مستوى طريقة ReadDatainner.
الإجراء Treader.ReadDatainner (مثيل: tcomponent) ؛
var
Oldparent ، Oldowner: tcomponent ؛
يبدأ
في حين أن لا endoflist لا readProperty (مثيل) ؛
قائمة القراءة ؛
oldparent: = الوالدين ؛
Oldowner: = المالك ؛
الوالد: = مثيل. getChildParent ؛
يحاول
المالك: = مثيل.
إذا لم يتم تعيينه (المالك) ثم المالك: = الجذر ؛
في حين أن endoflist do readcomponent (nil) ؛
قائمة القراءة ؛
أخيراً
الوالد: = oldparent ؛
المالك: = Oldowner ؛
نهاية؛
نهاية؛
هناك هذا السطر من الكود:
في حين أن لا endoflist لا readProperty (مثيل) ؛
يستخدم هذا لقراءة خصائص مكون الجذر. بالنسبة لهذين الخصائص المختلفة ، يجب أن يكون هناك طريقتان مختلفتان للقراءة.
الإجراء Treader.ReadProperty (Ainstance: tperSentive) ؛
...
يبدأ
...
propinfo: = getPropInfo (exate.classinfo ، fpropName) ؛
إذا كان propinfo <> nil ثم ReadPropValue (مثيل ، propinfo) آخر
يبدأ
{لا يمكن التعافي بشكل موثوق من خطأ في خاصية محددة}
fcanhandleexcepts: = false ؛
مثيل. defineProperties (الذات) ؛
fcanhandleexcepts: = صواب ؛
إذا كان fpropName <> '' ثم
Propertyerror (fpropName) ؛
نهاية؛
...
نهاية؛
من أجل توفير المساحة ، تم حذف بعض التعليمات البرمجية.
propinfo: = getPropInfo (exate.classinfo ، fpropName) ؛
هذا الرمز هو الحصول على معلومات الخاصية المنشورة fpropName. من الكود التالي ، يمكننا أن نرى أنه إذا لم تكن معلومات السمة فارغة ، فسيتم قراءة قيمة السمة من خلال طريقة ReadPropValue ، وأن طريقة ReadPropValue تقرأ قيمة السمة من خلال وظيفة RTTI ، والتي لن يتم تقديمها بالتفصيل هنا. إذا كانت معلومات السمة فارغة ، فهذا يعني أنه لم يتم نشر السمة fpropName ، ويجب قراءتها من خلال آلية أخرى. هذه هي طريقة DefineProperties المذكورة أعلاه ، على النحو التالي:
مثيل. defineProperties (الذات) ؛
هذه الطريقة تدعو في الواقع طريقة تعريف Treader:
الإجراء Treader.DefineProperty (اسم const: سلسلة ؛
ReadData: TreaderProc ؛
يبدأ
إذا كان sametext (الاسم ، fpropName) وتم تعيينه (readData) ثم
يبدأ
ReadData (الذات) ؛
fpropName: = '' ؛
نهاية؛
نهاية؛
يقارن أولاً ما إذا كان اسم سمة القراءة هو نفس اسم سمة الإعداد المسبق.
حسنًا ، تمت قراءة مكون الجذر ، ويجب أن تكون الخطوة التالية هي قراءة المكونات المملوكة لمكون الجذر. دعونا نلقي نظرة على الطريقة مرة أخرى:
الإجراء Treader.ReadDatainner (مثيل: tcomponent) ؛
هناك رمز يتبع هذه الطريقة:
في حين أن endoflist do readcomponent (nil) ؛
هذا هو بالضبط ما يستخدم لقراءة مكونات الطفل. آلية القراءة لمكون الطفل هي نفس قراءة مكون الجذر الذي تم تقديمه أعلاه ، وهو اجتياز عميق لشجرة.
حتى الآن ، تم تقديم آلية قراءة المكون.
دعونا نلقي نظرة على آلية كتابة المكون. عندما نضيف مكونًا إلى النموذج ، سيتم حفظ خصائصه ذات الصلة في ملف DFM ، ويتم تنفيذ هذه العملية بواسطة Twriter.
Ø Twriter
كائن Twriter هو كائن FaLer فوري يكتب البيانات في دفق. ويرث كائن TWRITER مباشرة من TFILER.
يوفر كائن Twriter العديد من الطرق لكتابة أنواع مختلفة من البيانات في الدفق. لذلك ، لإتقان أساليب التنفيذ والتطبيق لكائنات Twriter ، يجب أن تفهم تنسيق كائنات الكاتب التي تخزن البيانات.
أول شيء يجب ملاحظته هو أن كل دفق كائن Fileer يحتوي على علامات كائن Filer. تستغرق هذه العلامة أربعة بايت وقيمتها هي "TPF0". يقوم كائن Fileer بالوصول إلى TAG الخاص بـ ContractIgNature و READSIGNATURE. تُستخدم هذه العلامة بشكل أساسي لتوجيه عمليات القراءة عندما تقرأ كائنات القارئ البيانات (المكونات ، إلخ).
ثانياً ، يجب أن يترك كائن الكاتب جزءًا من علم البايت قبل تخزين البيانات للإشارة إلى نوع البيانات المخزنة لاحقًا. هذه البايت هي قيمة نوع tvalueType. TvalueType هو نوع التعداد الذي يحتل مساحة بايت واحدة ، وتعريفه كما يلي:
tvalueType = (Vanull ، Valist ، Vaint8 ، Vaint16 ، Vaint32 ، vaentended ، vastring ، vaident ،
Vafalse ، vatrue ، vabinary ، vaset ، valstring ، vanil ، vacollection) ؛
لذلك ، في تنفيذ كل طريقة كتابة بيانات لكائن الكاتب ، يجب أولاً كتابة بت العلم ثم كتابة البيانات المقابلة ؛ قراءة البيانات. شعار Valist له غرض خاص. لذلك ، عند كتابة العديد من العناصر المتطابقة المتتالية في كائن الكاتب ، استخدم أولاً WriteListbegin لكتابة علامة Valist ، وبعد كتابة عناصر البيانات ، ثم اكتب علامة Vanull ؛ استخدم وظيفة endoflist في الوسط حدد ما إذا كان هناك علامة vanull.
دعونا نلقي نظرة على طريقة مهمة للغاية لـ Twriter Writedata:
الإجراء twriter.writedata (مثيل: tcomponent) ؛
...
يبدأ
...
WritePrefix (Flags ، fchildpos) ؛
إذا استخدمت QualifiedNames ثم
Writestr (gettypedata (ptypeinfo (easule.classtype.classinfo)). unitname + '.'
آخر
Writestr (extal.className) ؛
Writestr (extal.name) ؛
خصائص: = الموضع ؛
if (fancestorlist <> nil) و (Fancestorpos <fancestorlist.count) ثم
يبدأ
إذا كان الجد <> nil ثم Inc (Fancestorpos) ؛
INC (FCHILDPOS) ؛
نهاية؛
WriteProperties (مثيل) ؛
WriteListend ؛
...
نهاية؛
من طريقة Writedata ، يمكننا أن نرى الصورة العامة لإنشاء معلومات ملف DFM. اكتب العلم أولاً (بادئة) أمام المكون ، ثم اكتب اسم الفصل واسم المثيل. ثم هناك جملة مثل هذا:
WriteProperties (مثيل) ؛
يستخدم هذا لكتابة خصائص المكون. كما ذكرنا سابقًا ، في ملفات DFM ، هناك سمات منشورة وسمات غير منشورة. دعونا نلقي نظرة على تنفيذ كتاب "Writeproperties":
الإجراء twriter.writeproperties (مثيل: tpersistent) ؛
...
يبدأ
العد: = gettypedata (مثيل. cclassinfo)^. propcount ؛
إذا احسب> 0 ثم
يبدأ
getMem (proplist ، count * sizeof (pointer)) ؛
يحاول
getPropinfos (extal.classinfo ، proplist) ؛
لأني: = 0 لعد - 1 افعل
يبدأ
propinfo: = proplist^[i] ؛
إذا propinfo = nil ثم
استراحة؛
إذا كان isstoredProp (مثيل ، propinfo) ثم
WriteProperty (مثيل ، propinfo) ؛
نهاية؛
أخيراً
Freemem (proplist ، count * sizeof (pointer)) ؛
نهاية؛
نهاية؛
مثيل. defineProperties (الذات) ؛
نهاية؛
يرجى الاطلاع على الرمز التالي:
إذا كان isstoredProp (مثيل ، propinfo) ثم
WriteProperty (مثيل ، propinfo) ؛
تحدد الوظيفة IsstoredProp ما إذا كان هناك حاجة إلى حفظ العقار عن طريق تخزين المؤهل.
بعد حفظ الممتلكات المنشورة ، يجب حفظ الممتلكات غير المنشورة.
مثيل. defineProperties (الذات) ؛
تم ذكر تنفيذ DefineProperties من قبل.
حسنًا ، حتى الآن لا يزال هناك سؤال: كيف يتم حفظ مكونات الطفل المملوكة لمكون الجذر؟ دعونا نلقي نظرة على طريقة Writedata (تم ذكر هذه الطريقة مسبقًا):
الإجراء twriter.writedata (مثيل: tcomponent) ؛
...
يبدأ
...
إذا لم يكن الجهل بعد ذلك
يحاول
إذا (فانكستور <> nil) و (فانكستور هو tcomponent) ثم
يبدأ
إذا (فانكستور هو tcomponent) و (csinline في tcomponent (فانكستور) .componentState) ثم
frootancestor: = tcomponent (فانكستور) ؛
FancestorList: = tlist.create ؛
TComponent (Fancestor) .getChildren (Addancestor ، Frotancestor) ؛
نهاية؛
إذا كان csinline في extine.componentState ثم
Froot: = مثيل ؛
مثيل.
أخيراً
fancestorlist.free ؛
نهاية؛
نهاية؛
تتيح خاصية MigrEchildren كائن الكاتب من تخزين مكون دون تخزين مكونات الطفل المملوكة للمكون. إذا كانت ملكية الجينوريكيلد صحيحة ، فإن كائن الكاتب لا يخزن المكونات الفرعية التي يتمتع بها عند تخزين المكون. خلاف ذلك ، سيتم تخزين المكونات الفرعية.
مثيل.
هذه هي الجملة الأكثر أهمية لكتابة المكونات الفرعية. وبهذه الطريقة ، ما نراه في ملف DFM هو بنية مكون يشبه الأشجار.