منتدى Borland Delphi

 اسم العضو:مهند عبادي  الاثنين,13/محرم/1426 هـ,09:23 مساءً
[ALIGN=center][IMG]http://www.arabmoheet.net/forum/pics/bsmla.gif[/IMG][/ALIGN] [COLOR=white]
الأخوة الأكارم ..
[/COLOR]
هذا شرح خطوة بخطوة لتصميم برنامج هاتف بسيط بواسطة دلفي المطلوب من أجل الاستفادة من الدورة الالمام بأساسيات الدلفي وسيتم شرح كل خطوة بخطوتها نظرياً ثم عملياً مع الدعم بالصور والمرفقات اللازمة .. أرجو المتابعة والتفاعل ..
مع تحياتي  

 اسم العضو:مهند عبادي  الاثنين,13/محرم/1426 هـ,09:55 مساءً
[ALIGN=center][COLOR=red][SIZE=5]الدرس الأول[/COLOR][/SIZE][/ALIGN] سنبدأ بتحليل ما نريده من البرنامج وأبعاده البرنامج هو برنامج بسيط جداً عبارة على دليل هاتف بسيط ، يتم تخزين الاسم [COLOR=green]-[/COLOR] الكنية [COLOR=green]-[/COLOR] العنوان [COLOR=green]-[/COLOR] هاتف المنزل [COLOR=green]-[/COLOR] هاتف العمل [COLOR=green]-[/COLOR] الفاكس [COLOR=green]-[/COLOR] المحمول [COLOR=green]-[/COLOR] البريد الالكتروني [COLOR=green]-[/COLOR] الموقع [COLOR=green]-[/COLOR] ملاحظات لن نعتمد على قواعد البيانات بل سنتعامل مع ملف نصي عادي المطلوب من البرنامج : حفظ واستعراض الأسماء [COLOR=green]-[/COLOR] البحث وفق أي حقل إذاً .. دعونا نبدأ بالعمل : نشغل برنامج دلفي وسيكون أمامنا الآن مشروع جديد به فورم فارغ طبعاً سننجز القسم الأول من البرنامج [COLOR=green]([/COLOR] تصميم الشكل[COLOR=green])[/COLOR] : بعد وضع كلفة الحقول .. نستخدم زر [COLOR=blue]BitBtn [/COLOR]من مجموعة [COLOR=blue]Additional .. [/COLOR]نضعه ثم نعين خاصية [COLOR=blue]Kind [/COLOR]تساوي [COLOR=blue]bkClose[/COLOR] ثم نغير الـ [COLOR=blue]Caption [/COLOR]إلى إغلاق [COLOR=green]([/COLOR]هذا الزر سيقوم الآن بإغلاق الفورم فوراً دون الحاجة إلى كنابة كود الإغلاق[COLOR=green])[/COLOR] سيبدو الفورم كما يلي بعد الانتهاء من تصميم الشكل : [ALIGN=center][IMG]http://www.arabmoheet.net/forum/Members_Upload_Pics/15/Tel_1.gif[/IMG][/ALIGN] وهذا هو الملف مرفق 

 اسم العضو:مهند عبادي  الثلاثاء,14/محرم/1426 هـ,11:12 مساءً
[ALIGN=center][COLOR=red][SIZE=5]الدرس الثاني[/COLOR][/SIZE][/ALIGN] الآن كما نشاهد أن كل بطاقة في دليل الهاتف تتألف من عدد من الحقول .. والمفروض من أجل سهولة العمل أن نقوم بتعريف نمط جديد [COLOR=blue]Type [/COLOR]خاص بالبطاقات تعريف الأنماط الخاصة بالبرنامج : [COLOR=sienna]1[/COLOR][COLOR=darkred]-[/COLOR] يتم وضع تعريف الأنماط الخاصة بالبرنامج ضمن تعريفات كلمة [COLOR=blue]Type [/COLOR]الموجودة في أعلى [COLOR=blue]Unit1 [/COLOR] [COLOR=sienna]2[/COLOR][COLOR=darkred]-[/COLOR] يأخذ تعريف نمط جديد مؤلف من عدة سجلات هذه الصيغة : كود:

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

[COLOR=sienna]3[/COLOR][COLOR=darkred]-[/COLOR] بالنسبة لحالتنا سنسمي النمط الجديد [COLOR=blue]PhoneCard [/COLOR]وسيتم تعريفه كما يلي : كود:

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

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

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;

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

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;

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

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

 

 اسم العضو:مهند عبادي  الأربعاء,15/محرم/1426 هـ,11:04 مساءً
[ALIGN=center][SIZE=5][COLOR=red]الدرس الثالث[/COLOR][/SIZE][/ALIGN] من أجل التعامل مع البرنامج كقاعدة بيانات فإنه يلزمنا أزرار التنقل بين السجلات التي هي : سجل جديد ، السجل الأول ، السجل السابق ، السجل التالي ، السجل الأخير بالإضافة إلى [COLOR=blue]Panel [/COLOR]نستخدمها لعرض رقم السجل الحالي بحيث يصبح شكل النموذج كما يلي : [ALIGN=center][IMG]http://www.arabmoheet.net/forum/Members_Upload_Pics/15/Tel_2.gif[/IMG][/ALIGN] وسنسمي الأزرار على التوالي : [COLOR=blue]GoNew - GoPrevious - GoNext - GoLast [/COLOR] ولعرض تعليقات [COLOR=blue]Hints [/COLOR]للأزرار نكتب في خاصية [COLOR=blue]Hint [/COLOR]لكل زر شرح عنه .. ثم نجعل خاصية [COLOR=blue]ShowHint [/COLOR]تساوي [COLOR=blue]True [/COLOR]

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

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

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;

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

var Form1: TForm1; Function NewPhoneCard(var PLastCard : PhonePointer):PhonePointer; implementation

[COLOR=sienna]2[/COLOR][COLOR=darkred]-[/COLOR] إجراء تخزين القيم الموجودة في الفورم ضمن عنصر من النمط [COLOR=blue]phoneCard[/COLOR] كود:

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;

[COLOR=sienna]3[/COLOR][COLOR=darkred]-[/COLOR] إجراء عرض عنصر[COLOR=blue]phoneCard [/COLOR]في الفورم : كود:

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;

[COLOR=sienna]4[/COLOR][COLOR=darkred]-[/COLOR] إجراء تفريغ الحقول في الفورم : كود:

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;

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

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

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

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;

 

 اسم العضو:أبو ربيع  الخميس,16/محرم/1426 هـ,05:37 صباحاً
السلام عليكم شو هذا استاذ مهند أي حيرتنا مره أكسس ومره فيجول بيسك ومره دوت واليوم دلفي، ما شاءلله عليك مخك لامم كل لغات البرمجة أنا خايف أحسدك بس والله ما شاءلله عليكم وربنا يقويك ، وياريت تكمل الدورة وإن شاءلله من اليوم سوف أكون من المتابعين لها. 

 اسم العضو:lord369  الخميس,16/محرم/1426 هـ,07:01 صباحاً
السلام عليكم ورحمة الله وبركاته شكرا يا أخى على المجهو الوافر المبذول والى الامام دائما بأذن الله 

 اسم العضو:محمد ربيع  الخميس,16/محرم/1426 هـ,02:46 مساءً
وفقك الله وجزاك الخير 

 اسم العضو:أبو ديب  الخميس,16/محرم/1426 هـ,03:17 مساءً
ألف شكر لك أستاذنا القدير مهند عبادي وعندي سؤال لو سمحت .. لماذا لا نستخدم المصفوفات بدل اللوائح المترابطة خاصة وأنها أسهل بالاستخدام ؟؟ 

 اسم العضو:مهند عبادي  الخميس,16/محرم/1426 هـ,05:17 مساءً
[COLOR=DarkBlue]
الأخوة : أبو ربيع - lord369 - محمد ربيع - أبو ديب ..
[/COLOR] شكراً لمساهمتكم ومروركم على الموضوع

[COLOR=DarkBlue]
الأخ أبو ديب ..
[/COLOR] بالنسبة لعدم استعمال المصفوفات بدلاً عن اللوائح المترابطة فهذا لأن اللوائح المترابطة أكثر تلبية لاحتياجات البرنامج من حيث عدم محدودية عددها بعدد معين كما أنني قصدت من هذا المثال تعريف المتابعين للمؤشرات وأسلوب التعامل مع اللوائح المترابطة (وهي تقنية القليل فقط من يجيدها).. تحياتي لك 

 اسم العضو:مهند عبادي  الخميس,16/محرم/1426 هـ,11:41 مساءً
[ALIGN=center][COLOR=red][SIZE=5]الدرس الرابع[/COLOR][/SIZE][/ALIGN] الآن يجب أن نستخدم الإجراءات التي سبق لنا تصميمها : عند عملية الانتقال بالأزرار يجب تخزين محتويات المعلومات الظاهرة على الشاشة في السجل في الذاكرة .. و إذا كان سجل جديد يجب قبلها أن يتم إضافة عنصر جديد من النوع [COLOR=blue]phoneCard ... [/COLOR]وبعد ذلك يجب اجراء عملية الانتقال ثم استدعاء إجراء [COLOR=blue]ConfigMovePanel .. [/COLOR]لذلك يجب تعريف متحول عام على مستوى الـ [COLOR=blue]Unit [/COLOR]من النوع [COLOR=blue]Boolean [/COLOR]سنسميه [COLOR=blue]IsNewRec [/COLOR] كما سيلزم لنا تحديد السجل الأول والسجل الأخير والسجل الحالي لذلك سنقوم بتعريف [COLOR=sienna]3[/COLOR] متحولات عامة من النوع [COLOR=blue]PhonePointer [/COLOR]سنسميها : [COLOR=blue]FirstPoint , CurrPoint , LastPoint .[/COLOR] بحيث تصبح التعريفات العامة لمتحولات الوحدة [COLOR=blue]Unit1 [/COLOR]هكذا : كود:

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

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

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;

[COLOR=teal]>>[/COLOR] حدث الضغط على زر الانتقال للسجل الأول : كود:

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;

[COLOR=teal]>>[/COLOR] حدث الضغط على زر الانتقال للسجل السابق : كود:

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;

[COLOR=teal]>>[/COLOR] حدث الضغط على زر الانتقال للسجل التالي : كود:

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

[COLOR=teal]>>[/COLOR] حدث الضغط على زر الانتقال للسجل الأخير : كود:

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

[COLOR=teal]>>[/COLOR] حدث الضغط على زر سجل جديد : كود:

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;

[COLOR=teal]>>[/COLOR] أما الحالة التي يجب أن يبدأ بها البرنامج فيتم تحديدها من خلال حدث [COLOR=blue]FormCreate [/COLOR]كما يلي : كود:

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

نلاحظ في الإجراءات السابقة استخدامنا لتعليمة [COLOR=blue]inc [/COLOR]ووظيفتها زيادة قيمة المتحول الممرر وتعليمة [COLOR=blue]Dec [/COLOR]ووظيفتها انقاص قيمة المتحول الممرر وأهم ما يجب الاستفادة منه في الإجراءات السابقة والانتباه له هو أسلوب بناء اللوائح المترابطة والتعامل مع المؤشرات

[COLOR=teal]>>[/COLOR] حدث عند تغير النص في حقل الاسم نضع هذا الكود : كود:

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

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

 

 اسم العضو:مهند عبادي  السبت,18/محرم/1426 هـ,12:04 صباحاً
[ALIGN=center][COLOR=red][SIZE=5]الدرس الخامس[/COLOR][/SIZE][/ALIGN] المرحلة الثانية بالنسبة لبرنامجنا فإننا سنقوم بتخزين المعلومات وقراءتها من ملف نصي .. من أجل التعامل مع الملفات النصية نتبع الخطوات التالية : [COLOR=sienna]1[/COLOR][COLOR=green]-[/COLOR] تعريف متحول من النوع [COLOR=blue]TextFile[/COLOR] [COLOR=sienna]2[/COLOR][COLOR=green]-[/COLOR] ربط هذا المتحول مع ملف بواسطة التعليمة [COLOR=blue]AssignFile [/COLOR]وفق الصيغة : كود:

AssignFile (VarFile , FileName)

[COLOR=sienna]3[/COLOR][COLOR=green]-[/COLOR] فتح الملف بإحدى الحالات التالية : [COLOR=teal]>>[/COLOR] فتح الملف للقراءة منه : نستخدم تعليمة [COLOR=blue]Reset [/COLOR]بهذه الصيغة : كود:

Reset(VarFile)

[COLOR=teal]>>[/COLOR] إنشاء ملف جديد : نستخدم تعليمة [COLOR=blue]ReWrite [/COLOR]بهذه الصيغة : كود:

ReWrite(VarFile)

[COLOR=teal]>>[/COLOR] فتح الملف للإضافة إلى محتوياته : نستخدم تعليمة [COLOR=blue]Append [/COLOR]بهذه الصيغة : كود:

Append(VarFile)

[COLOR=sienna]4[/COLOR][COLOR=green]-[/COLOR] التعامل مع الملف بإحدى الحالات التالية: [COLOR=teal]>>[/COLOR] كتابة سطر كامل : نستخدم تعليمة [COLOR=blue]WriteLn [/COLOR]بهذه الصيغة : كود:

WriteLn(VarFile,String)

[COLOR=teal]>>[/COLOR] كتابة نص دون الانتقال للسطر التالي : نستخدم تعليمة [COLOR=blue]Write [/COLOR]بهذه الصيغة : كود:

Write(VarFile,String)

[COLOR=teal]>>[/COLOR] قراءة سطر كامل : نستخدم تعليمة [COLOR=blue]ReadLn [/COLOR]بهذه الصيغة : كود:

ReadLn(VarFile,String)

[COLOR=teal]>>[/COLOR] قراءة مجموعة أحرف : نستخدم تعليمة [COLOR=blue]Read [/COLOR]بهذه الصيغة : كود:

Read(VarFile,String)

[COLOR=sienna]5[/COLOR][COLOR=green]-[/COLOR] إغلاق الملف بعد الانتهاء من التعامل معه : بواسطة تعليمة [COLOR=blue]CloseFile [/COLOR]بهذه الصيغة : كود:

CloseFile(VarFile)

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

[COLOR=sienna]1[/COLOR][COLOR=green]-[/COLOR] إجراء تخزين ترويسة الملف : إن لكل ملف رأس [COLOR=blue]Header [/COLOR]يميز نوع هذا الملف ويحتوي معلومات عنه . وبالنسبة للملفات الناتجة عن برنامجنا سنعمل لها [COLOR=blue]Header [/COLOR]خاص . أولاً يبدأ الـ [COLOR=blue]Header [/COLOR]بمميز يميز نوع الملف وهو عبارة عن نص معين أو مجموعة أحرف وسنجعل هذا المميز في برنامجنا عبارة : [COLOR=purple]"Phone guide 4 Arab Moheet"[/COLOR] ثم سنخزن رقم النسخة [COLOR=blue]Version [/COLOR]للبرنامج وستكون [COLOR=purple]"Ver 1"[/COLOR] ثم سنخزن عدد البطاقات في الدليل .. وسينفصل بين كل معلومة والمعلومة التي تليها برمز خاص .. أقترح أن يكون المحرف ذو الرقم صفر . وسنمرر للإجراء متحول من نمط مؤشر إلى نوع [COLOR=blue]TextFile [/COLOR]لكي يتمكن الإجراء من التخزين في الملف .. لهذا نعرف هذا النمط في [COLOR=blue]Type [/COLOR]للوحدة [COLOR=blue]Unit1 [/COLOR]وسنسميه [COLOR=blue]PTF [/COLOR]بحيث يصبح كود [COLOR=blue]Type [/COLOR]كما يلي : كود:

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;

[COLOR=sienna]2[/COLOR][COLOR=green]-[/COLOR] دالة فصل متحول نص إلى جزئين حسب وجود محرف معين : و سيتم استدعاؤها من باقي الإجراءات . ستقوم هذه الدالة بالبحث عن محرف معين ضمن متحول من نوع نص ثم تفصل هذا النص إلى جزئين قبل وبعد هذا المحرف .. وواضح أننا نحتاج إلى متحول من نمط خاص يتألف من سجلين للتعامل مع هذه الدالة .. سنسمي هذا النمط الجديد : [COLOR=blue]TowString [/COLOR]وتعريفه مع الأنماط الأخرى في [COLOR=blue]Type [/COLOR]هكذا : كود:

TowString = Record Left,Right : String; End;

يتم تحديد مكان وجود محرف معين ضمن سلسلة محارف من خلال الدالة [COLOR=blue]Pos [/COLOR]وهذه صيغتها : كود:

Pos(Substring ; String)

ويتم نسخ جزء من سلسة محارف باستخدام دالة [COLOR=blue]Copy [/COLOR]وهذه صيغتها : كود:

Copy(String; Start; Length)

كما يتم معرفة طول سلسة محارف من خلال دالة [COLOR=blue]Length ..[/COLOR] بالاعتماد على ما سبق يكون كود الدالة هذه كما يلي : كود:

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;

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

[COLOR=sienna]3[/COLOR][COLOR=green]-[/COLOR] دالة قراءة ترويسة الملف : تعود بقيمة [COLOR=blue]True [/COLOR]إذا كان نوع الملف صحيح .. و [COLOR=blue]False [/COLOR]إذا كان غير ذلك سنقوم أولاً بالتأكد من مميز الملف ثم التأكد من رقم النسخة [COLOR=green]([/COLOR]يمكن مستقبلاً أن يتم تطوير البرنامج وعمل نسخ أحدث تكون غير متوافقة مع بيانات هذه النسخة[COLOR=green])[/COLOR] ثم قراءة عدد السجلات وضبط المتحول [COLOR=blue]RecordCount [/COLOR]على أساسها. وفي حال كانت الترويسة غير مقبولة سيتم إظهار رسالة خطأ توضح ذلك . سيتم تقسيم الـ [COLOR=blue]Header [/COLOR]إلى أجزاءه الثلاثة من خلال دالة [COLOR=blue]GetTowString[/COLOR] وهذت هو الكود : كود:

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;

[COLOR=sienna]4[/COLOR][COLOR=green]-[/COLOR] إجراء تخزين بطاقة موجودة في [COLOR=blue]PhoneCard [/COLOR]في الملف المفتوح : سيتم تخزين كل المعلومات لبطاقة واحدة بشكل متتالي على سطر واحد بحيث يفصل بين كل بيان وآخر رمز [COLOR=blue]char(0) [/COLOR] كود:

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;

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

 اسم العضو:مهند عبادي  السبت,18/محرم/1426 هـ,12:30 صباحاً
[ALIGN=center][COLOR=red][SIZE=5]الدرس السادس[/COLOR][/SIZE][/ALIGN] [COLOR=sienna]5[/COLOR] [COLOR=green]-[/COLOR] إجراء إسناد قيمة Nil للمؤشرات العامة المستخدمة في البرنامج : كود:

Procedure SetNilPointers ; Begin FirstPoint := Nil; LastPoint := Nil; CurrPoint := Nil; End;

[COLOR=sienna]6[/COLOR] [COLOR=green]-[/COLOR] إجراء قراءة بطاقة من الملف المفتوح وتخزينها في بطاقة بواسطة مؤشر إليها : كود:

Procedure GetCardFromFile(PF : PTF ; Rval : PhonePointer); Var Gff : String ; TS : TowString; Const X = char(0); Begin ReadLn(Pf^ , Gff); With Rval^ Do Begin Ts := GetTowString(Gff,X); FName := Ts.Left ; Ts := GetTowString(Ts.Right ,X); LName := Ts.Left ; Ts := GetTowString(Ts.Right ,X); Address := Ts.Left ; Ts := GetTowString(Ts.Right ,X); HomeNo := Ts.Left ; Ts := GetTowString(Ts.Right ,X); JobNo := Ts.Left ; Ts := GetTowString(Ts.Right ,X); FaxNo := Ts.Left ; Ts := GetTowString(Ts.Right ,X); Mobile := Ts.Left ; Ts := GetTowString(Ts.Right ,X); Email := Ts.Left ; Ts := GetTowString(Ts.Right ,X); Page := Ts.Left ; Rem := Ts.Right ; End; End;

[COLOR=sienna]7[/COLOR][COLOR=green]-[/COLOR] إجراء فتح ملف جديد من أجل التخزين به ثم إغلاقه : هذا الإجراء سيأخذ اسم الملف ثم سيقوم بإنشائه وتخزين الـ [COLOR=blue]Header [/COLOR]له ثم تخزين جميع البطاقات في الملف ثم إغلاق الملف وفي البداية سيتم التأكد من أن اسم الملف ينتهي بالامتداد الذي سنعتمده لبرنامجنا ألا وهو .[COLOR=blue]AMPG [/COLOR]اختصاراً لـ [COLOR=blue]Arab Moheet Phone Gouid .. [/COLOR]هذا إذا لم يكن لاسم الملف أي امتداد : كود:

Procedure SaveAllToFile(FN : String); Var F : textFile; PF : PTF; Begin If GetTowString(Fn,'.').Right = ' then Fn := Fn + '.ampg'; AssignFile(F,FN); ReWrite (F); PF := @F; SaveHeader (Pf); SaveCardToFile(Pf,FirstPoint); CloseFile(F); End;

نلاحظ استدعاء إجراء [COLOR=blue]SaveCardToFile [/COLOR]مرة واحدة فقط مع أول بطاقة .. وهذا يكفي لتخزين كافة البطاقات لأن هذا الإجراء إجراء تعاودي كما سبقت الإشارة إلى ذلك ..

[COLOR=sienna]8[/COLOR][COLOR=green]-[/COLOR] إجراء تفريغ الذاكرة من جميع البطاقات المنشأة بها من النوع [COLOR=blue]PhoneCard :[/COLOR] نستعمل لتحرير الذاكرة من متحول منشأ بتعليمة [COLOR=blue]NEW [/COLOR]تعليمة [COLOR=blue]DisPose .. [/COLOR]وهذا هو الإجراء : كود:

Procedure DeleteCards(PCard : PhonePointer); Begin If lastPoint <> nil then Begin If Pcard <> LastPoint then DeleteCards(pcard^.Next) DisPose(Pcard); End; End;

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

[COLOR=sienna]9[/COLOR] [COLOR=green]-[/COLOR] إجراء فتح ملف جديد من أجل القراءة منه ثم إغلاقه : يتم في هذا الإجراء التاكد من رأس الملف [COLOR=blue]Header [/COLOR]ثم قراءة السجلات جميعها وضعها في عناصر لائحة مترابطة .. ثم عرض السجل الأول على الشاشة كود:

Procedure OpenAMPGFile(FN:String); Var F : TextFile; Pf : PTF; R : LongInt; Begin AssignFile(F,FN); Reset(F); Pf := @F; If ReadHeaderOk(Pf) then Begin DeleteCards(firstPoint); SetNilPointers; For R := 1 to RecordCount Do Begin CurrPoint := NewPhoneCard(CurrPoint); GetCardFromFile(pf,CurrPoint); End; LastPoint := CurrPoint; CurrentRec:=1; CurrPoint := FirstPoint; GetFromCard (CurrPoint); IsNewRec := False; ConfigMovePanel; End; CloseFile(F);

 

 اسم العضو:مهند عبادي  السبت,18/محرم/1426 هـ,03:33 مساءً
[ALIGN=center][COLOR=red][SIZE=5]الدرس السابع[/COLOR][/SIZE][/ALIGN] الآن لنقم بإكمال البرنامج وذلك بعمل واجهات [COLOR=darkred]([/COLOR]طرائق[COLOR=darkred])[/COLOR] للاستفادة من الإجراءات والدوال التي قمنا بتصميمها .. الاقتراح هو أن تكون هذه الواجهات عبارة عن قائمة [COLOR=blue]MainMenu .. [/COLOR]ولعمل ذلك نقوم بإدراح أداة [COLOR=blue]MainMenu [/COLOR]الموجودة في مجموعة أدوات [COLOR=blue]Standerd [/COLOR]وهي ثاني أداة من جهة اليسار ندرجها ضمن الفورم .. ثم نضغط ضغط مزدوج فوقها فتح المحرر الخاص بها حيث سنحرر القائمة التي نريدها القائمة التي سنحتاجها أولاً هي قائمة ملف وتحتوي على الخيارات : جديد [COLOR=darkred]-[/COLOR] فاصل [COLOR=darkred]-[/COLOR] فتح [COLOR=darkred]-[/COLOR] حفظ [COLOR=darkred]-[/COLOR] حفظ باسم [COLOR=darkred]-[/COLOR] فاصل [COLOR=darkred]-[/COLOR] إنهاء وقائمة سجلات وتحتوي على نفس خيارات الأزرار : سجل جديد [COLOR=darkred]-[/COLOR] فاصل [COLOR=darkred]-[/COLOR] السجل الأول [COLOR=darkred]-[/COLOR] السجل السابق [COLOR=darkred]-[/COLOR] السجل التالي [COLOR=darkred]-[/COLOR] السجل الأخير . وقائمة تعليمات تحتوي على : حول البرنامج . عمل خط فاصل ضمن الخيارات نجعل قيمة الـ [COLOR=blue]Caption [/COLOR]للقائمة هي إشارة [COLOR=darkred]-[/COLOR] وعند الانتهاء من تحرير هذه القوائم نقوم بإغلاق محرر الأداة [COLOR=blue]MaunMenu [/COLOR]لنجد أن القائمة أضيفت في الأعلى وأن حجم الفورم ازداد بسببها مما يوجب علينا أن نزيد طوله قليلاً حتى تظهر كل العناصر ضمنه .. ولكن القائمة موجودة من اليسار لليمين .. فكيف نجعلها من اليمين لليسار ؟؟ الحل هو أن نجعل اتجاه الفورم كله من اليمين لليسار بواسطة خاصية [COLOR=blue]BidoMode [/COLOR]نجعلها تساوي [COLOR=blue]bdRightToLeft .. [/COLOR] انتبه إلى أن اتجاه الأسهم الموجودة في أزرار التنقل ستنقلب للاتجاه الثاني بسبب هذه العملية .. لذلك نعيد كتابتها بالاأسهم بالاتجاه المقلوب .. وسنقوم بعمل الكود لكل خيار قائمة الآن : [COLOR=sienna]1[/COLOR][COLOR=darkred]-[/COLOR] قائمة حفظ باسم : لعمل حفظ لملف ما يجب في البداية أن نحدد اسم الملف المطلوب الحفظ به .. ويتم استدعاء صندوق حوار حفظ ملف من خلال الأداة [COLOR=blue]SaveDialog [/COLOR]من صفحة أدوات [COLOR=blue]Dialogs [/COLOR]كما في الصورة : [IMG]http://www.arabmoheet.net/forum/Members_Upload_Pics/15/Tel_3.gif[/IMG] ندرج أداة [COLOR=blue]SaveDialog [/COLOR]ضمن الفورم ثم نذهب إلى خاصية [COLOR=blue]Filter : [/COLOR]التي يتم من خلالها تعيين أنواع الملفات التي يدعمها صندوق الحوار [COLOR=darkred]([/COLOR]حفظ[COLOR=darkred])[/COLOR] وننقر نقراً مزدوجاً فيتم فتح مربع [COLOR=blue]Filter Editor .. [/COLOR]نعبئه كما في الصورة : [IMG]http://www.arabmoheet.net/forum/Members_Upload_Pics/15/Tel_4.gif[/IMG] الآن تكون أداة [COLOR=blue]SaveDialog1 [/COLOR]جاهزة للاستخدام يتم عرض أي مربع حوار من خلال الطريقة .[COLOR=blue]Execute [/COLOR]والتي تعيد قيمة [COLOR=blue]True [/COLOR]أو [COLOR=blue]False [/COLOR]للدلالة على أن المستخدم قد أغلق صندوق الحوار بالضغط على زر حفظ أو زر إلغاء الأمر .. كما يتم تخزين اسم الملف الذي تم اختياره ضمن خاصية [COLOR=blue]FileName [/COLOR]لهذه الأداة وهذا هو كود إجراء خيار القائمة حفظ باسم : كود:

begin If SaveDialog1.Execute then SaveAllToFile(SaveDialog1.FileName); end;

[COLOR=sienna]2[/COLOR][COLOR=darkred]-[/COLOR] قائمة حفظ : تختلف هذه القائمة عن القائمة السابقة في أنها تقوم بعمل حفظ دون السؤال عن اسم الملف .. إلا في حالة ملف جديد .. لذلك يلزمنا متحول يدلنا على أن الملف جديد أو لا .. ومن أجل هذه الغاية نقوم بتعريف متحول عام على مستوى الوحدة [COLOR=blue]Unit1 [/COLOR]من النوع [COLOR=blue]Boolean [/COLOR]سنسميه [COLOR=blue]IsNewFile [/COLOR]ومتحول عام آخر يحمل اسم الملف الحالي هو [COLOR=blue]CurrentFN [/COLOR]من النوع [COLOR=blue]String .[/COLOR] وسنضيف سطر يعين قيمته تساوي [COLOR=blue]True [/COLOR]عند حدث [COLOR=blue]FormCreate ..[/COLOR] وسنضيف سطر يعين قيمته تساوي [COLOR=blue]False [/COLOR]في إجراء [COLOR=blue]SaveAllToFile [/COLOR]بالإضافة إلى سطر تخزين اسم الملف الذي تم حفظه في المتحول [COLOR=blue]CurrentFN [/COLOR]و سطر عرض اسم الملف في شريط العنوان ، وفي إجراء [COLOR=blue]OpenAMPGFile [/COLOR]نفس الشيء.. بحيث يكون إجراء [COLOR=blue]SaveAllToFile [/COLOR]بهذا الشكل : كود:

Procedure SaveAllToFile(FN : String); Var F : textFile; PF : PTF; Begin If GetTowString(Fn,'.').Right = ' then Fn := Fn + '.ampg'; AssignFile(F,FN); ReWrite (F); PF := @F; SaveHeader (Pf); SaveCardToFile(Pf,FirstPoint); CloseFile(F); IsNewFile := False; CurrentFn:= FN ; Form1.Caption := Fn; End;

وإجراء [COLOR=blue]OpenAMPGFile [/COLOR]بهذا الشكل : كود:

Procedure OpenAMPGFile(FN:String); Var F : TextFile; Pf : PTF; R : LongInt; Begin AssignFile(F,FN); Reset(F); Pf := @F; If ReadHeaderOk(Pf) then Begin DeleteCards(firstPoint); For R := 1 to RecordCount Do Begin CurrPoint := NewPhoneCard(CurrPoint); GetCardFromFile(pf,CurrPoint); End; LastPoint := CurrPoint; CurrentRec:=1; CurrPoint := FirstPoint; GetFromCard (CurrPoint); IsNewRec := False; ConfigMovePanel; IsNewFile := False; CurrentFn:= FN ; Form1.Caption := Fn; End; CloseFile(F); End;

والآن سيكون كود قائمة حفظ هو : كود:

begin If Not IsNewFile Then SaveAllToFile(CurrentFN) Else N6Click(Sender); end;

نلاحظ في الكود استخدامنا لاستدعاء حدث النقر على قائمة حفظ باسم ..

[COLOR=sienna]3[/COLOR][COLOR=darkred]-[/COLOR] قائمة فتح : لعمل فتح لملف ما يجب في البداية أن نحدد الملف المطلوب فتحه .. ويتم استدعاء صندوق حوار فتح ملف من خلال الأداة [COLOR=blue]OpenDialog [/COLOR]من صفحة أدوات [COLOR=blue]Dialogs [/COLOR] ندرج أداة [COLOR=blue]OpenDialog [/COLOR]ضمن الفورم ثم نذهب إلى خاصية [COLOR=blue]Filter [/COLOR]ونعينها تماماً مثل ما عملنا لأداة [COLOR=blue]SaveDialog [/COLOR] الآن تكون أداة [COLOR=blue]OpenDialog1 [/COLOR]جاهزة للاستخدام وهذا هو كود إجراء خيار القائمة فتح : كود:

procedure TForm1.N4Click(Sender: TObject); begin If OpenDialog1.Execute Then OpenAMPGFile(OpenDialog1.FileName); end;

[COLOR=sienna]4[/COLOR][COLOR=darkred]-[/COLOR] قائمة جديد : كود:

procedure TForm1.N2Click(Sender: TObject); begin DeleteCards(FirstPoint); SetNilPointers; EmptyFields; IsNewRec := True; RecordCount := 1; CurrentRec := 1; Form1.Caption := 'ملف جديد'; ConfigMovePanel; end;

[COLOR=sienna]5[/COLOR][COLOR=darkred]-[/COLOR] قائمة إنهاء : نضع فيها فقط تعليمة [COLOR=blue]Close .. [/COLOR]ونحذف زر إغلاق من على الفورم إذ لا داعي لبقائه الآن

[COLOR=sienna]6[/COLOR][COLOR=darkred]-[/COLOR] قوائم سجلات: كل قائمة فيها نستدعي حدث عند الضغط على الزر من أزرار التنقل المقابلة لنفس الإجراء ..

[COLOR=sienna]7[/COLOR][COLOR=darkred]-[/COLOR] قائمة حول البرنامج : نصمم فورم ثاني بالشكل الذي يناسبنا .. ثم نستدعيه من خلال التعليمة : كود:

Form2.ShowModal;

ولكن لكي نستطيع استدعاء [COLOR=blue]Form2 [/COLOR]يجب أن يكون معروفاً في [COLOR=blue]Form1 [/COLOR]ويتم ذلك من خلال تعريفه ضمن [COLOR=blue]implementation [/COLOR]كما يلي : كود:

implementation uses Unit2;

الآن تستطيعون تجربة البرنامج وإعطائي أية ملاحظات لديكم عنه .. ولكن مهلاً لم ننتهي بعد .. ما زال هنالك إكمال للبرنامج .. 

 اسم العضو:eslol  السبت,18/محرم/1426 هـ,04:58 مساءً
جزاك الله خير استاذ مهند وفعلا اسلوب جديد باستخدام البوينتر ويعطيك العافية  

 اسم العضو:lord369  الأحد,19/محرم/1426 هـ,04:43 صباحاً
جزاك الله خير 

 اسم العضو:مهند عبادي  الاثنين,20/محرم/1426 هـ,09:07 مساءً
[ALIGN=center][SIZE=5][COLOR=red]الدرس الثامن[/COLOR][/SIZE][/ALIGN] استكمال البرنامج : إن برنامجنا قد وصل إلى درجة جيدة من الاكتمال لحد الآن .. إلا أنه لازال يعاني من بعض النواقص .. دعونا نحصيها حتى نعمل لها الحلول المناسبة . [COLOR=sienna]1[/COLOR][COLOR=green]-[/COLOR] إضافة زر حذف . [COLOR=sienna]2[/COLOR][COLOR=green]-[/COLOR] عند الضغط على خيار ملف جديد يجب السؤال عن الرغبة في حفظ البيانات في حال كونها غير محفوظة كذلك عند انهاء البرنامج وعند فتح ملف. [COLOR=sienna]3[/COLOR][COLOR=green]-[/COLOR] يجب أن تكون باقي قوائم سجلات غير متاحة إذا كانت الأزرار المقابلة لها غير متاحة .. [COLOR=sienna]4[/COLOR][COLOR=green]-[/COLOR] ظهور خطأ في حالة الرغبة بتخزين ملف جديد به أول سجل فقط [COLOR=sienna]5[/COLOR][COLOR=green]-[/COLOR] عدم تخزين التعديلات المجراة على السجل الحالي [COLOR=sienna]6[/COLOR][COLOR=green]-[/COLOR] عملية البحث وفق أحد الحقول [COLOR=sienna]7[/COLOR][COLOR=green]-[/COLOR] عرض قائمة بجميع الأسماء [COLOR=sienna]8[/COLOR][COLOR=green]-[/COLOR] تحسين الإظهارات

[COLOR=sienna]1[/COLOR][COLOR=green]-[/COLOR] إضافة زر حذف سجل : سنضيف زراً جديداً للنموذج .. بعنوان : 'حذف السجل الحالي' ونسميه [COLOR=blue]DelCurrRec ..[/COLOR] ودعونا نحلل ماذا سيحدث عند الضغط عليه : بالاستناد إلى أسلوب ارتباط البطاقات [COLOR=green]([/COLOR]اللوائح المترابطة[COLOR=green])[/COLOR] في الذاكرة .. فإن كل بطاقة لديها حقل [COLOR=blue]Next [/COLOR]وحقل [COLOR=blue]Perv [/COLOR]يحتويان على عناوين البطاقات التالية والسابقة ، لذلك المطلوب عند حذف سجل معين هو : [COLOR=teal]>>[/COLOR] ربط حقل [COLOR=blue]Next [/COLOR]في البطاقة السابقة بالبطاقة التالية إذا كان ليس السجل الأول [COLOR=teal]>>[/COLOR] ربط حقل [COLOR=blue]Prev [/COLOR]في البطاقة التالية بالبطاقة السابقة إذا كان ليس السجل الأخير [COLOR=teal]>>[/COLOR] تحرير عنوان الذاكرة للبطاقة الحالية [COLOR=teal]>>[/COLOR] إنقاص عدد السجلات الإجمالي [COLOR=teal]>>[/COLOR] تعيين السجل الحالي هو السجل الأخير والانتقال إليه وهذا هو الكود المنفذ لما سبق : كود:

procedure TForm1.DelCurrRecClick(Sender: TObject); begin If Currpoint = FirstPoint then FirstPoint := CurrPoint^.Next Else if Currpoint = LastPoint then LastPoint := CurrPoint^.prev Else Begin CurrPoint^.Prev^.Next :=CurrPoint^.Next ; CurrPoint^.Next^.Prev :=CurrPoint^.Prev ; End; DisPose(CurrPoint); Dec(RecordCount); CurrentRec := 1; If RecordCount = 0 Then Begin RecordCount := 1; SetNilPointers; IsNewRec := True; End; CurrPoint := LastPoint; If CurrPoint = Nil then EmptyFields else GetFromCard (CurrPoint); ConfigMovePanel; end;

كما أننا نحتاج إلى تعيين تفعيل[COLOR=green]/[/COLOR]عدم تفعيل الزر الجديد وذلك ضمن إجراء : [COLOR=blue]ConfigMovePanel [/COLOR]وذلك بإضافة هذا السطر ضمن كتلة [COLOR=blue]With Form1:[/COLOR] كود:

DelCurrRec.Enabled := Not IsNewRec;

أيضاً سنضيف قائمة فرعية ضمن القائمة سجلات هي حذف السجل الحالي ونبرمجها بنفس أسلوب باقي القوائم ..

[COLOR=sienna]2[/COLOR][COLOR=green]-[/COLOR] عند الضغط على خيار ملف جديد يجب السؤال عن الرغبة في حفظ البيانات في حال كونها غير محفوظة وكذلك الأمر عند إنهاء البرنامج . لمعرفة أن البيانات غير محفوظة أو أن تعديلاً جرى عليها فإنه يلزم لنا أن نستخدم متحولاً عاماً جديداً لهذه الغاية .. وسنسمي المتحول الجديد [COLOR=blue]IsSaved [/COLOR]من النوع [COLOR=blue]Boolean [/COLOR]وسيتم تعيين القيمة لهذا المتحول وفق ما يلي : [COLOR=teal]>>[/COLOR] في حدث [COLOR=blue]FormCreate [/COLOR]سيكون [COLOR=blue]True [/COLOR] [COLOR=teal]>>[/COLOR] عند ضغط أي زر في أي عنصر [COLOR=blue]Edit [/COLOR]سنجعل قيمته [COLOR=blue]False[/COLOR] [COLOR=teal]>>[/COLOR] بعد حذف أي سجل سنجعل قيمته [COLOR=blue]False[/COLOR] [COLOR=teal]>>[/COLOR] بعد الحفظ في ملف ستصبح قسمته [COLOR=blue]True[/COLOR] [COLOR=teal]>>[/COLOR] بعد الضغط على قائمة ملف جديد سنجعل قيمته [COLOR=blue]True[/COLOR] [COLOR=teal]>>[/COLOR] بعد فتح ملف سنجعل قيمته [COLOR=blue]True[/COLOR] وبعد إنجاز هذه النقاط سنضع شرط فحص قيمة [COLOR=blue]IsSaved [/COLOR]عند الضغط على قائمة ملف جديد وكذلك عند إنهاء البرنامج فإذا كانت البيانات غير مخزنة تظهر رسالة سؤال عن الرغبة في حفظ البيانات ، وهذا هو الكود بعد التعديل : [COLOR=teal]>>[/COLOR] زر جديد : كود:

procedure TForm1.N2Click(Sender: TObject); Var C : Integer; begin C := idNo; If Not IsSaved Then c:= MessageBox(Application.Handle,'هل تريد حفظ البيانات قبل المتابعة ؟' ,'البيانات غير محفوظة',MB_YESNOCANCEL +MB_ICONQUESTION +MB_RTLREADING); If C <> idCancel Then Begin If C = IdYes Then N5Click(Sender); DeleteCards(FirstPoint); SetNilPointers; EmptyFields; IsNewRec := True; RecordCount := 1; CurrentRec := 1; Form1.Caption := 'ملف جديد'; IsSaved := True; ConfigMovePanel; End; end;

[COLOR=teal]>>[/COLOR] عند إغلاق البرنامج : .. نستعمل الحدث [COLOR=blue]FormDestroy [/COLOR]وهذا هو الكود : كود:

procedure TForm1.FormDestroy(Sender: TObject); begin If Not IsSaved Then If MessageBox(Application.Handle,'هل تريد حفظ البيانات قبل الإنهاء ؟' ,'البيانات غير محفوظة',MB_YESNO +MB_ICONQUESTION +MB_RTLREADING) = idYes Then N5Click(Sender); end;

[COLOR=teal]>>[/COLOR] زر فتح : كود:

procedure TForm1.N4Click(Sender: TObject); Var C:Integer; begin C := idNo; If Not IsSaved Then c:= MessageBox(Application.Handle,'هل تريد حفظ البيانات قبل المتابعة ؟' ,'البيانات غير محفوظة',MB_YESNOCANCEL +MB_ICONQUESTION +MB_RTLREADING); If C <> idCancel Then Begin If C = IdYes Then N5Click(Sender); If OpenDialog1.Execute Then OpenAMPGFile(OpenDialog1.FileName); End; end;

[COLOR=sienna]3[/COLOR][COLOR=green]-[/COLOR] يجب أن تكون باقي قوائم سجلات غير متاحة إذا كانت الأزرار المقابلة لها غير متاحة .. [COLOR=teal]>>[/COLOR] في إجراء [COLOR=blue]ConfigMovePanel [/COLOR]نضيف الأسطر التالية ضمن كتلة [COLOR=blue]With Form1 :[/COLOR] كود:

n10.Enabled := GoNew.Enabled; n19.Enabled := DelCurrRec.Enabled; n12.Enabled := GoFirst.Enabled; n13.Enabled := GoPrevious.Enabled; n14.Enabled := GoNext.Enabled ; n15.Enabled := GoLast.Enabled ;

[COLOR=sienna]4[/COLOR][COLOR=green]-[/COLOR] ظهور خطأ في حالة الرغبة بتخزين ملف جديد به أول سجل فقط : سبب هذا الخطأ هو أن السجل الحالي عند عملية حفظ الملف لا يتم حفظه في السجل في الذاكرة إذا كان عدد السجلات [COLOR=green]=[/COLOR][COLOR=sienna]1[/COLOR] فقط والسجل غير محفوظ إذاً [COLOR=blue]FirstPoint = Nil [/COLOR]مما يؤدي إلى هذا الخطأ لمعالجته فإننا بحاجة إلى عملية حفظ السجل الحالي في الذاكرة قبل كل عملية حفظ الملف لعمل هذا نضيف الكود التالي في أول إجراء [COLOR=blue]SaveAllToFile:[/COLOR] كود:

If IsNewRec then Begin CurrPoint := NewPhoneCard(CurrPoint); LastPoint := CurrPoint; End; SaveToCard (CurrPoint);

[COLOR=sienna]5[/COLOR][COLOR=green]-[/COLOR] عدم تخزين التعديلات المجراة على السجل الحالي : لقد تم حل هذه المشكلة من خلال حل المشكلة السابقة لأن السبب واحد

 

 اسم العضو:DelphiLover  الاثنين,20/محرم/1426 هـ,09:34 مساءً
[ALIGN=center][COLOR=purple]السلام عليكم ورحمة الله وبركاته ما شاء الله أستاذ مهند عبادي بجد شكراً شكراً شكراً على الدروس الرائعة ... اللي يتابعها يستفيد أكثر من الأكواد .. يستفيد خبرة تصميم البرامج بكل سهولة بصراحة موضوع رهيب جداً أشكرك مرة ثانية [/COLOR][/ALIGN] 

 اسم العضو:khaled helal  الاثنين,20/محرم/1426 هـ,10:43 مساءً
أخى مهند عبادى . .
لم أرى من هو خير منك فى سرد اى شرح لأى برنامج أو فكرة فتحية لك على هذا المجهود الرائع منك لأخوانك فى هذا المنتدى . . . 

 اسم العضو:مهند عبادي  الخميس,23/محرم/1426 هـ,06:23 صباحاً
[ALIGN=center][COLOR=red][SIZE=5]الدرس التاسع [/COLOR][/SIZE]والأخير[/ALIGN] [COLOR=sienna]6[/COLOR][COLOR=darkred]-[/COLOR] عملية البحث وفق أحد الحقول : من أجل انجاز هذه الإمكانية فإننا نحتاج إلى ما يلي : [COLOR=teal]>> إضافة زر البحث : [/COLOR]سنسمي هذا الزر [COLOR=blue]CardSearch [/COLOR]وإضافة قائمة فرعية لقائمة سجلات بعنوان البحث ضمن السجلات [COLOR=teal]>> واجهة البحث :[/COLOR] يوجد في دلفي ضمن مجموعة [COLOR=blue]Dialogs [/COLOR]مربع حوار خاص بالبحث اسمه [COLOR=blue]FindDialog [/COLOR]نضيفه إلى الفورم لاستخداه في عملية البحث .. ولكي نستطيع أن نختبره نعمل دبل كليك فوقه فيفتح لنا مربع الحوار كما في هذا الشكل : [ALIGN=center][IMG]http://www.arabmoheet.net/forum/Members_Upload_Pics/15/Tel_5.gif[/IMG][/ALIGN]نلاحظ وجود خيارات فيه هي : [COLOR=blue]Match whole word only [/COLOR]و [COLOR=blue]Match case [/COLOR]و [COLOR=blue]Direction .. [/COLOR]ونحن بالحقيقة لسنا بحاجة إلى هذه الخيارات .. لذلك نقوم بإخفائها من خلال خصائص أداة [COLOR=blue]FindDialog [/COLOR]خاصية [COLOR=blue]Options [/COLOR]وهي خاصية مركبة من ضمنها [COLOR=blue]FrHidewholeword - FrHideMatchCase - FrHideUpDown [/COLOR]نضع قيمة هذه الخصائص الثلاثة تساوي [COLOR=blue]True ..[/COLOR] بحيث يصبح شكل فورم البحث هكذا : [ALIGN=center][IMG]http://www.arabmoheet.net/forum/Members_Upload_Pics/15/Tel_6.gif[/IMG][/ALIGN] [COLOR=teal]>> تصميم إجراء البحث [/COLOR] : البحث عن أي سلسلة محارف ضمن جميع الخلايا ضمن جميع البطاقات ويتوقف عند البطاقة التي تحتوي على مطابق ، ويجب أن يراعي هذا الإجراء إما بداية البحث من أول بطاقة أو المتابعة من البطاقة الحالية لذلك نعرف متحولاً عاماً جديداً من النمط [COLOR=blue]Boolean [/COLOR]نسميه [COLOR=blue]SearchStart [/COLOR]لتحديد هذه النقطة . وهذا هو إجراء البحث : كود:

Procedure FindCard(T : String); Var FindIt : Boolean; S : String; Const X = char(0); Begin FindIt := False; While ((CurrPoint <> LastPoint) or SearchStart) AND (Not FindIt) do Begin If SearchStart Then Begin form1.GoFirstClick(Form1); SearchStart := False; End Else form1.GoNextClick(Form1); With currPoint^ Do S := FName + X + LName + X + Address + X + HomeNo + X + JobNo + X + FaxNo + X + Mobile + X + Email + X + Page + X + Rem ; If pos(UpperCase(T),UpperCase(S)) > 0 Then FindIt := True ; End; If Not FindIt Then Begin messageBox(application.Handle,وصل البحث إلى نهاية دليل الهاتف','رسالة البحث',MB_OK + MB_ICONWARNING + MB_APPLMODAL + MB_RTLReading); SearchStart:=True; End; End;

نلاحظ أننا استخدمنا في الإجراء السابق تعليمة [COLOR=blue]Pos [/COLOR]للبحث عن وجود سلسلة محارف جزئية ضمن سلسة محارف .. وهو دالة تعود بقيمة تمثل ترتيب الحرف حيث يوجد السلسة الفرعية .. أما إذا لم توجد فإن نتيجة هذه الدالة تكون صفراً . أيضاً نلاحظ استخدام تعليمة [COLOR=blue]UpperCase [/COLOR]ووظيفتها تحويل الأحرف الانكليزية من نمط الأحرف الصغيرة [COLOR=blue]small Litters [/COLOR]إلى أحرف كبيرة [COLOR=blue]Capital Litter .. [/COLOR]وقد استعملت هذه الدالة لتجاهل حالة الأحرف الصغيرة أو الكبيرة في عملية البحث [COLOR=teal]>> كتابة الكود المناسب للبدء بالبحث ومتابعته :[/COLOR] إن عملية البحث في العادة بعد كتابة كلمة ما ، وعند كل ضغطة على كلمة [COLOR=blue]Find Next [/COLOR]يقوم بالانتقال إلى بطاقة تالية تحتوي على نص البحث . لذلك فإن عملية البحث تتم عند الضغط على هذا الزر .. ولبرمجة هذا الزر بالذات نحدد أداة [COLOR=blue]FindDialog [/COLOR]ثم من خلال نافذة الأحداث الخاصة به ننقر نقراً مزدوجاً على خاصية [COLOR=blue]OnFind [/COLOR] ثم نضيف كود البحث هذا : كود:

procedure TForm1.FindDialog1Find(Sender: TObject); begin FindCard(FindDialog1.FindText); end;

ومن أجل إظهار مربع حوار البحث نكتب في حدث الصغط على زر البحث الموجود في الفورم هذا الكود : كود:

procedure TForm1.CardSearchClick(Sender: TObject); begin SearchStart := True; FindDialog1.Execute; end;

نلاحظ أننا عينا متحول [COLOR=blue]SearchStart [/COLOR]إلى القيمة [COLOR=blue]True [/COLOR]قبل بداية أي بحث .. هذا من أجل أن يبدأ البحث أول مرة من بداية الأسماء .. وأخيراً نضيف كود من أجل قائمة البحث بنفس أسلوب باقي قوائم [COLOR=darkred]([/COLOR]قائمة سجلات[COLOR=darkred])[/COLOR] حسناً دعونا نجرب الآن إمكانية البحث ... هل عملت كما ينبغي ؟؟

[COLOR=sienna]7[/COLOR][COLOR=darkred]-[/COLOR] عرض قائمة بجميع الأسماء : أين ستظهر هذه القائمة ؟؟ وكيف سنضيفها ؟؟ وما الغاية منها ؟؟ ؛ ستظهر هذه القائمة في يمين الفورم على يمين العناصر الموجودة حالياً .. ولإضافتها نمسك الحد الأيمن للفورم ثم نسحبه لكي نزيد عرض الفورم بالشكل الكافي فإضافة هذه القائمة ، ثم نضيفها [COLOR=darkred]([/COLOR]أداة [COLOR=blue]ListBox [/COLOR]من مجموعة [COLOR=blue]Standard) [/COLOR]في المكان الفارغ .. ستكون الفائدة من هذه القائمة بالإضافة إلى عرض جميع الأسماء بشكل سريع أمام المستخدم هي أن يتم الانتقال إلى سجل اسم معين عند الضغط عليه في هذه القائمة بعد أن أدرجنا هذه الأداة يلزم أنا نصمم إجراء يقوم بإضافة جميع الأسماء إلى هذه القائمه .. وهذا هو : كود:

Procedure FillTheList(PCard : PhonePointer); Begin If Pcard <> Nil Then Form1.ListBox1.Items.Add (Pcard^.FName + ' ' + Pcard^.LName); If Pcard <> Lastpoint Then FillTheList(pCard^.Next); End;

نلاحظ أن هذا الإجراء إجراء تعاودي . أي يستدعي نفسه ، فبعد إضافة كل بطاقة يتم التأكد من أنها ليست البطاقة الأخيرة من أجل استدعاء نفس الإجراء مع البطاقة التالية .. الآن نعدل كود إجراء [COLOR=blue]ConfigMovePanel [/COLOR]لكي يعرض لنا القائمة ويعرض كلمة سجل جديد إذا كان هنالك سجل جديد ويعمل تحديد للسجل الحالي في القائمة .. بحث يصبح هذا الإجراء كما يلي : كود:

Procedure ConfigMovePanel; Begin With Form1 Do Begin ListBox1.Clear ; FillTheList(firstpoint); If IsNewRec then Begin Panel1.Caption := 'سجل جديد من '+ IntToStr(RecordCount); ListBox1.Items.Add('سجل جديد'); End 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 > '); DelCurrRec.Enabled := Not IsNewRec; n10.Enabled := GoNew.Enabled; n19.Enabled := DelCurrRec.Enabled; n12.Enabled := GoFirst.Enabled; n13.Enabled := GoPrevious.Enabled; n14.Enabled := GoNext.Enabled ; n15.Enabled := GoLast.Enabled ; ListBox1.Selected[CurrentRec-1]:=True ; End; End;

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

Procedure GoTORecord(Rno : LongInt); Var R : LongInt; Begin If IsNewRec then Begin CurrPoint := NewPhoneCard(CurrPoint); LastPoint := CurrPoint; IsNewRec := False; End; SaveToCard (CurrPoint); CurrPoint:= FirstPoint; For R:=1 To Rno Do CurrPoint := CurrPoint^.Next ; GetFromCard (CurrPoint); CurrentRec := Rno+1; ConfigMovePanel; End;

ثم نكتب في حدث عند النقر على أداة القائمة [COLOR=blue]ListBox1 [/COLOR]هذا الكود : كود:

procedure TForm1.ListBox1Click(Sender: TObject); begin GoTORecord(ListBox1.ItemIndex); end;

[COLOR=sienna]8[/COLOR][COLOR=darkred]-[/COLOR] تحسين الإظهارات : تتضمن تحسين الإظهارات ما يلي : [COLOR=teal]الأزرار :[/COLOR] ويتم تحسينها من خلال إضافة صور للأزرار وبما أن الأزرار ليست لديها هذه الميزة نقوم باستبدالها بأزرار [COLOR=blue]BitBtn [/COLOR]حيث نحذف الأزرار القديمة ثم نضيف أزار [COLOR=blue]BitBtn [/COLOR]ونسميها نفس أسماء الأزرار القديمة ثم نربطها مع حدث النقر وذلك من خلال لوحة الأحداث ننقر نقر مزدوج فوق حدث [COLOR=blue]Click[/COLOR] [COLOR=Teal]القوائم :[/COLOR] ويتم تحسينها بإضافة صور إليها .. ويتم هذا باتباع الخطوات التالية : أ [COLOR=darkred])[/COLOR] إدراج أداة [COLOR=blue]ImageList [/COLOR]ضمن الفورم من مجموعة [COLOR=blue]Win32[/COLOR] ب[COLOR=darkred])[/COLOR] نقر مزدوج على هذه الأداة لفتح نافذة التحكم بها ونضيف إليها الصور المطلوبة .. حيث تأخذ كل صورة رقماً خاصاً بها جـ[COLOR=darkred])[/COLOR] نحدد أداة [COLOR=blue]MainMenu [/COLOR]ثم نعين خاصية [COLOR=blue]Images [/COLOR]تساوي [COLOR=blue]ImageList1[/COLOR] د [COLOR=darkred])[/COLOR] نحدد لكل قائمة أو قائمة فرعية في خاصية [COLOR=blue]ImageIndex [/COLOR]رقم الصورة المطلوب إظهارها بجانبه..

وهكذا نكون قد أنهينا تصميم البرنامج وأصبح في درجة مقبولة من الجودة .. وهذا هو الشكل النهائي للبرنامج : [ALIGN=center][IMG]http://www.arabmoheet.net/forum/Members_Upload_Pics/15/Tel_7.gif[/IMG][/ALIGN] طبعاً يمكن لأي واحد أن يأتي بأفكار لتطوير هذا البرنامج أو لاستكمال نواقصه [COLOR=darkred]([/COLOR]مثل : إضافة [COLOR=blue]HotKeys - [/COLOR]منع إدخال نفس الاسم أكثر من مرة [COLOR=darkred]-[/COLOR] ربطه مع برنامج الأوتلوك ...الخ[COLOR=darkred])[/COLOR]

وفي النهاية أرجوا من الله تعالى أن أكون قد أفدتكم في هذه الدورة وأن يخلص نيتي لوجهه الكريم [ALIGN=center][COLOR=blue]
[SIZE=6]انتهت الدورة[/COLOR][/SIZE]
[/ALIGN] 

 اسم العضو:am2812  السبت,23/فر/1426 هـ,05:42 مساءً
أخي الكريم دورة ممتازه وجزاك الله خيراً لأكن أرجو منك مراجعة الملفات لأنني حاولت التحميل لكن حجم الملفات صفر يعني لا يوجد شيء  

 اسم العضو:am2812  الأحد,24/فر/1426 هـ,01:20 صباحاً
أخي الكريم مهند تم تحميل الملف لكن في خطأ دائم الظهور هل هذا من مساويء استخدام اللوائح ام ماذا ؟ مرفق صورة الخطأ وشكراً  

 اسم العضو:مهند عبادي  الأربعاء,27/فر/1426 هـ,07:05 صباحاً
لا أستطيع الجزم بسبب الخطأ .. هل تستطيع تحديد متى يحدث بالضبط ؟؟ 

 اسم العضو:am2812  السبت,01/ربيع الأول/1426 هـ,03:15 صباحاً
الأخ مهند السلام عليكم الخطأ يحصل عندما يكون سجل مثلا فاضي واردت الانتقال الى سجل آخر ومرفق صورة توضح ذلك وشكراً 

 اسم العضو:am2812  السبت,01/ربيع الأول/1426 هـ,05:37 صباحاً
وهذا أيضا  

 اسم العضو:am2812  السبت,01/ربيع الأول/1426 هـ,05:38 صباحاً
تابع للسابق 

 اسم العضو:M-SOFT  الأحد,09/ربيع الأول/1426 هـ,06:38 مساءً
بسم الله الرحمن الرحيم الاخ مهند تحيه طيبه احيك على الموضوع الرا ئع جدا وهي فكره جميله جدا ان يتعلم الانسان بهذا الاسلوب لكن واجهتني مشكله ان الملفات المرفقه لاتفتح وتظهر لي رساله بان الملفات تالفه عن التنزيل وقد جربت ذلك عدة مراة ارجو ان تاجد ردا على هذه المشكله .  

 اسم العضو:مهند عبادي  الأحد,16/ربيع الأول/1426 هـ,04:33 صباحاً
الأخ M-SOFT .. جرب أن تحدث برنامج WinRar لديك 

 اسم العضو:Hosain21  الجمعة,23/جمادى الثانية/1426 هـ,02:24 صباحاً
السلام عليكم ورحمة الله وبركاته أستاذنا الكريم : أجزل الله لكم المثوبة وتقبّل منكم 0  

 اسم العضو:عاشقة الأكسس  السبت,09/رجب/1426 هـ,10:54 مساءً
ألف شكر للأستاذ مهند وأرجو أن تتابع في الدروس مواضيع أخرى 

 اسم العضو:hom_rcp  الخميس,14/رجب/1426 هـ,05:47 مساءً
السلام عليكم ورحمة الله استاذنا الكريم للأسف لم أتعرف على هذا الموقع القيم إلا منذ أيام لقد رأيت الدورة و اتطلعت عليها وهي راإعة جداً وشكراً جزيلاً لك سؤالي الأول : لقد استخدمت اللوائح المترابطة على هيئة المكدس فلماذا لم توحي إلى ذلك , وسؤالي الثاني : لماذا لم تستخدم الملفات النمطية بدلاً من الملفات النصية علماً أن الأول هو المتعارف عليه في مثل هذا النوع من البرامج ؟ ولك جزيل الشكر أستاذي الجديد مهند عبادي .. وأعلمك أني المستفيد الأكبر بدون منازع لهذه الدورة لأني أبحث عن هذا الموضوع تحديداً منذ قرابة الشهر وشكراً جزيلا مجدداً همام من دمشق .... كيف الحال إن شاء الله دوم بخير ؟ 

 اسم العضو:مهند عبادي  السبت,16/رجب/1426 هـ,02:17 مساءً
السلام عليكم ورحمة الله وبركاته أوجه الشكر للأخ Hosain21 والأخت عاشقة الأكسس كما أشكر الأخ hom_rcp على مداخلته الجيدة .. [QUOTE] لقد استخدمت اللوائح المترابطة على هيئة المكدس فلماذا لم توحي إلى ذلك , [/QUOTE] الجواب هو أني أركز في هذه الدورة على التعامل مع المؤشرات بشكل عام .. وبغض النظر عن شكل اللائحة النهائي ، والتي يمكن إن أتقنها الشخص أن يتعامل مع اللوائح من أي نمط (شجري - حلقي - نجمي - خطي) ولم أشر إلى نمط اللائحة (سهواً) لأني ركزت على مبدأ الترابط نفسه [QUOTE] لماذا لم تستخدم الملفات النمطية بدلاً من الملفات النصية علماً أن الأول هو المتعارف عليه في مثل هذا النوع من البرامج ؟ [/QUOTE] كان الهدف أيضاً من الدورة تعليم بناء الملفات ذات البنية الخاصة وفي استخدام الملفات النصية استطعنا أن نتعلم كيفية عمل Header للملف وكيفية اختبار نوع الملف .. وأنا أفضلها على الملفات النمطية على أي حال 

 اسم العضو:sattar2006  الأحد,14/شوال/1427 هـ,02:38 صباحاً
الأخ والأستاذ مهند العابادي المحترم السلام عليكم ورحمة الله وبركاته بارك الله فيك على هذا الموضوع القيم ونطمح منح المزيد مع امنياتي لكم بالتوفيق  

 اسم العضو:salahafifi  الثلاثاء,15/ذو القعدة/1427 هـ,02:50 صباحاً
جزاك الله خيراً ... وجعله فى ميزان حسناتك ... آمين. 

 اسم العضو:abo abyda  الأحد,18/ذو الحجة/1427 هـ,01:23 صباحاً
جزاكم الله خيرا 

 اسم العضو:amhr  الأربعاء,20/محرم/1428 هـ,04:46 مساءً
بسم الله الرحمن الرحيم جزاك الله خيرا على هذه المعلومات القيمة ولكن لي طلب لما لا تضيف زراً للقيام بالإتصال ارجو ان تزودني بهذه المعلومة وشكرا 

 اسم العضو:First Star  السبت,28/فر/1428 هـ,07:17 صباحاً
شكرا لك ياأخي الكريم 

 اسم العضو:First Star  السبت,28/فر/1428 هـ,07:19 صباحاً
واطلب منك لو سمحت كتاب عربي ممتاز لتعليم الدلفي 7 من المبتدئ لمستوى متقدم وشكرا 

 اسم العضو:bouchibane_1983  السبت,27/ربيع الأول/1428 هـ,08:09 صباحاً
الف الف شكر 

 اسم العضو:marwnk  الأربعاء,29/ربيع الثاني/1428 هـ,03:08 صباحاً
الف الف شكور على الدرس الطيب ( وأسال الله لكم التوفيق ) ..... 

 اسم العضو:First Star  الخميس,01/جمادى الأولى/1428 هـ,08:26 صباحاً
أين الرد على سؤالي.... 

 اسم العضو:حمادهp  الأحد,25/جمادى الأولى/1428 هـ,02:07 مساءً
اخي اشكرك على المجهود الطيب اخب اين توجد كلنه:.. والمفروض من أجل سهولة العمل أن نقوم بتعريف نمط جديد Type خاص بالبطاقات تعريف الأنماط الخاصة بالبرنامج : 1- يتم وضع تعريف الأنماط الخاصة بالبرنامج ضمن تعريفات كلمة Type الموجودة في أعلى Unit1 2- يأخذ تعريف نمط جديد مؤلف من عدة سجلات هذه الصيغة : غير موجوده عندي لا احيدها في الدلفي  

 اسم العضو:delphi555  الخميس,14/شوال/1428 هـ,04:14 مساءً
السلام عليكم انا مبتدأ اخي يا ريت تعمل دورة للمبتدئين عموما انا ما فهمت كيف اوضع الكود في مكانه الصحيح انا متبع معك الدرس ولكن لم اسوعي بعد ممك تشرح اكثر والسلام عليكم 

 اسم العضو:ahmadj5  الجمعة,10/محرم/1429 هـ,11:38 صباحاً
اخي الموضوع ممتاز و الفائدة كبيرة ان شاء الله و وفقك الله للخير 

 اسم العضو:akero  الخميس,07/فر/1429 هـ,02:34 مساءً
شكراً لك اخي الكريم على هذا المقال البرنامج غاية فى الجمال بس الرجاء تحميل الشرح مع البرنامج وشكراً 

 اسم العضو:khadija1  السبت,01/ربيع الأول/1429 هـ,12:31 مساءً
[ALIGN=center][IMG]http://www.arabmoheet.net/forum/pics/bsmla.gif[/IMG][/ALIGN] اود السؤال هل يمكن استخدام ازار الحفظ والتعديل وما الى دلك او يفضل استخدامprocedure مع الشكر 

 اسم العضو:athen25  الثلاثاء,24/شعبان/1429 هـ,02:25 مساءً
استاذي العزيز ممكن ترسل لنا ايقونات دلفي ؟ والله يحفظكم ويرعاكم ويجعل ذلك في موازين حسناتكم 

 اسم العضو:ibrahematia  الجمعة,03/شوال/1429 هـ,10:46 صباحاً
مشكور اخي العزيز على هذا الشرح ويا ليث يكون شرح على المصفوفات في البحث وعدم التكرار وكل العام والجميع بخير  

 اسم العضو:End Sub  الأحد,12/شوال/1429 هـ,05:07 مساءً
شــكراااا جدااااا لك أخى 

 اسم العضو:ابو حمد  الاثنين,03/ذو الحجة/1429 هـ,12:06 مساءً
جعله الله في ميزان حسناتك 

 اسم العضو:samiro79  الأحد,08/محرم/1430 هـ,12:03 مساءً
[ALIGN=center][IMG]http://www.arabmoheet.net/forum/pics/bsmla.gif[/IMG][/ALIGN] [SIZE=3][COLOR=indigo]بارك الله فيك[/COLOR][/SIZE]  

 اسم العضو:redouane ali  السبت,18/ربيع الأول/1430 هـ,07:45 مساءً
بارك الله فيك موفق في الشرح و الاداء 

 اسم العضو:inassah  الاثنين,27/ربيع الأول/1430 هـ,02:26 صباحاً
بارك الله فيك أخي كفيت ... ووفيت 

 اسم العضو:GHU  الاثنين,13/جمادى الثانية/1432 هـ,12:07 صباحاً
بارك الله فيك أخي على هذه الدروس وأدخلك الله بها الجنة وأرجو من المشرفين إعادة النظر في الروابط لأنها لا تعمل أو [COLOR=#87ceeb]إعادة شرح مكان وضع الأكواد [/COLOR] كما نطلب من خبراء الدلفي تزويدنا بمثل هذه الدروس أي كتابة برنامج معين من الصفر إلى إكمال البرنامج كما قام به [B][I]مهند عبادي[/I][/B] أدخله الله الجنة 

 اسم العضو:a-majeed  الثلاثاء,09/فر/1433 هـ,07:49 مساءً
شكراً لك لو كانت الدوره بقاعدتين نصيه واكسس كانت افضل 

جميع الحقوق محفوظة لـمنتديات المحيط العربي 2004 - 2021