alwahatech

alwahatech (http://www.alwahatech.net/vb/index.php)
-   واحـة لغـات البرمجـة (http://www.alwahatech.net/vb/forumdisplay.php?f=37)
-   -   دورة تعليمية في تصميم دليل هاتف في دلفي (http://www.alwahatech.net/vb/showthread.php?t=688)

nagati 04-06-2008 01:44 PM

دورة تعليمية في تصميم دليل هاتف في دلفي
 
لأخوة الأكارم ..


هذا شرح خطوة بخطوة لتصميم برنامج هاتف بسيط بواسطة دلفي

المطلوب من أجل الاستفادة من الدورة الالمام بأساسيات الدلفي

وسيتم شرح كل خطوة بخطوتها نظرياً ثم عملياً مع الدعم بالصور والمرفقات اللازمة ..

أرجو المتابعة والتفاعل ..


مع تحياتي [عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

nagati 04-06-2008 01:56 PM

1 مرفق
الدرس الأول


سنبدأ بتحليل ما نريده من البرنامج وأبعاده

البرنامج هو برنامج بسيط جداً عبارة على دليل هاتف بسيط ، يتم تخزين الاسم - الكنية - العنوان - هاتف المنزل - هاتف العمل - الفاكس - المحمول - البريد الالكتروني - الموقع - ملاحظات

لن نعتمد على قواعد البيانات بل سنتعامل مع ملف نصي عادي

المطلوب من البرنامج : حفظ واستعراض الأسماء - البحث وفق أي حقل

إذاً .. دعونا نبدأ بالعمل :

نشغل برنامج دلفي وسيكون أمامنا الآن مشروع جديد به فورم فارغ طبعاً

سننجز القسم الأول من البرنامج ( تصميم الشكل) :
بعد وضع كلفة الحقول .. نستخدم زر BitBtn من مجموعة Additional .. نضعه ثم نعين خاصية Kind تساوي bkClose
ثم نغير الـ Caption إلى إغلاق (هذا الزر سيقوم الآن بإغلاق الفورم فوراً دون الحاجة إلى كنابة كود الإغلاق)
سيبدو الفورم كما يلي بعد الانتهاء من تصميم الشكل :

[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]
وهذا هو الملف مرفق

nagati 04-06-2008 01:59 PM

الدرس الثاني

الآن كما نشاهد أن كل بطاقة في دليل الهاتف تتألف من عدد من الحقول ..
والمفروض من أجل سهولة العمل أن نقوم بتعريف نمط جديد Type خاص بالبطاقات

تعريف الأنماط الخاصة بالبرنامج :
1- يتم وضع تعريف الأنماط الخاصة بالبرنامج ضمن تعريفات كلمة Type الموجودة في أعلى Unit1
2- يأخذ تعريف نمط جديد مؤلف من عدة سجلات هذه الصيغة :

كود:

MyType = Record
Rec1 : Type ;
Rec2 : Type;
.
.
end;


3- بالنسبة لحالتنا سنسمي النمط الجديد PhoneCard وسيتم تعريفه كما يلي :


كود:

phoneCard = Record
FName,LName,Address : string;
HomeNo,JobNo,FaxNo,Mobile : string;
Email , Page, Rem : string;
End;


[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]


من أجل التعامل مع عدد من السجلات المرتبة يفضل استخدام تقنية اللوائح المترابطة وهي تقنية مهمة جداً في دلفي سيتم شرحها الآن بالتفصيل :
اللوائح المترابطة :تعتمد هذه التقنية على ربط مجموعة من أنماط السجلات مع بعضها البعض بواسطة متحولات من النمط مؤشر ، فما هو نمط المؤشر ؟؟
المؤشر : هو نمط معطيات يتم استخدامه لتخزين عنوان في الذاكرة أي أنه يدل على عنوان كائن ما في الذاكرة ، حيث يمكننا استخدام هذا العنوان للتعامل مع الكائن المعنون مباشرة
>> يتم تعريف متحول من النمط مؤشر لأحد الأنماط بوضع إشارة ^ قبل النمط
>> يتم اتخزين قيمة مؤشر في متحول بوضع إشارة @ قبل اسم الكائن المراد عنونته في متحول المؤشر
>> يتم التعامل مع الكائن المخزن في متحول من خلال وضع إشارة ^ بعد اسم المتحول من النمط مؤشر
مثال :


كود:

var
X, Y: Integer; // X and Y are Integer variables
P: ^Integer; // P points to an Integer
begin
X := 17; // assign a value to X
P := @X; // assign the address of X to P
Y := P^; // dereference P; assign the result to Y
end;


تستخدم المؤشرات في أحد أهم استخداماتها في بناء اللوائح المترابطة .. التي هي عبارة عن مجموعة متحولات من نمط سجل محجوزة في الذاكرة بحيث يحتوي كل متحول منها على عنوان متحول واحد آخر على الأقل بحيث تشكل سلسلة من المتحولات لهذا تدعى اللوائح المترابطة
ويتم إنشاء متحول جديد في الذاكرة من خلال التعليمة New بهذه الصيغة :

كود:

New(VarPointer)



مثال :

كود:
type
PListEntry = ^TListEntry;
TListEntry = record
Next: PListEntry;
Text: string;
Count: Integer;
end;
var
List, P: PListEntry;
begin
...
New(P);
P^.Next := List;
P^.Text := 'Hello world';
P^.Count := 1;
List := P;
...
end;




بناءً على ما تقدم سنقوم بتعريف نمط جديد من نوع مؤشر إلى النمط PhoneCard سنسمية PhonePointer
أيضاً سنقوم بتعديل النمط phoneCard وإضافة سجلان عليه هما Next و Prev من النمط PhonePointer
وسيصبح الكود كما يلي :

كود:

PhonePointer = ^PhoneCard;
phoneCard = Record
FName,LName,Address : string;
HomeNo,JobNo,FaxNo,Mobile : string;
Email , Page, Rem : string;
Next,Prev : PhonePointer;
End;


[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

nagati 04-06-2008 02:15 PM

1 مرفق
الدرس الثالث

من أجل التعامل مع البرنامج كقاعدة بيانات فإنه يلزمنا أزرار التنقل بين السجلات
التي هي :
سجل جديد ، السجل الأول ، السجل السابق ، السجل التالي ، السجل الأخير بالإضافة إلى Panel نستخدمها لعرض رقم السجل الحالي بحيث يصبح شكل النموذج كما يلي :
[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

وسنسمي الأزرار على التوالي : GoNew - GoPrevious - GoNext - GoLast
ولعرض تعليقات Hints للأزرار نكتب في خاصية Hint لكل زر شرح عنه .. ثم نجعل خاصية ShowHint تساوي True
[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

لنقم الآن بتحديد الإجراءات والدوال التي تلزم لنا في البرنامج لكي نقوم ببرمجتها وهي :
>> دالة لإضافة عنصر جديد من النمط phoneCard وربطه في اللائحة المترابطة والبطاقات الموجودة
>> إجراء تخزين القيم الموجودة في الفورم ضمن عنصر من النمط phoneCard
>> إجراء عرض عنصرphoneCard في فورم
>> إجراء تفريغ الحقول في الفورم
>> إجراء إظهار رقم السجل الحالي في الـ Panel بالإضافة إلى تحديد حالة Enabled للأزرار حسب السجل الحالي
[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

1- دالة إضافة عنصر جديد من النوع phoneCard وربطه في اللائحة المترابطة والبطاقات الموجودة :
هذه الدالة وظيفتها إنشاء عنصر جديد من النمط phoneCard وتخزين عنوان العنصر السابق لها في خاصية Prev وتخزين عنوان العنصر الجديد في خاصية Next للعنصر السابق وتعود هذه الدالة بقيمة من النوع PhonePointer كمؤشر للعنصر الجديد الذي تم إنشاؤه
وسنمرر لهذه الدالة موشر للعنصر السابق
وهذه هي الدالة(نكتبها في آخر ال Unit1 قبل كلمة End.) :

كود:

Function NewPhoneCard(PLastCard : PhonePointer):PhonePointer;
Var
NewCard : PhonePointer;
Begin
New(PNewCard);
PNewCard^.Prev := PLastCard;
If PlastCard <> nil then
PLastCard^.Next := PNewCard
Else
FirstPoint:=PNewCard;
NewPhoneCard := PNewCard;
End;

ويجب أن لا ننسى أننا يجب أن نصرح عن أي إجراء أو دالة أعلى الـ Unit1 بعد التصريح عن المتحولات العامة حتى نتمكن من استعماله في أجزاء الـ Unit الأخرى
كما نشاهد :

كود:

var
Form1: TForm1;

Function NewPhoneCard(var PLastCard : PhonePointer):PhonePointer;

implementation

[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

2- إجراء تخزين القيم الموجودة في الفورم ضمن عنصر من النمط phoneCard

كود:

Procedure SaveToCard(PCard : PhonePointer);
Begin
With Form1 Do
Begin
Pcard^.FName := Edit1.Text;
Pcard^.LName := Edit2.Text;
Pcard^.Address := Edit3.Text;
Pcard^.HomeNo := Edit4.Text;
Pcard^.JobNo := Edit5.Text;
Pcard^.FaxNo := Edit6.Text;
Pcard^.Mobile := Edit7.Text;
Pcard^.Email := Edit8.Text;
Pcard^.Page := Edit9.Text;
Pcard^.Rem := Edit10.Text;
End;
End;

[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

3- إجراء عرض عنصرphoneCard في الفورم :

كود:

Procedure GetFromCard(PCard : PhonePointer);
Begin
With Form1 Do
Begin
Edit1.Text := Pcard^.FName;
Edit2.Text := Pcard^.LName;
Edit3.Text := Pcard^.Address;
Edit4.Text := Pcard^.HomeNo;
Edit5.Text := Pcard^.JobNo;
Edit6.Text := Pcard^.FaxNo;
Edit7.Text := Pcard^.Mobile;
Edit8.Text := Pcard^.Email;
Edit9.Text := Pcard^.Page;
Edit10.Text := Pcard^.Rem;
End;
End;

[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

4- إجراء تفريغ الحقول في الفورم :

كود:

Procedure EmptyFields;
Begin
With Form1 Do
Begin
Edit1.text := ';
Edit2.text := ';
Edit3.text := ';
Edit4.text := ';
Edit5.text := ';
Edit6.text := ';
Edit7.text := ';
Edit8.text := ';
Edit9.text := ';
Edit10.text := ';
End;
End;

[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

5- إجراء إظهار رقم السجل الحالي في الـ Panel بالإضافة إلى تحديد حالة Enabled للأزرار حسب السجل الحالي
رقم السجل الحالي : يمكننا معرفة رقم السجل الحالي إذا استخدمنا متحول عام رقمي كعداد للسجلات .. ويتم التعريف عن المتحولات العامة في بداية الـ Unit1 بعد كلمة var
سنسمي هذا المتحول الذي يدل على السجل الحالي CurrentRec .. وسنضيف متحول عام آخر يدل على عدد السجلات بشكل عام سنسميه RecordCount .. وهذان المتحولان يجب أن يكونا من النمط LongInt
وبالاعتماد على قيمة هذين المتحولين يمكننا أن نكتب في Panel قيمة السجل الحالي وعدد السجلات الإجمالي كما يلي :

كود:

Form1.Panel1.Caption := IntToStr(CurrentRec) + ' من ' + IntToStr(RecordCount);

وأيضاً بالاعتماد عليها بإمكاننا تحديد حالة أزرار التنقل (متاحة/غير متاحة) كما يلي :
السجل الحالي = 1 : عدم تفعيل أزرار GoFirst - GoPrevious
السجل الحالي هو الأخير : عدم تفعيل أزرار GoNext - GoLast
وهكذا يكون الإجراء كما يلي :

كود:

Procedure ConfigMovePanel;
Begin
With Form1 Do
Begin
Panel1.Caption := IntToStr(CurrentRec) + ' من ' + IntToStr(RecordCount);
GoFirst.Enabled := (CurrentRec > 1);
GoPrevious.Enabled := GoFirst.Enabled ;
GoNext.Enabled := (CurrentRec < RecordCount);
GoLast.Enabled := GoNext.Enabled;
End;

[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

nagati 04-06-2008 02:17 PM

1 مرفق
الدرس الرابع



الآن يجب أن نستخدم الإجراءات التي سبق لنا تصميمها :
عند عملية الانتقال بالأزرار يجب تخزين محتويات المعلومات الظاهرة على الشاشة في السجل في الذاكرة .. و إذا كان سجل جديد يجب قبلها أن يتم إضافة عنصر جديد من النوع phoneCard ... وبعد ذلك يجب اجراء عملية الانتقال ثم استدعاء إجراء ConfigMovePanel .. لذلك يجب تعريف متحول عام على مستوى الـ Unit من النوع Boolean سنسميه IsNewRec
كما سيلزم لنا تحديد السجل الأول والسجل الأخير والسجل الحالي لذلك سنقوم بتعريف 3 متحولات عامة من النوع PhonePointer سنسميها : FirstPoint , CurrPoint , LastPoint .
بحيث تصبح التعريفات العامة لمتحولات الوحدة Unit1 هكذا :
كود:

var
Form1: TForm1;
CurrentRec , RecordCount : LongInt;
IsNewRec : Boolean;
FirstPoint,CurrPoint,LastPoint : PhonePointer;


وبالاعتماد على المتحول IsNewRec سنقوم ببعض التعديلات على إجراء ConfigMovePanel وسنضيف غليه معالجة تفعيل زر سجل جديد حسب الحالة ، حيث أن زر GoNew يجب أن يكون غير متاح إذا كان السجل الحالي سجل جديد وكانت حقل الاسم فارغاً وسيصبح الإجراء بعد التعديل كما يلي:
كود:

Procedure ConfigMovePanel;
Begin
With Form1 Do
Begin
If IsNewRec then
Panel1.Caption := 'سجل جديد من '+ IntToStr(RecordCount)
Else
Panel1.Caption := IntToStr(CurrentRec) + ' من ' + IntToStr(RecordCount);
GoFirst.Enabled := (CurrentRec > 1);
GoPrevious.Enabled := GoFirst.Enabled ;
GoNext.Enabled := (CurrentRec < RecordCount);
GoLast.Enabled := GoNext.Enabled;
GoNew.Enabled := (Not IsNewRec) Or (Edit1.Text > ');
End;
End;

[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

>> حدث الضغط على زر الانتقال للسجل الأول :

كود:

procedure TForm1.GoFirstClick(Sender: TObject);
begin
If IsNewRec then
Begin
CurrPoint := NewPhoneCard(CurrPoint);
LastPoint := CurrPoint;
End;
SaveToCard (CurrPoint);
CurrPoint:= FirstPoint;
GetFromCard (CurrPoint);
CurrentRec := 1;
IsNewRec := False;
ConfigMovePanel;
end;

[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

>> حدث الضغط على زر الانتقال للسجل السابق :

كود:

procedure TForm1.GoPreviousClick(Sender: TObject);
begin
If IsNewRec then
Begin
CurrPoint := NewPhoneCard(CurrPoint);
LastPoint := CurrPoint;
End;
SaveToCard (CurrPoint);
CurrPoint:= CurrPoint^.Prev ;
GetFromCard (CurrPoint);
Dec(CurrentRec);
IsNewRec := False;
ConfigMovePanel;
end;

[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

>> حدث الضغط على زر الانتقال للسجل التالي :

كود:

procedure TForm1.GoNextClick(Sender: TObject);
begin
SaveToCard (CurrPoint);
CurrPoint:= CurrPoint^.Next ;
GetFromCard (CurrPoint);
Inc(CurrentRec);
ConfigMovePanel;
end;

[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

>> حدث الضغط على زر الانتقال للسجل الأخير :

كود:

procedure TForm1.GoLastClick(Sender: TObject);
begin
SaveToCard (CurrPoint);
CurrPoint:= LastPoint ;
GetFromCard (CurrPoint);
CurrentRec := RecordCount;
ConfigMovePanel;
end;

[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

>> حدث الضغط على زر سجل جديد :

كود:

procedure TForm1.GoNewClick(Sender: TObject);
begin
If IsNewRec then
Begin
CurrPoint := NewPhoneCard(CurrPoint);
LastPoint := CurrPoint;
End;
SaveToCard(CurrPoint);
IsNewRec := True;
EmptyFields;
Inc(RecordCount);
CurrentRec := RecordCount;
ConfigMovePanel;
end;

[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

>> أما الحالة التي يجب أن يبدأ بها البرنامج فيتم تحديدها من خلال حدث FormCreate كما يلي :

كود:

procedure TForm1.FormCreate(Sender: TObject);
begin
IsNewRec := true;
CurrentRec := 1;
RecordCount := 1;
ConfigMovePanel;
end;

نلاحظ في الإجراءات السابقة استخدامنا لتعليمة inc ووظيفتها زيادة قيمة المتحول الممرر وتعليمة Dec ووظيفتها انقاص قيمة المتحول الممرر
وأهم ما يجب الاستفادة منه في الإجراءات السابقة والانتباه له هو أسلوب بناء اللوائح المترابطة والتعامل مع المؤشرات
[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

>> حدث عند تغير النص في حقل الاسم نضع هذا الكود :

كود:

GoNew.Enabled := (Not IsNew) Or (Edit1.Text > ');

ووظيفة هذا الكود هي أن يفعّل زر سجل جديد عند إدخال نص في حقل الاسم في حالة سجل جديد

عند هذه النقطة نكون قد أنجزنا الجزء الأساسي من البرنامج وأصبح قابلاً للاختبار ..
[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

nagati 04-06-2008 02:20 PM

الدرس الخامس


المرحلة الثانية بالنسبة لبرنامجنا فإننا سنقوم بتخزين المعلومات وقراءتها من ملف نصي ..
من أجل التعامل مع الملفات النصية نتبع الخطوات التالية :

1- تعريف متحول من النوع TextFile

2- ربط هذا المتحول مع ملف بواسطة التعليمة AssignFile وفق الصيغة :
كود:
AssignFile (VarFile , FileName)

3- فتح الملف بإحدى الحالات التالية :

>> فتح الملف للقراءة منه : نستخدم تعليمة Reset بهذه الصيغة :
كود:
Reset(VarFile)


>> إنشاء ملف جديد : نستخدم تعليمة ReWrite بهذه الصيغة :
كود:
ReWrite(VarFile)


>> فتح الملف للإضافة إلى محتوياته : نستخدم تعليمة Append بهذه الصيغة :
كود:
Append(VarFile)

4- التعامل مع الملف بإحدى الحالات التالية:
>> كتابة سطر كامل : نستخدم تعليمة WriteLn بهذه الصيغة :
كود:
WriteLn(VarFile,String)


>> كتابة نص دون الانتقال للسطر التالي : نستخدم تعليمة Write بهذه الصيغة :
كود:
Write(VarFile,String)


>> قراءة سطر كامل : نستخدم تعليمة ReadLn بهذه الصيغة :
كود:
ReadLn(VarFile,String)


>> قراءة مجموعة أحرف : نستخدم تعليمة Read بهذه الصيغة :
كود:
Read(VarFile,String)


5- إغلاق الملف بعد الانتهاء من التعامل معه : بواسطة تعليمة CloseFile بهذه الصيغة :
كود:
CloseFile(VarFile)

[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

وبنفس الأسلوب السابق نحدد أولاً الإجراءات اللازمة للبرنامج :
- إجراء تخزين ترويسة الملف .
- دالة فصل متحول نص إلى جزئين حسب وجود محرف معين .
- دالة قراءة ترويسة الملف .
- إجراء تخزين بطاقة موجودة في PhoneCard في الملف المفتوح
-إجراء إسناد قيمة Nil للمؤشرات العامة المستخدمة في البرنامج
- إجراء قراءة بطاقة من الملف المفتوح وتخزينها في بطاقة بواسطة مؤشر إليها
- إجراء فتح ملف جديد من أجل التخزين به ثم إغلاقه
- إجراء تفريغ الذاكرة من جميع البطاقات المنشأة بها من النوع PhoneCard
- إجراء فتح ملف جديد من أجل القراءة منه ثم إغلاقه
[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

1- إجراء تخزين ترويسة الملف : إن لكل ملف رأس Header يميز نوع هذا الملف ويحتوي معلومات عنه . وبالنسبة للملفات الناتجة عن برنامجنا سنعمل لها Header خاص .
أولاً يبدأ الـ Header بمميز يميز نوع الملف وهو عبارة عن نص معين أو مجموعة أحرف وسنجعل هذا المميز في برنامجنا عبارة : "Phone guide 4 Arab Moheet"
ثم سنخزن رقم النسخة Version للبرنامج وستكون "Ver 1"
ثم سنخزن عدد البطاقات في الدليل ..
وسينفصل بين كل معلومة والمعلومة التي تليها برمز خاص .. أقترح أن يكون المحرف ذو الرقم صفر .
وسنمرر للإجراء متحول من نمط مؤشر إلى نوع TextFile لكي يتمكن الإجراء من التخزين في الملف .. لهذا نعرف هذا النمط في Type للوحدة Unit1 وسنسميه PTF بحيث يصبح كود Type كما يلي :
كود:
type
PhonePointer = ^PhoneCard;
phoneCard = Record
FName,LName,Address : string;
HomeNo,JobNo,FaxNo,Mobile : string;
Email , Page, Rem : string;
Next,Prev : PhonePointer;
End;
PTF = ^TextFile;
.
.


وهكذا سيكون هذا الإجراء :
كود:
Procedure SaveHeader(PF : PTF);
Var
Hdr : String;
Begin
Hdr := 'Phone guide 4 Arab Moheet' + char(0)
+ 'Ver 1' + Char(0) + IntToStr(RecordCount);
WriteLn(Pf^,HDR);
End;

[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

2- دالة فصل متحول نص إلى جزئين حسب وجود محرف معين : و سيتم استدعاؤها من باقي الإجراءات .
ستقوم هذه الدالة بالبحث عن محرف معين ضمن متحول من نوع نص ثم تفصل هذا النص إلى جزئين قبل وبعد هذا المحرف .. وواضح أننا نحتاج إلى متحول من نمط خاص يتألف من سجلين للتعامل مع هذه الدالة .. سنسمي هذا النمط الجديد : TowString وتعريفه مع الأنماط الأخرى في Type هكذا :
كود:
TowString = Record
Left,Right : String;
End;


يتم تحديد مكان وجود محرف معين ضمن سلسلة محارف من خلال الدالة Pos وهذه صيغتها :
كود:
Pos(Substring ; String)


ويتم نسخ جزء من سلسة محارف باستخدام دالة Copy وهذه صيغتها :
كود:
Copy(String; Start; Length)

كما يتم معرفة طول سلسة محارف من خلال دالة Length ..

بالاعتماد على ما سبق يكون كود الدالة هذه كما يلي :
كود:
Function GetTowString( S : String ; C : char):TowString;
Var
RSLT : TowString;
P : integer;
Begin
P := pos(C,S);
If P = 0 then P:=length(s)+1;
Rslt.left := Copy(S,1,P-1);
Rslt.Right := Copy(s,p+1,length(s)-P);
GetTowString:= Rslt;
End;

وكما نلاحظ أن تصميم الدالة راعى تقسيم النص عند وجود محرف يتم تمريره للدالة .. وليس المحرف صفر وهذا من أجل جعل هذه الدالة ذات مرونة أكبر لاستخدامها في برامج أخرى ..
[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

3- دالة قراءة ترويسة الملف : تعود بقيمة True إذا كان نوع الملف صحيح .. و False إذا كان غير ذلك
سنقوم أولاً بالتأكد من مميز الملف
ثم التأكد من رقم النسخة (يمكن مستقبلاً أن يتم تطوير البرنامج وعمل نسخ أحدث تكون غير متوافقة مع بيانات هذه النسخة)
ثم قراءة عدد السجلات وضبط المتحول RecordCount على أساسها.
وفي حال كانت الترويسة غير مقبولة سيتم إظهار رسالة خطأ توضح ذلك .
سيتم تقسيم الـ Header إلى أجزاءه الثلاثة من خلال دالة GetTowString
وهذت هو الكود :
كود:
Function ReadHeaderOk (PF : PTF):Boolean;
Var
Hdr : String;
TS : TowString;
Rslt : Boolean;
Begin
ReadLn(Pf^,Hdr);
TS := GetTowString(Hdr,char(0));
Rslt := False;
If Ts.Left = 'Phone guide 4 Arab Moheet' then
Begin
Ts := GetTowString(Ts.Left,char(0));
If Ts.Left = 'Ver 1' then
Begin
RecordCount := StrToInt(Ts.Right);
Rslt := True ;
End;
End;
If Not Rslt then
MessageBox(application.Handle,'هذا الملف ليس ملف دليل هاتف صالح', 'خطأ عند فتح الملف',MB_OK + MB_ICONWARNING + MB_APPLMODAL + MB_RTLReading);
ReadHeaderOk := Rslt ;
End;

[عزيزي الزائر يتوجب عليك التسجيل لمشاهدة الروابط .. للتسجيل فضلاً اضغط هنا]

4- إجراء تخزين بطاقة موجودة في PhoneCard في الملف المفتوح :
سيتم تخزين كل المعلومات لبطاقة واحدة بشكل متتالي على سطر واحد بحيث يفصل بين كل بيان وآخر رمز char(0)
كود:
Procedure SaveCardToFile(PF : PTF ; Card : PhonePointer);
Var STF : String ;
Const X = char(0);
Begin
With card^ Do
Stf := FName + X + LName + X + Address + X + HomeNo + X + JobNo +
X + FaxNo + X + Mobile + X + Email + X + Page + X + Rem ;
WriteLn(Pf^,Stf);
If Card <> LastPoint then
SaveCardToFile(PF,Card.Next);
End;


نلاحظ في الإجراء السابق تقنية مهمة جداً في البرمجة ألا وهي الإجراء التعاودي الذي يعيد استدعاء نفسه من ضمن كوده ... والإجراء السابق يفعل هذا إذا أنه في آخر سطرين يقوم بالتأكد إذا كانت البطاقة التي سجلها ليست آخر بطاقة فيقوم باستدعاء نفسه مرة جديدة مع البطاقة التالية .. ولذلك فإن استدعاء هذا الإجراء مع البطاقة الأولى من شأنه تخزين جميع البطاقات في الملف .

منقول الافادة

daliaradwan 01-23-2014 08:15 AM

شكرا جدا لمجهودك

mmohamed 12-13-2014 09:58 AM

lمشكوووووووووووووووووور على امجهود ارائع

فؤاد 28 12-28-2014 04:19 PM

لبابلا
 
لبالبابلابلا:SugarwareZ-093:

deaa1981 01-19-2018 07:06 PM

مشكوووووووووووووووووور احي


الساعة الآن 07:41 AM.

Powered by Alwaha® Version
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.

Adsense Management by Losha

new notificatio by 9adq_ala7sas
alwahatech.net