Shagrouni

كيف يحتفظ البرنامج بآخر شكل له عند تشغيله كل مرّة

خالد الشقروني, 28 نوفمبر 2002

أوراق دلفي
 


كيف يحتفظ برنامجنا بآخر شكل كان عليه عند تشغيله لآخر مرّة.  أو بعبارة أدق كيف تحتفظ النماذج= الشاشات forms بنفس الحجم و الو ضعية التي كانت عليها كما تركها المستخدم آخر مرّة بما فيها خصائصها و خصائص المكوّنات الأخرى التي تحتويها الأخرى كالخطوط والألوان.

لو قمت بتشغيل برنامج المفكرة Notepad و غيّرت في حجم و موضع نافذة البرنامج؛ أو حتى نوع الخط ؛ فإن المرة الثانية التي تعيد فيها تشغيل البرنامج ستلاحظ أنّه احتفظ بنفس التغييرات. الطريقة التي يتّبعها برنامج المفكرة ؛ هي قيامه بتخزين هذه المعلومات حال اغلاقه في سجلّ الويندوز Registry في مدخل: HKEY_CURRENT_USER\Software\Microsoft\Notepad ،ثم قيامه بقراءة هذه المعلومات عند تشغيله مرّة أخرى ليقوم بتوصيف النافذة و صياغة خصائصها حسب المعلومات المسجّلة.  

هذا الأسلوب مناسب في حالة أن الخصائص أو المعلومات المراد تسجيلها و الاحتفاظ بها معدودة و يسهل حصرها.

لكن ماذا لو أن النموذج form مزدحم بالمكونات بأنواعها، وتريد أن تحتفظ بكل التغييرات التي تطرأ عليها، ماذا لو أردت أن تحتفظ حتى بالبيانات التي يدخلها المستخدم كالنصوص في مكونات الكتابة أو الصور التي يحملّها المستخدم في احدى مكونات الصور في البرنامج.

الأسلوب المقترح هنا، هو أن نقوم بحفظ كافة خصائص النموذج form حال اغلاقه دفعة واحدة في ملف خارجي . و عند تشغيل البرنامج مرّة أخرى و اظهار النموذج، يقوم البرنامج بتحميل الملف و تخصيص بياناته للنموذج ذات العلاقة عوضا عن البيانات المحددة في وقت التصميم. و سنستخدم في حفظ و قراءة الملف أمرين من أوامر دلفي : WriteComponent  لحفظ المكونات في الملف و  ReadComponent لقراءة المكونات من نفس الملف.

 

unit fPreservForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs; type TForm1 = class(TForm) private

اعادة تعريف الاجرائيتين Create و BeforeDestruction التابعتين أصلا لصنف(class)   TComponent الذي يعدّ أحد الأصول التي ينحدر منها صنف TForm:

       
         
  public
    constructor Create(AOwner: TComponent); override; // (1)
    procedure BeforeDestruction; override;  // (2)
  end
;

يمكنك الوقوف بالمؤشّر عل سطر التعريف و الضغط على مفاتيح Ctrl+Shift+C لبناء جسم الاجرائتين آليا.

بعدها، نعرّف متغيرا عاما نحتفظ فيه باسم و مسار ملف الحفظ :


var
  Form1: TForm1;
  PreservePath: string; // (3)
implementation

المتن في الاجرائيتين ، لاحظ أن اسم الملف هو نفس اسم صنف النموذج متبوعا بالامتداد : "sav" ، و يتم حفظه في مجلد Preserve.

{$R *.dfm}
 
constructor TForm1.Create(AOwner: TComponent); // (4)  
begin

  PreservePath := ExtractFilePath(Application.ExeName) + 
    'Preserve';
  if not DirectoryExists(PreservePath) then
    CreateDir(PreservePath);
  PreservePath := PreservePath + '\';

  if FileExists(PreservePath + ClassName + '.sav') then
  begin
    CreateNew(AOwner, 0);
    with TFileStream.Create(PreservePath + ClassName + '.sav',
                            fmOpenRead or fmShareDenyWrite) do
    try
      ReadComponent(Self);
    finally
      Free;
    end;
  end
  else

  inherited Create(AOwner);

end;
procedure TForm1.BeforeDestruction; // (5) 
begin
  inherited;

  with TFileStream.Create(PreservePath + ClassName + '.sav',
fmCreate) do try WriteComponent(Self); finally Free; end; end; end.

ملاحظة أخيرة:
بما أن النموذج سوف يقرأ محتوياته من ملف خارجي و لن يعتدّ بالمواصفات المحددة له عند التصميم؛ فربما تجد نفسك مضطرا لعدم تفعيل الاجرائتين الا عند الاصدار النهائي للبرنامج. 

Shagrouni 2002 Khaled Shagrouni khaled@shagrouni.com