آلة حاسبة بسيطة بالدلفي
#1
السلام عليكم

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

نبدأ بسم الله
سوف نستعمل دلفي 2006
1- مبادئ الحساب:
[INDENT]- عملية الإدخال ستكون متسلسلة أي رقم يليه رقم أو عملية.

- الأرقام من نوع العدد الصحيح.
- حيز الكتابة (ظهور الأرقام) لا يقبل سوى الأرقام الطبيعية (0..9) ، الفاصلة و مؤشر العدد السالب
- العمليات هي الجمع، الطرح، الضرب، القسمة و النتيجة[/INDENT]

2- الخوارزمية:
[INDENT]- تهيئة (initialisation) الأرقام تكون العدد 0 (صفر)
- إدخال الرقم عبارة عن الحرف السابق متبوع بالحرف الجديد.
- العمليات عبارة عن متغير حيث (القسمة: 1، الضرب: 2، الطرح: 3، الجمع: 4)[/INDENT]

3- تصميم الشكل الخارجي:
- إقلاع الدلفي 2006
- إنشاء برنامج جديد (win32)
كود :
http://up103.arabsh.com/files/b2vffuhcexlp562q4z6v.gif

- ثم بعد ظهور form نعدل على قياساتها كالأتي:
Height: 225
Width: 260
Caption: (حسب اللغة المرادة) مثلا Calculatrice
كود :
http://up103.arabsh.com/files/zs5es7ehpe8xumscrde3.gif
- نذهب إلى لوحة الأدوات (Tool Palette) و نختار Standard -> TEdit
نعدل على قياساتها كالأتي:
Left : 10
Top : 10
Width : 230
BiDiMode : bdRightToLeft
Text : نمحي الكتابة الموجودة
كود :
http://up103.arabsh.com/files/wupt1d0wlmx5dxirx4s2.gif
- الآن نقوم بإضافة الأزرار
هناك خدعة () في الدلفي بحيث تكفي نقرة واحدة بالفأرة لإضافة مكوِّن بعدد ما نريد. وهي الضغط على Shift و النقر على المكون في الوقت نفسه.
أو – بكل بساطة - ننقر على المكون TButton ثم نذهب إلى الواجهة form وننقر بالفأرة مرة واحدة بحيث نحصل عل الأتي:
كود :
http://up103.arabsh.com/files/qqealkmdezxbml7x0slx.gif

الآن نعدل على قياسات الزر:
Left : 10
Top : 35
Width : 32
Height: 32
Caption : نمحي الكتابة الموجودة
ثم نقوم بنسخ الزر (ctrl+c) أو النقر بالزر الأيمن ثم Edit ثم copy
بعدها ننسخ (17 مرة)
يتبع ..


الملفات المرفقة
.zip   Project.zip (الحجم : 245.22 ك ب / التحميلات : 1,759)
.pdf   Calc.pdf (الحجم : 561.9 ك ب / التحميلات : 1,825)
الرد
#2
بسم الله الرحمن الرحيم

بارك الله فيك اخي مروان
تصدق كنت اكتب درس مشابه لكن باختلافات صغيرة
استحدمت دلفي7 بدلا من 2006
استعملت TLabel بدلا من TEdit
ولم استخدم الخاصية Tag ولم اغير اسماء الازرار
اختلاف تام في الزر +/- وزر القاصلة وطريقة الحساب...
وتفاصيا اخرى صغيرة
...
لكن نفس الفكرة في استخدام Sender واجرائية واحدة لكل ازرار الارقام

بانتظار درس مقبل
والسلام عليكم ورحمة الله
الرد
#3
كود :
http://up102.arabsh.com/my/9d62eab.png
في الأخير نحصل على ما يلي:
كود :
http://up102.arabsh.com/my/34cb54b.gif
لاحظ أننا قد غيرنا في قياسات زرين هما C و =
C: Width: 70 =: Height: 70
الآن انتهينا من الواجهة و سننتقل إلى البرمجة.
ننقر على Code في الأسفل أو بكل بساطة F12

نعود قليلا إلى الواجهة F12
ننقر مرتين على 0 (B0) فنحصل على
كود :
http://up103.arabsh.com/files/hx0cltdw259slza9prfe.jpg
سأتوقف قليلا للشرح بسيط في البرمجة غرضية التوجه
في البرمجة العادية للتطبيق المثال الآلة الحاسبة سوف نقوم بكتابة شفرة لكل زر ذات رقم
أي للزر 0 سنكتب
كود :
procedure TForm1.B0Click(Sender: TObject) ; begin Edit1.Text := Edit1.Text + ‘0’ ; end;
لكن في البرمجة غرضية التوجه سوف نقوم بكتابة إجراء (procedure) واحد بحيث يقوم بعمل 10 أزرار باستغلال (Sender : TObject) الظاهر في الإجراء حيث خانة الكتابة Edit1 سوف تجمع الكتابة السابقة لها و تعبير الزر (caption) أي

كود :
Edit1.Text := Edit1.Text + (Sender as TButton).Caption

وهذا السطر سيكون في الإجراء السابق ويعبر عن كل الأزرار حين النقر عليها، أي

B1 : OnClick : B0Click
B2 : OnClick : B0Click
B3 : OnClick : B0Click
…
B8 : OnClick : B0Click
B9 : OnClick : B0Click
و سنحصل على:
كود :
http://up103.arabsh.com/files/d3dh6k6nbpyuqpoq0d9h.jpg
ثم نذهب بالنسبة لكل زر من 1 حتى 9 إلى Event ونختار من قائمة الخاصة بـ OnClick الإجراء B0Click
كود :
http://up103.arabsh.com/files/oympimuxxq712r9tr5wz.jpg

الآن تذهب إلى الزر c ، ننقر عليه مرتين ونكتب الكود التالي:
كود :
Edit1.Text := '0'
بالنسبة لزر المؤشر SIGNAL ننقر مرتين عليه ثم نكتب الكود :
كود :
Edit1.Text := FloatToStr(- StrToFloat(Edit1.Text))
FloatToStr: تحول العدد الصحيح Float إلى متغير كتابي String

StrToFloat: تحول متغير كتابي String إلى العدد الصحيح Float
ننتقل الآن إلى العمليات
نصعد في الكود حتى نجد
كود :
var Form1: TForm1;
نضيف المتغير Operation وإذا أردنا أن نحدد عملية الجمع كعملية أساسية عندما لا يحدد المستعمل ماذا يريد يصبح لدينا

كود :
var Form1: TForm1; Operation : Integer = 4 ;


الآن ننقر مرتين على الزر / أو BDiv و نكتب الكود :
إذا كان Edit1.Text غير فارغ إذاً n1 تأخذ قيمة Edit1.Text على شكل عدد صحيح
Operation تأخذ قيمة Tag الخاص بزر العملية المختارة

Edit1 تصبح فارغة
كود :
If Edit1.Text <>'' Then n1 := StrToFloat(Edit1.Text) ; Operation := (Sender as TButton).Tag ; Edit1.Clear ;
ثم بالنسبة لأزرار *، -، + نذهب إلى Event ونختار من قائمة الخاصة بـ OnClick الإجراء BivClick
أما الزر الفاصلة ننقر مرتين على BVer ثم نضع الكود:

كود :
Edit1.Text := Edit1.Text + DecimalSeparator;

حتى الآن لقد قمنا بالعمل البسيط، ولكي نواصل لا بد من إنشاء متغيرين صحيحين n1 و n2
بعد Var
كود :
var Form1: TForm1; Operation : Integer = 4 ; N1 : Real = 0 ; N2 : Real = 0 ;

نلاحظ "=0" وهي توجه المصنف compiler أنه عند إنشاء المتغيرين أعطهم العدد 0، وبهذا سيكون لدينا n1=0 و n2=0 في البداية
الآن النتيجة:

الإجراء كما يلي:
إذا كانت قيمة edit1.Text فارغة إذاَ Edit1.Text تأخذ القيمة '0'
N2 تأخذ قيمة Edit1.Text على شكل عدد صحيح
حالة Operation من

[INDENT]1: إذا كانت قيمة n1 و n2 تساويان الصفر إذاَ[/INDENT]

[INDENT][INDENT]أظهر نافذة خطأ تحتوي على الرسالة 'نتيجة العملية غير محددة'

خروج من الإجراء[/INDENT][/INDENT]

[INDENT]وإلا إذا كانت قيمة n2 تساوي الصفر إذاَ[/INDENT]

[INDENT] أظهر نافذة خطأ تحتوي على الرسالة ' القسمة على الصفر مستحيلة '

خروج من الإجراء

وإلا النتيجة = n1 /n2[/INDENT]

[INDENT] 2: النتيجة = n1 ×n2

3: النتيجة = n1 -n2

4: النتيجة = n1 +n2
[/INDENT]
نهاية الحالة

Edit1.Text تأخذ قيمة النتيجة على شكل كتابة

كود :
procedure TForm1.BEgalClick(Sender: TObject); begin if Edit1.Text = '' Then Edit1.Text := '0'; n2 := StrToFloat(Edit1.Text); Case Operation of 1 : begin if (n1 = 0) and (n2 = 0) then begin messagedlg('نتيجة العملية غير محددة',mtError,[mbOk],-1); exit end else if n2 = 0 then begin messagedlg('القسمة على الصفر مستحيلة',mtError,[mbOk],-1); exit end else Resultat := n1/n2; end; 2 : Resultat := n1*n2; 3 : Resultat := n1-n2; 4 : Resultat := n1+n2; end; Edit1.Text := FloatToStr(Resultat); end;

الآن البرمجة عندما يدخل المستعمل الأرقام عبر لوحة المفاتيح:

للتحكم في إدخال لوحة المفاتيح هناك إجراء يساعدنا للمزيد أنظر

http://www.delphi4arab.net/forum/showthread.php?tid=5



ننقر على Form1 مرة واحدة ثم نذهب إلى Event و بالتحديد OnKeyPress ثم ننقر مرتين على الخانة المواجهة

نكتب الكود التالي:

كود :
if key in ['+','-','*','/'] then begin if key = '+' then BOper(BAdd) else if key = '-' then BOper(BDiff) else if key = '*' then BOper(BMult) else if key = '/' then BOper(BQuot); Key := #0; exit; end; if Key in ['=', #13] then begin BEgaleClick(BEgale); Key := #0; exit; end; if key in ['.',','] then begin key := DecimalSeparator; end; if not (Key in [#8, '0'..'9', DecimalSeparator]) then Key := #0;
في الأخير ننقر مرة واحدة على الواجهة Form ثم نتوجه إلى Properties عند BorderIcons نعطي لـ biMaxisimize القيمة False
ملاحظة: البرنامج غير كامل على القراء بعد التطبيق إكتشاف الأخطاء سواء من الناحية البرمجية أو من ناحية عمله في نظام التشغيل
وأرحب بكل التعليقات

تحياتي
الرد
#4
السلام عليكم

تصحيحا للأخطاء

سهوا

إقتباس :ثم بالنسبة لأزرار *، -، + نذهب إلى Event ونختار من قائمة الخاصة بـ OnClick الإجراء BivClick

ثم بالنسبة لأزرار *، -، + نذهب إلى Event ونختار من قائمة الخاصة بـ OnClick الإجراء BDivClick

هنا كنت برمجت بإنشاء إجراء BOper
لكن للتسهيل حافظت على BDivClick


كود :
if key in ['+','-','*','/'] then begin if key = '+' then BOper(BAdd) else if key = '-' then BOper(BDiff) else if key = '*' then BOper(BMult) else if key = '/' then BOper(BQuot); Key := #0; exit; end; if Key in ['=', #13] then begin BEgaleClick(BEgale); Key := #0; exit; end; if key in ['.',','] then begin key := DecimalSeparator; end; if not (Key in [#8, '0'..'9', DecimalSeparator]) then Key := #0;


التصحيح

كود :
if key in ['+','-','*','/'] then begin if key = '+' then BDivClick(BAdd) else if key = '-' then BDivClick(BDiff) else if key = '*' then BDivClick(BMult) else if key = '/' then BDivClick(BDiv); Key := #0; exit; end; if Key in ['=', #13] then begin BEgaleClick(BEgale); Key := #0; exit; end; if key in ['.',','] then begin key := DecimalSeparator; end; if not (Key in [#8, '0'..'9', DecimalSeparator]) then Key := #0;

فعذرا
Smile
الرد
#5
DeltaAziz كتب :
تصدق كنت اكتب درس مشابه لكن باختلافات صغيرة

وفيك بركة أخي DeltaAziz
أود أن تضع درسك لأنك والظاهر أكثر تجربة مني في مجال الشروحات
وأيضا لكي نتعلم منك ومن خبرتك

تقبل تحياتي Smile
الرد
#6
الف شكر اخ مروان على الشرح الاكثر من رائع
اتضحت لي الكثير من الامور بعد درسك والحمد لله
كنت قد برمجة الة حاسبة لكن اغلب اكوادها كان بالباسكال Rolleyes
شكرا شكرا مرة اخرى
الرد
#7
شكرا على الدرس الرائع

فقط عندي ملاحظة

الآلة الحاسبة تجمع بين عددين فقط

وهذه المشكلة حصلت معي

لو وضعنا مثلا 3+3+3

ستعطيك النتيجة 6

لأنها مبرمجة لحساب n1 و n2 فقط

يا ريت لو تطور الآلة الحاسبة أكثر

جزاكم الله خيرا
الرد
#8
إقتباس :لو وضعنا مثلا 3+3+3
ستعطيك النتيجة 6
يا ريت لو تطور الآلة الحاسبة أكثر
السلام عليكم ورحمة الله
هذا درس للانطلاق وليس برنامج كامل
على المتلقي التفكير بنفسه بالتكملة
ان واجهتك مشكلة يمكنك طرح سؤال بقسم الاسئلة
الرد
#9
الأخ nabilsoft مرحبا بك في المنتدى
هنا تجد آلة حاسبة تكاد تكون (تقريبا) مكتملة:
http://www.delphi4arab.net/forum/showpos...stcount=13
اللهم احقن دماء المسلمين، لا تنسوهم بالدعاء...
الرد
#10
و عليكم السلام و رحمة الله و بركاته
شكرا لك اخي على الدرس و السورس
و الله البراحة كنت فكرت في عمل مثل هذة الحاسبة
و صممت الواجهة تقريبا بنفس هذا المثال قلت ساجرب
نفسي مع ابسط شيء لاتعلم لكن عندما و صلت الى الاكواد
حصلت شوي مع اني مبتدئ
الحمد لله وجدت هذا الموضوع استفدت منك كثيرا بارك الله فيك
و يزيدك علم على علم . تحية لك اخي العزيز
الرد


التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم