السلام عليكم و رحمة الله و بركاته
Parent, Sender,Owner, ControlCount, ComponentCount
ما هو Sender المرسل ؟
تحتوي جميع احداث دلفي على الوسيط Sender لكن ما هو هذا الوسيط و كيف نستفيد منه الوسيط Sender هو من النمط TObject و هو الاب لجميع الانماط في الدلفي لذلك يمكن ان يحمل اي نمط مورث منه...
فكر في Sender على انه طريقة لمعرفة من استدعى الحدث...
كيف نستفيذ منه ؟
يوفر الوسيط Sender طريقة لمعرفة من استدعى الحدث لذلك ستكون لديك مرونة كبيرة في حالة كان الكود يتكرر في العديد من الاماكن
الفورم اعلاه يحتوي على مجموعة من TSpeedButton تمت اعادة تسميتها بالطريقة btn_0, btn_1, btn_2 الخ و كما هو واضح الفورم عبارة عن آلة حاسبة بسيطة نريد عندما ننقر على الارقام كتابتها في Edit1 تماما مثل الالة الحاسبة ليس الهدف برمجة الة حاسبة نريد فقط توضيح الفكرة مبرمجنا لا يوضف الـ Sender لذلك سيكتب الكود عند حدث النقر على الزر btn_0 :
PHP كود :
procedure TForm1.btn_0Click(Sender: TObject);
begin
Edit1.Text := btn_0.Caption;
end;
شيئ بسيط و سنحصل على الكود التالي لجميع الازرار
PHP كود :
procedure TForm1.btn_0Click(Sender: TObject);
begin
Edit1.Text := btn_0.Caption;
end;
procedure TForm1.btn_1Click(Sender: TObject);
begin
Edit1.Text := btn_1.Caption;
end;
procedure TForm1.btn_2Click(Sender: TObject);
begin
Edit1.Text := btn_2.Caption;
end;
procedure TForm1.btn_3Click(Sender: TObject);
begin
Edit1.Text := btn_3.Caption;
end;
procedure TForm1.btn_4Click(Sender: TObject);
begin
Edit1.Text := btn_4.Caption;
end;
procedure TForm1.btn_5Click(Sender: TObject);
begin
Edit1.Text := btn_5.Caption;
end;
procedure TForm1.btn_6Click(Sender: TObject);
begin
Edit1.Text := btn_6.Caption;
end;
procedure TForm1.btn_7Click(Sender: TObject);
begin
Edit1.Text := btn_7.Caption;
end;
procedure TForm1.btn_8Click(Sender: TObject);
begin
Edit1.Text := btn_8.Caption;
end;
procedure TForm1.btn_9Click(Sender: TObject);
begin
Edit1.Text := btn_9.Caption;
end;
لاحظ الالم في تكرير الكود يقوم تقريبا بنفس العمل
لنوضف الـ Sender
في حدث الضغط على الزر btn_0
اكتب
PHP كود :
procedure TForm1.btn_0Click(Sender: TObject);
begin
Edit1.Text := TSpeedButton(Sender).Caption;
end;
حدد جميع الازرار اذهب ObjectInspector -> Events الحدث OnClick تصفح القائمة ستجد btn_0Click اختره الذي قمنا به هو اننا اسندنا الحدث btn_0Click الى الازرار btn_1, btn_2, btn_3 ... اي عندما نضغط على btn_1 كأننا ضغطنا على btn_0 كما قلنا يمكننا ان نعرف عن طريق الـ Sender الزر الذي طلب الحدث و بالتالي الاستجابة حسبه ...
فبدل العشر اسطر سنحصل على سطر واحد نظيف و في مكان واحد
ما هو Owner المالك ؟
Owner المالك هو المسؤول عن تحرير الذاكرة لجميع المكونات التي يملكها
لنلاحظ المثال التالي:
PHP كود :
procedure TForm1.Button1Click(Sender: TObject);
var
OpenDialog: TOpenDialog;
begin
OpenDialog := TOpenDialog.Create(Self);
if not(OpenDialog.Execute) then Exit;
ShowMessage(OpenDialog.FileName);
end;
باني Constructor للغرظ TOpenDialog يحتوي على وسيط AOwner اي يمكن تمرير مالك للـ TOpenDialog سيكون مسؤول عن تحرير الغرض من الذاكرة عندما يتحرر بدوره من الذاكرة لذلك لا داعي لاستخدام Free قمنا بتمرير Self الى الوسيط, Self هنا تعود للـ TForm1 اي عند استدعاء هادم TForm1 عن طريق Free مثلا سيتم استدعاء هادم TOpenDialog
ما هو الـ Parent الاب ؟
ليس كل المكونات يمكن لها ان تكون اباء هناك فئة من المكونات التي يمكن لها ان تكون اباء لمكونات اخرى نذكر منها TPanel, TForm, TPageControl, TTabSheet, TGroupBox و مثل في الحياة يمكن للابناء ان يحملو صفات الاباء فمثلا زر موجود على Panel1 يمكن له ان يحمل نفس لون Parent و يمكن للـ Parent ان يغير جميع نوع الخط حجم الخط لجميع الابناء يكفي فقط ان تكون خاصية ParentFont = True للابن
PHP كود :
Button1.ParentFont := True;
[ComponentCount, Components[Index ؟
كما يمكن الوصول الى خصائص المكونات عن طريق اسم المكون مثل Edit1.Text يمكن الوصول الى المكونات عن طريق Index رقم المكون او رتبته الخاص بها جميع المكونات على الفورم لديها Index خاص بها فمثلا فورم يحتوي فقط على مكون Edit1 سيكون Index الخاص بالـ Edit1 هو 0 و بالتالي يمكن الوصول الى المكون Edit1 عن طريق معرفة Index السطرين التالين متكافئان و يقومان بنفس الامر
PHP كود :
Edit1.Text := 'Delphi4Arab';
TEdit(Components[0]).Text := 'Delphi4Arab.Net';
لنفترض لدينا مجموعة من الـ Edits و نريد عمل Reset افراغ جميع المكونات من النصوص مبرمج لا يضف ComponentCount سيكتب شيئ مثل
PHP كود :
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit1.Clear;
Edit2.Clear;
Edit3.Clear;
Edit4.Clear;
Edit5.Clear;
Edit6.Clear;
Edit7.Clear;
Edit8.Clear;
Edit9.Clear;
Edit10.Clear;
Edit12.Clear;
Edit13.Clear;
end;
و مرة اخرى الم كبير في تكرير الكود
باستخدام الـ ComponentCount يمكننا عمل حلقة على جميع مكونات الفورم التحقق اذا كانت من النمط TEdit اذا كانت كذلك نقوم بعملية تسمى Type Casting و نقوم باجراء ما نريد و سيكون لدينا كود انضف بكثير
PHP كود :
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
begin
for I := 0 to ComponentCount - 1 do
if (Components[i] is TEdit) then
TEdit(Components[i]).Clear;
end;
لكن ماذا لو كان لدينا جميع Edits موجودة على Panel اي
PHP كود :
Edit1.Parent <> nil
عندها الكود اعلاه لن يعمل حاول ذلك و لن يعمل ما العمل دلفي يوفر طريقة اخرى
[ControlCount,Controls[Index ؟
اذا كان المكونات لديها Parent نستخدم ControlCount بدل من ComponentCount
PHP كود :
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
begin
for I := 0 to Panel1.ControlCount - 1 do
if (Panel1.Controls[i] is TEdit) then
TEdit(Panel1.Controls[i]).Clear;
end;
[Screen.FormsCount, Forms[Index ؟
ماذا لو اردنا ان نغير جميع الـ Captions لجميع الفرومات في مشروعنا او خواص اخرى
يمكننا ذلك عن طريق FormsCount التابعة للنمط Screen مثال:
PHP كود :
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
begin
for I := 0 to Screen.FormCount -1 do
begin
TForm(Screen.Forms[i]).Caption := 'Test' + IntToStr(I);
TForm(Screen.Forms[i]).Show;
end;
end;
ان شاء الله اكون قد وفقت في الطرح ان اصبت فمن الله و ان أخطأت فمن نفسي و الشيطان و السلام عليكم
و لرب نازلة يضيق لها الفتى ذرعا و عند الله منها المخرج
ضاقت فلما استحكمت حلقاتها فرجت و كنت اضنها لا تفرج
ضاقت فلما استحكمت حلقاتها فرجت و كنت اضنها لا تفرج



![[-]](https://delphi4arab.net/forum/D4A2020/collapse.png)