الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

الفرق بين هاتين الطريقتين-استفسار وليس بسؤال-لاصحاب الخبرة

مغلق
بدأه essam7 في 25 يوليو 2006 · 8 رد · 653 مشاهدة · في لغة Delphi
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

اود من اصحاب الخبرة ان يبينو ا الفرق بين هذين الكودين:

كفكرة عامة عندي فورم رئيسي وفورم ثانوي

عند استدعاء الفورم الثانوي من الفورم الرئيسي بواسطة زر مثلا سيظهر الفورم الثانوي والذي يحوي

عددا من اللافتات ومربعات الادخال (ايديت) وزر الاغلاق وزر اوكي!! طبعا عددها غير معروف الا عند لحظة انشاء الفورم الثانوي ولنتخيل العدد هو من اختيار المستخدم في الفورم الرئيسي وعند اختيار العدد يوضع ضمن متحول عام فوق الامبلمنتيشن ليراه الفورم الثانوي

السؤال هو التالي :

ما هو الفرق تماما جدا بين الطريقتين التاليتين:

اولا :

اعمل الفورم الثانوي في زمن التصميم وبه مثلا 100 لافتة (هو الحد الاعلى لدى المستخدم اي اصلا لا يستطيع المستخدم اختيار اكبر من ذلك)

وكذلك 100 ايديت وزرين واضع كلللللل الاحداث اللازمة

للعلم انا اهتم باحداث onkeypress onkeydown

طبعا كل الافتات والايديتات مخفية !!!

عند كبس زر ما في الفورم الاساسي انشئ لبفورم الثانوي اي

application.createform(tform2,form2);

وفي حدث الكرييت له ارى المتحول كم قيمته مثلا 30 فاجعل 30 لا فتة و30ايدت ظاهرة واضبط مكان الزرين اوكي واغلاق واظبط حجم الفورم الثانوي!!!

وعند الانتهاء من الفورم الثانوي وعند اغلاقه او ضغط اوكي اعمل له كلوز

وفي حدث الكلوز اضع action:= cafree

هذه الطريقة الاولى والتي افضلها (لكن هي غبية بعض الشيئ ) المهم انها من ناحية الذاكرة انشات الفورم ليس عند اقلاع البرنامج وايضا عند اغلاق الفورم حررته من الذاكرة فهل عليها اشكال؟؟؟؟

الطريقة الثانية هي التالي وهذا كودها (صراحة هي احترافية اكثر لكن معقدة بلا طعمة اقصد ما في داعي للتعقيد ما دامت الاولى متوفرة!!!)

انشات فورم اساسي فقط عند اقلاع البرنامج وعند ضغط الزر انشات الفورم الثانوي

لكن في زمن التنفيذ انشات الثانوي ب

application.createform(tform2,form2)

عليه فقط زرين اغلاق واوكي اما الافتات والاديتات فبالشكل التالي انشاتها:

هذا الكود الكلي للفورم او الوحدة الثانوية

unit fmDifferentSMS

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TfmDifferentSMS = class(TForm)
	btOK: TButton;
	lbMsgLength: TLabel;
	btCancel: TButton;
	Label3: TLabel;
	procedure FormClose(Sender: TObject; var Action: TCloseAction);
	procedure FormCreate(Sender: TObject);
	procedure btOKClick(Sender: TObject);
	procedure btCancelClick(Sender: TObject);
	procedure TheEditChange(Sender: TObject); //لاحظ هذا الاجراء
	procedure TheEditEnter(Sender: TObject); //لاحظ هذا الاجراء
	procedure TheEditKeyPress(Sender: TObject; var Key: Char); //لاحظ هذا الاجراء
	procedure TheEditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); //لاحظ هذا الاجراء
	procedure FormShow(Sender: TObject);
	procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
	procedure FormKeyPress(Sender: TObject; var Key: Char);
  private
	{ Private declarations }
  public
	{ Public declarations }
  end;

var
  fmDifferentSMS: TfmDifferentSMS;

implementation

uses UntSendSMS; //الفورم الاساسي

{$R *.dfm}

function ShowStatus(Sender: TEdit): String;
var
  CharNum, MsgNum: Integer;
begin
  CharNum:= Length(Sender.Text) mod 43;
  MsgNum:= (length(Sender.Text) div 43)+ 1;
  if (CharNum= 0) and (Sender.Text <> '') then CharNum:= 43;
  if (Length(Sender.Text) mod 43)= 0 then MsgNum:= MsgNum- 1;
  if (Sender as TEdit).Text= '' then MsgNum:= 1;  
  Result:= inttostr(CharNum)+ ' of 43 Char(s)   '+ inttostr(MsgNum)+ ' Message(s)   '+(fmDifferentSMS.FindComponent('lb'+ copy((Sender as TEdit).Name, 3, 2)) as TLabel).Caption;
end;

procedure TfmDifferentSMS.TheEditChange(Sender: TObject);
begin
  lbMsgLength.Caption:= ShowStatus(Sender as TEdit);
end;

procedure TfmDifferentSMS.TheEditEnter(Sender: TObject);
begin
  lbMsgLength.Caption:= ShowStatus(Sender as TEdit);
end;

procedure TfmDifferentSMS.TheEditKeyPress(Sender: TObject; var Key: Char);
begin
  if (Key= #13) or (Key= #27) then
	Key:= #0;
end;

procedure TfmDifferentSMS.TheEditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  ob: TObject;
begin
  if Key= 13 then
  begin
	ob:= FindComponent('ed'+ inttostr(strtoint(copy(TEdit(Sender).Name, 3, 2))+ 1)); //لاحظ هذا التعقيد!!
	if ob <> nil then
	begin
	  (ob as TEdit).SetFocus;
	  (ob as TEdit).SelectAll;
	end else begin
			   btOK.SetFocus;
			   btOkClick(btOk);
			 end;
  end;
end;

procedure TfmDifferentSMS.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  Action:= caFree;
end;

procedure TfmDifferentSMS.FormCreate(Sender: TObject);
var
  i: Integer;
  ed: TEdit;
  lb: TLabel;
begin
  for i:= 0 to CounterMob- 1 do
  begin
	lb:= TLabel.Create(Self);
	lb.Parent:= Self;
	lb.Top:= 34+ (i* 26);
	lb.Left:= 10;
	lb.Caption:= 'To: '+ SendTo;
	lb.Name:= 'lb'+ IntToStr(i);

	ed:= TEdit.Create(Self);
	ed.Parent:= self;
	ed.Top:= 30+ (i* 26);
	ed.Left:= 135;
	ed.Width:= 325;
	ed.Name:= 'ed'+ IntToStr(i);
	ed.Text:= '';
	ed.OnChange:= TheEditChange;
	ed.OnEnter:= TheEditEnter;
	ed.OnKeyPress:= TheEditKeyPress;
	ed.OnKeyDown:= TheEditKeyDown;
  end;
  btOk.Left:= 170;
  btOk.Top:= 35+ (CounterMob* 26);
  btCancel.Left:= 255;
  btCancel.Top:= 35+ (CounterMob* 26);
end;

procedure TfmDifferentSMS.btOKClick(Sender: TObject);
var
  i: Integer;
  tmp: String;
  CorrectCounterMessage: Integer;
begin
  for i:= 0 to 99 do
	Msg:= '';
  CounterMsg:= 0;
  CorrectCounterMessage:= 0;
  for i:= 0 to CounterMob- 1 do
  begin
	tmp:= (FindComponent('ed'+ inttostr(i)) as TEdit).Text;
	if tmp= '' then
	begin
   //any thing
	end;
  end; //for
  if CorrectCounterMessage > 100 then
  begin
	MessageDlg('You can send 100 messages maximum!'#13'Every one 43 char(s) maximum!', mtError, [mbOK], 0);
	Exit;
  end;
  if MessageBox(fmDifferentSMS.Handle, PChar('You will send '+ inttostr(CorrectCounterMessage)+ ' message(s) to different mobile(s) number.'), 'Confirmation', MB_OKCANCEL)= ID_CANCEL then
	Exit;
  Close; 
end;

procedure TfmDifferentSMS.btCancelClick(Sender: TObject);
var
  i: integer;
begin
  for i:= 0 to 99 do
	Msg:= '';
  Close;
end;

procedure TfmDifferentSMS.FormShow(Sender: TObject);
begin
  (FindComponent('ed0') as TEdit).SetFocus; //لاحظ هذا
end;

procedure TfmDifferentSMS.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
var
  i: integer;
begin
  if (Sender as TForm).Name <> 'fmDifferentSMS' then
	for i:= 0 to 99 do
	  Msg:= '';
  CanClose:= true;	
end;

procedure TfmDifferentSMS.FormKeyPress(Sender: TObject; var Key: Char);
begin
  if Key= #27 then
	Key:= #0;
end;

end.

هل الطريقتان بينهما اختلاف من ناحية ادارة الذاكرة؟؟؟؟

ان كان لا فانا افضل الطريقة الاولى!!!!

ارجو ممن لديه الخبرة الادلاء برايه

وسؤال على الهامش لماذ عند صنع برنامج فقط فورم اي افتح الدلفي ثم اضغط اف 9 ساجد ان حجم تالبرنامج بالذاكرة من البروسس حوالي 3 ميغا !!! وهو ضخم جدا جدا

كيف اخفف الحجم بالذاكرة ؟؟؟

ان كان يحتاج تفصيل ممكن وضعه بمشاركة مستقلة لتعم الفائدة

وشكرا لكم مقدما

#2

بالنسبة لحجم الذاكرة المحجوز فهو ثابت في الطريقة الأولى عند إنشاء النافذة يتم حجز ذاكرة كبيرة نسبيا وذلك لوجود 100 Label & Edit

أما في الطريقة الثانية فأنت تحجز ذاكرة بقدر ما تحتاج إليه ويختلف حجم الذاكرة التي يتم حجزها كل مرة تنشأ بها النافذة تبعا لعدد Label & Edit

وشخصيا أرى الطريقة الثانية أسهل خاصة إذا أردت التعديل في المستقبل فتكون أساسا تتعامل بشكل ديناميكي مع النافذة

بإمكانك استعراض المشاركة التالية حيث تم الحديث فيها عن حجوم تطبيقات Delphi أيضا

أصغر برنامج على الإطلاق مكتوب بدلفي

تم تعديل هذه المشاركة بواسطة fh_feras في 26 يوليو 2006 في 04:13

#3

شكرا لك اخي الكريم

لكن انا مستغرب هل الكائنات الصغيرة مثل الزر والادت والليبل تاخذ حجما في الرام؟؟؟

المشكلة هي اني لا استطيع التجريب ؟؟

فنفس التطبيق وليكن فارغا اي افتح الدلفي ثم اف 9 كل مرة له حجم بالرام

طبعا يختنلف بالكيلوات

فاذا كان كذلك لا استطيع التاكد ان الاديت كم ياخذ حجما!!!!

على كل شكراجزيلا لك على تجاوبك وساقرا المشاركة التي اشرت لها

#4

اخي الكريم

الموضوع اللي اشرت له مشوق جدا

لكن انا لا اتحدث عن حجم البرنامج على الهارد وانما على الرام

اصغر برنامج بالمشاركات كان 750بايت تقريبا

اما على الرام فكان حوالي 2 ميغا!!!!!!!!

حجم الرام هو ما يهمني

شي جميل البرنامج يكون صغير على العارد لكن مادام البرنامج اقل من واحد ميغا فهو مقبول عند جميع الناس

المشاركة التي اشرت لها هي للتحدي فقط او ممكن لاستعمال اهكر اما بالشكل الطبيعي اصلا المستخدم يخاف من هيك برامج صغيرة جدا !!!

#5

الحجم التي يتم حجزه للتطبيق في الذاكرة قصة طويلة

ولكن حجم 2MB يعتبر حجم صغير في الذاكرة كما أن العناصر الموجودة لا تأثر على حجم الذاكرة المحجوزة بشكل أساسي بل ما تحويه هذه العناصر كأن يكون لديك Memo فيه نص بحجم 2MB عندها سيصبح حجم برنامجك في الذاكرة هو 4MB

#6

السلام عليكم ورحمة الله وبركاته

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

بالطريقة الثانية كما رايت انك قمت بخلق نموزج وقت التصميم الى هنا كما في الطريقة الاولى

ومن ثم قمت باضافة الاجراء function ShowStatus

لاحظ معي صديقي ان نوع المتحولات هي من نوع integer ان هذا النوع من المتحولات ذي الحجم 6 بايت قد تم حجزه سواء تم استخدام هذه المساحة ام لا وانت بما انك لن تستخدم اكثر من الرقم 100 فانصحك باستخدام النوع Char ...؟؟؟

ومن ثم قمت باسناد الاسماء والى ماهنالك

انا برايي ان الاختلاف في التعامل مع الرام والفرق هو لاشيء يذكر او يستحق كل هذا العناء لان هذه الامور تمت كتابتها في تصميم الايديت مثلا بدقة وعناية مرة واحدة

انت هنا لم تقم غير بخلق صفوف جديدة عن الاولى ولم تقم باضافة اي شيء على تلك الصفوف اي انك لم بتطويرها او تعديلها وهذا الامر الدلفي تقدمة لك بنقرة من زر الماوس وتقوم بدلا عنك بالتعريف والاشتقاق المطلوب

ان مااردت قولهان لغات البرمجة الحديثة من احد اهم اهدافها كتابة البرامج بايسر الطرق وبافضل استخدام للذاكرة وهنا مادام لدينا الطريقة الاولى اليسيرة فلما لانستخدما طبعا بخلاف البرامج العملاقة( وانا بصراحة اشك ان في الوطن العربي كله تم تصميم احد البرامج العملاقة بمعناها الكامل) عندها يتم برمجتها يدويا اي تركيبيا واحيانا يتم الاستعانة برقعات الايسمبلي للوصول لافضل اداء وافضل ادارة للذاكرة

سؤال اخير انت واثناء تجربتك للطريقتين بامكانك مراقبة الذاكرة رام من نافذة ادارة المهمات شغل البرنامج الاول وانظر الحجم المستهلك ومن ثم شغل البرنامج الثاني واختر اولا 1 عددا للمراد خلقه وراقب ومن ثم اختر 99 وابلغنا ماالنتائج وانا بانتظار ردك اخي الكريم

ملاحظة : هذا عبارة عن رايي شخصي بحت

اما اخي الكريم ان اردت ان تعرف الطريقة التي تتم بها الامور والاداء في الذاكرة فاقول لك ببساطة اقرأ البرنامج وستعرف 90 بالمائة من الاجابة

اصحيح ان العرب في هذه الحياة.......هذا بالاسم فقط

لالالالابالاحلام ....او..لاكمال العدد؟؟؟؟؟؟

#7

شكرا اخي fh_feras وكلامك فعلا في محله

وشكرا جزيلا اخي زاهر سعيد على التوضيح وارى انك معي في اختيار الطريقة الاولى!!! ;)

لكن كانك لم تنتبه الى امر ما!!!!!

ان لاحظت اني في الطريقتين انشء الفورم الثانوي وقت ما احتاجه وعند اغلاقه احرره من الذاكرة اي ليس عند اقلاع البرنامج!!!

اذا ما يهمني هو طريقة وضع او خلق العناصر داخل الفورم هل تؤثر على الاداء او الذاكرة!!!؟؟؟ وهذا ما اختلف في الطريقتين

والسؤال الاهم هو انني عند تحرير الفورم فاتوقع ان العناصر الداخلية تتحرر بالتاكيد وليس من المعقول ان احررها يدويا!!

اما طلبك ان اراقب الحجم فانا اسلفت ان ذلك صعب لان كل تشغيل للبرنامج (نفسه تماما ) يعطي حجم مختلف بفارق يصل لـ 200 كيلو تقريبا!!!

فصعب المراقبة

#8

إن تعامل Delphi مع أمور حجز وتحرير الذاكرة مريح نوعا ما

بالنسبة لتحرير العناصر التي كنت قد أنشأتها فإنه وبتحرير النافذة (والتي هي ستكون Owner للعناصر المنشأة) فإنها ستحرر من الذاكرة

كما أن Garbage Collector سيقوم بتحرير أي عناصر موجودة وفي الذاكرة ولم يعد هناك أي مؤشر عليها

#9

شِكرا اخي على الاجابة

هذا الموضوع مغلق.

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…