احمد غريب

فهم البرمجه من الاساس

58 ردود في هذا الموضوع

بسم الله الرحمن الرحيم

السلام عليكم

قد يبدو للوهله الاولى من عنوان الموضع انه موضوع عام عن البرمجه, ولكن هدفى هو ان يبداء الموضوع كموضوع عام ثم ينتهى بنا الى التطرق ومن ثم فهم برمجه الاسمبلى.

الذى لاحظته من اكثر المبرمجمين هو انهم ينهمكون فى فهم تفاصيل اللغه وينسون الهدف الاساسى وهو البرمجه.

دعونا نبداء فى تعريف البرمجه :

البرمجه بكل بساطه هى مخزون من المعلومات DATA , وعدد من الاوامر INSTRUCTIONS. قد يستغرب البعض هل هذه هى كل البرمجه, اقول نعم البرمجه ليست إلى مجموعه من المعلومات و الاوامر.

دعونا الان ناتى بمثال من الحياة العامه:

نفترض ان لديك قاموس وتريد ان تعرف معنى كلمة خوارزميه, ماذا تفعل ؟؟

هل تفتح القاموس من حرف الالف ثم تمر بجميع الكلمات الموجوده تحت الالف ثم الباء وهكذا؟. بالتاكيد لا, لانك تعلم ان كلمة خوارزميه تندرج تحت حرف الخاء, ولذالك ستقفز مباشرة الى حرف الخاء ثم فى الخاء ستقفز إلى حرف الواو وهكذا إلى إن تصل إلى الكلمه المنشوده.

مثال اخر:

نفترض ان هناك رساله موجهه للشخص التالى :

محمد على

شارع الجيزه 9, ميدان الجامع

مصر الجديده, القاهره

جمهورية مصر العربيه

الان هل نبداء البحث عن شخص إسمه محمد على ؟ هل نرسل الرساله إلى جميع دول العالم, وكل دوله تعرض الرساله على كل شخص اسمه يوافق إسم المرسل إليه ؟

بالتاكيد لا , لابد ان نحصر البحث على دولة مصر اولاً ثم القاهره وهكذا, وإلى ما الداعى لكتابة العنوان بهذا الشكل.

ما دخل كل هذا بالبرمجه ؟ قد يتسائل البعض, اقول البرمجه ما هى إلى معلومات مخزنه فى ذاكرة الجهاز وباصدار بعض الاوامر تحصل على هذه المعلومات.

دعنى اعطيك مثال على ذالك :

فهم البرمجه من الاساس

منتدى مبرمجي لغة الآلة (التجميع) Assembly

منتديات لغات البرمجة العام

منتديات الفريق العربي للبرمجة

http://www.arabteam2000-forum.com/

هذا هو عنوان الموضوع, كيف يتم البحث عنه فى الانترنت ؟

عندما تنقر على رابط معين يرسل الرابط الطلب إلى http://www.arabteam2000-forum.com/. بعد ذالك يقوم المنتدى بالبحث فى قسم البرمجه العامه عن قسم الاسمبلى و من ثم يبحث عن الموضوع تحت حرف الفاء وهكذا.

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

فى البرمجه هناك ما يسمى الرابط HANDLE او Addres او offset او Pointer كلها تحمل تقريباً نفس المعنى, وهو عنوان المعلومه فى الذاكره , على سبيل المثال النوافذ windows والتى تظهر امامك على الشاشه هى عباره عن معلومات مخزنه فى الذاكره, كل نافذه لها عنوان يسمى Handle, فى الذاكره تجد معلومات عن هذه النافذه مثل حجم النافذه, لون النافذه الخ...

بمساعدة ال handle تستطيع الوصول إلى النافذه فى ذاكرة الجهاز ومن ثم تغير اللون او الحجم او حتى شكل النافذه.

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

دعونا نعطى مثال من الحياة العامه:

لنفرض انك تريد ان تستورد اجهزة تصوير رقميه من اليابان وهناك ملحق تجارى لليابان فى المدينه التى تسكنها, سيقوم الملحق التجارى بإعطائك اسماء وعناوين الشركات التى تصنع الاجهزه, هل توصلت إلى الشركه ؟ باطبع لا, انت توصلت إلى إسم وعنوان الشركه, والان عليك ان تتصل بالشركه للاتفاق معها.

إذا نستطيع ان نقول ان العنوان الاول -الملحق التجارى- هو عباره عن مصدر عناوين للشركات التى نريد ان نصل إليها, او عنوان للعناوين التى نريد ان نصل إليها.

هذه الطريقه متبعه فى كل انواع البرمجه, بعض الغات تسميها link , والبعض الاخر يسميها handle , pointer , offset , reference ولكن فى النهايه هى عناوين فى ذاكره جهازك او الجهاز الذى تتصل به عن طريق الشبكه.

الخلاصه :

البرمجه هى مخزون من المعلومات و التى نستطيع الحصول على عناوينها بطريقه او باخرى, ومجموعه من الاوامر تطبق على هذه المعلومات لتعطينا النتيجه المرجوه.

ما كان من توفيق فمن الله عز وجل وما كان من خطاء او نسيان من نفسى ومن الشيطان والله ولى التوفيق.

والسلام

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

فى المره السابقه ذكرنا ال handle او ال offset والتى تعنى تقريباً نفس الشئ, وقلنا انها مجرد عناوين فى ذاكرة الجهاز. هذه هى من اكبر المشاكل التى تواجه المبرمجين, فنلاحظ مثلاً ان مبرمج السى يشتكى من ال pointer و ال reference فى حين ان مبرمج ال pascal يشتكى من ال var ومبرمج الاسمبلى يشتكى من ال offset الخ..

فى واقع الامر المسئله بسيطه للغايه, ولكن إنهماك المبرمج فى فهم التقنيه وإهمال جانب الفهم العام للبرمجه وللد عنده هذه المشكله, دعونا نعطى مثال على ما ذكر ولكن قبل ان ابداء المثال دعونى اذكركم ان التركيز ليس على التقنيات بقدر ما هو على المفهوم العام.

كلنا يعرف الرسائل فى الوندوز, رسائل الخطاء و رسائل التنبيه ورسائل التحذير ورسائل المعلومات الخ...

رسائل المعلومات تكون على شكل مربع وفيه نص معين وزرار عليه OK.

كل هذه الرسائل هى عباره عن برامج جاهزه فى الوندوز تقوم بستدعائها من برنامجك, وانت الذى تحدد محتوى الرساله.

.data
MsgCaption      db "اول برنامج اسمبلى",0
MsgBoxText      db "الاسمبلى لغه شيقه",0

.code
start:
invoke MessageBox, NULL,addr MsgBoxText, addr MsgCaption, MB_OK
invoke ExitProcess,NULL
end start

نلاحظ فى البرنامج انه منقسم إلى قسمين, قسم اسمه data - مخزن المعلومات-, والقسم الاخر code -اوامر- وهذا ما ذكرناه من قبل.

فى مخزن المعلومات لدينا رسالتين, الرساله الاولى عنوانها MasgCaption وتحتوى على النص -اول برنامج اسمبلى-, بينما الرساله الثانيه عنوانها MsgBoxText وتحتوى على النص -الاسمبلى لغه شيقه-, إذاً إذا اردنا معرفه محتوى الرسله علينا ان نذهب الى عنوانها.

فى اغلب الاحيان البرامج الجاهزه فى الوندوز والتى تسمى API تطلب عناوين الرسائل او المعلومات التى نريد ان ندرجها فى برنامجنا, احد هذه ال API هو MessageBox والتى مهمتها هو إظهار رسائل الوندوز التى ذكرناها, وتكتب فى الاسمبلى على النحو التالى:

invoke MessageBox, NULL,addr MsgBoxText, addr MsgCaption, MB_OK

invike MessageBox تعنى إستدعى برنامج إظهار الرسائل, هذا البرنامج يطلب اربع معطيات, الخانه الاولى تريد عنوان مالك الرساله, وبما ان الرساله ليست جزء من برنامج وإنما هى البرنامج نفسه, إذاً ليس لدينا عنوان فنعطيها الداله NULL والتى تعنى لا عنوان.

الداله الثانيه هى راس الرساله والذى يظهر فى اعلى الصندوق, وبما اننا لن نرسل الرساله الاصليه وإنما سنرسل عنوانها, نضيف كلمه addr للدلاله على ان المرفق هو عنوان الرساله وليس الرساله الاصليه, على نفس المنوال نرسل عنوان محتوى الرساله.

الان نلاحظ ان MB_OK وتعنى اننا نريد رساله من نوع معلومات وزرار OK, لم نسبقها بكلمة addr, وذالك لان MB_OK ليس عنوان لرساله وإنما هى الرساله نفسها.

ارجو ان تكون الفكره واضحه, قد تبدو الطريقه معقده للوهلة الاولى ولكن هذه الطريقه متبعه فى جميع لغات البرمجه وليست مقتصره على الاسمبلى.

الخلاصه :

الفرق بين الداله وعنوان الداله يسبب الكثير من المشاكل حتى للمبرمج المتمكن, وذالك يرجع لعدم الفهم الصحيح فى الفرق بين الداله والعنوان. لذالك الفهم الصحيح للفرق بين الداله وعنوانها قد يجنبك الكثير من المشاكل فى طريقك لتعلم البرمجه.

ما كان من توفيق فمن الله عز وجل وما كان من خطاء او نسيان من نفسى ومن الشيطان والله ولى التوفيق.

والسلام

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

فى المره السابقه إنتهينا عند الداله وعنوانها, الان ارغب فى توضيح انواع الدوال, عناوين الدوال لها شكل ثابت وهو رقم يتكون من 32 بت.

الان بالنسبة للدوال فهوناك انواع كثيره من الدوال, الداله من الممكن ان تكون حرف واحد ومن الممكن ان تكون سلسله من الحروف كالتى مرت علينا فى المثال فى الدرس السابق.

ايضاً الداله يمكنها ان تكون من نوع structure وهذه ليست غريبه علينا فى حياتنا اليوميه, لناخذ مثال:

الاسم : احمد غريب

العنوان : شارع الجيزه 9 مصر الجديده , القاهره , مصر

رقم الهاتف : 777888212

كما نلاحط فهذه مجموعه من البيانات, ونستطيع ان نرى مثل هذه البيانات مجتمعه فى مكان واحد, وهو وحده من البيانات المرتبطه ببعضها, ومثل هذه البيانات تجدها على سبيل المثال فى دليل الهاتف, او فى سجل الموظفين فى شركة ما.

مثل هذه البيانات يحتفظ بها فى data base او من الممكن الاحتفاظ بها فى ملف text إذا كان عدد البيانات ليس بالكبير ولا يحتاج إلى قاعدة بيانات data base.

هذا كان مجرد مثال على كيفية حفظ المعلومات فى الجهاز, هناك الكثير من الطرق لحفظ المعلومات فى الجهاز مثل ال Array, linked list,double linked list, hash table كل هذه المصطلحات هى طريقه لحفظ المعلومات فى الجهاز بحيث يسهل عليك الوصول اليها.

بالطبع على المبرمج إختيار الطريقه المناسبه لحفظ المعلومات التى يريد إستخدامها فى برنامجه, فمثلاً إذا اراد ان يحفظ مجموعه من الارقام المحدوده لربما كانت طريقه الحفظ المناسبه هى ال Array, وإذا كان المراد حفظه هو عناوين لاشخاص مع ارقام الهواتف فطريقة Structure قد تكون هو الانسب.

ذكرت Structure بالذات لغرض فى نفسى الا وهو ربط النوافذ windows بالمعلومات المخزنه فى الجهاز عن النوافذ.

كما ذكرنا من قبل API هو عباره عن برامج جاهزه فى الوندوز, يقوم المبرمج بإستدعائها مع مجموعه من البيانات, والتى بدورها تحدد شكل و حجم النافذه.

لنتامل احد هذه البرامج الموجوده فى ال API ونقارنها بمثال قاعدة البيانات اعلاه.

typedef struct {
   UINT cbSize;
   UINT style;
   WNDPROC lpfnWndProc;
   int cbClsExtra;
   int cbWndExtra;
   HINSTANCE hInstance;
   HICON hIcon;
   HCURSOR hCursor;
   HBRUSH hbrBackground;
   LPCTSTR lpszMenuName;
   LPCTSTR lpszClassName;
   HICON hIconSm;
} WNDCLASSEX, *PWNDCLASSEX;

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

ليطمئن قلب القارئ اقول انه ليس هناك احد يحفظ كل هذه الاشياء المعقده, ولكن المطلوب هو كيف يصل المبرمج للمعلومه المنشوده بسرعه ويفهم كيف يستخدمها.

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

الخلاصه :

العنوان هو مجرد رقم يتكون من 32 بت, والمعلومات تحفظ بطرق مختلفه, حلاما عرفنا كيف خزنت المعلومه يسهل علينا التعامل معها. الاختيار الانسب لحفظ المعلومات فى الذاكره يسهل علينا الكثير عند التعامل معها.

ما كان من توفيق فمن الله عز وجل وما كان من خطاء او نسيان من نفسى ومن الشيطان والله ولى التوفيق.

والسلام

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

ألف شكر أخي أحمد على تبسيط الموضوع :)

ومنتظرين مواضيعك في المنتدى

-

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

اشكرك اخى jaas على المرور, واتعجب ان لا ارى اى تعليق من المبتدئين على الموضوع, فقد بدات الموضوع ليكون نواه للبدء فى تعلم برمجة الاسمبلى, انا لا انتظر الشكر و الثناء بقدر ما يسعدنى رؤية نقد بناء, واعلم يقيناً ان الاخ jaas غنى عن قراءة موضوع مبسط بهذا الشكل.

عموماً ساواصل شرح الدروس عسى ان ينفع الله بها احد ويدعو لى بالتوفيق.

كما وعدت فى المره السابقه سابداء بوضع النقاط على الحروف, وربط الشرح النظرى الذى قمنا به الى تطبيق عملى.

قبل ان ابداء بالشروع فى التطبيق العملى علينا ان نفهم تركيبة الكمبيوتر الداخليه.

الكمبيوتر يتكون من عقل -Processor- ووظيفته تنفيذ الاوامر, ومخزن للمعلومات وهو الذاكره -Ram memory- ومجموعه من الادوات -Preferalse- وتحت هذه المجموعه تندرج كل ما تراه من الجهاز مثل طابعه و شاشه الجهاز, وما لا تراه مثل وحدة التخزين -Hard disk- و كرت الشاشه -Geaphic card- الخ.

ال processor لديه ذاكره محدده يمكنه من خلالها الاحتفاظ بمجموعه من العناوين او المعطيات وهذه الذاكره تسمى -register- امثل eax ; ebx الخ

سؤعطيكم مثال على كيف يستخدم ال processor لهذه الذاكر والتى هو بمثابة متغيرات:

mov eax,5
mov ebx,6
add eax,ebx

فى هذا المثال البسيط نضع الرقم 5 فى register eax ثم نضع الرقم 6 فى register ebx, واخيراً نجمع الرقمين ونضع الناتج فى register eax.

من السهل على اى إنسان درس مبادئ الرياضيات ان يرى التشابه الكبير بين هذا البرنامج و ما يدرس فى المدارس الابتدئيه, دعونا نكتب البرنامج بالصيغه التى تدرس فى المدارس:

X1=5
X2=6
X3=X1+X2

ماهى قيمة X3 الان ؟ من الواضح ان قيمتها تساوى مجموع الرقمين السابقين, إذاً خلاصه القول هو ان ال Processor هو عقل الجهاز الذى يقوم بالعمليات الحسابيه والمنطقيه.

الذاكره لا تقوم باى عمل منطقى او حسابى, فمهمتها تقتصر على حفظ المعلومات فقط, فى درس سابق ذكرنا هذا المثال:

.data
MsgCaption      db "اول برنامج اسمبلى",0
MsgBoxText      db "الاسمبلى لغه شيقه",0

.code
start:
invoke MessageBox, NULL,addr MsgBoxText, addr MsgCaption, MB_OK
invoke ExitProcess,NULL
end start

نلاحظ القسم الاعلى من البرنامج والذى إسمه data هو عباره عن مجموعه من الاحرف, البروسسور ليس لديه الذاكره التى تستطيع ان تحفظ كل هذه الحروف - اول برنامج اسمبلى- لذالك يحتاج الوصول إليها عن طريق عنوانها فى الذاكره, وهنا ياتى دور العناوين addr, offset,Handle كما ذكرنا سابقاً هذه كلها مسميات لكلمة عنوان.

MsgCaption على سبيل المثال هو عنوان للنص الاول, إذا قمنا باعطاء ال Processor عنوان النص وطلبنا منه ان يطبع النص على الشاشه, يقوم ال processor باءحضار النص حرف حرف ومن ثم طباعته على الشاشه, هذه العمليه تكون سريعه جداً لذالك يهيئ لنا ان الطباعه تتم فى ان واحد.

الصور و الاصوات وحتى الافلام كلها معلومات مخزنه فى ذاكره الجهاز,يحصل ال Processor على عنوانها فى الذاكره ثم يقوم بإحضارها نقطه تلو الاخرى ويطبعها على الشاشه او حتى على الورق من خلال الطابعه.

الخلاصه :

ال Processor هو عقل الجهاز وله ذاكره محدوده جداً تستطيع حفظ العناوين وبعض المعطيات البسيطه, فى حين ان الذاكره -Ram memory- ذاكره تحفظ المعلومات و لا تستطيع القيام باى عمل حسابى او منطقى,

ما كان من توفيق فمن الله عز وجل وما كان من خطاء او نسيان من نفسى ومن الشيطان والله ولى التوفيق.

والسلام

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

الله يبارك فيك ياأحمد ,, اشتقنا لمداخلاتك الشيقة ,, وياريت تزورنا أكثر وأكثر في قسم السي++ ,,

واستمر ولاتهتم ,, فسيأتي اليوم الذي سيستفيد أحد الأعضاء من الموضوع باذن الله ,,

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

و الله أنا قرأت الموضوع عدا أخر ردين

باين إنك عم تحكي عن إسمبلي 32 بت يعمل تحت الوندوز

أنا حاليا أعمل على إسمبلي 16 تحت بيوس و الدوس

لما أعرف شوية شغلات فيه ممكن أنتقل للـ 32

لكن عندي شعور إني هفشل لأني عم أشتت ذهني

بين الإسبلي و السي + +

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

اخى DESIGEN انصحك بالتركيز على المواضيع التى بداتها, وعدم تشتيت جهودك فى مواضيع عديده. هذه الدروس باقيه إن شاء الله فى المنتدى, فحالما تشعر بالحاجه الى تعلمها يمكنك العوده إليها.

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

الاخ الحبيب HGB انا إن شاء الله معكم ولكن ارى ان قسم الاسمبلى 32 بت فى بعض القصور بالنسبه للمبتدئين, لذالك احببت ان اساهم فيه بقدر الامكان. وقسم السى ++ ما شاء الله فيه نشاط وانا اتعلم منكم الكثير, خاصة الاخ jaas الذى لم يدع لاحد مجال ما شاء الله عليه.

والسلام

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

نعود مره اخرى لنواصل الدروس, مارايكم فى ان نبداء فى تطبيق ما درسنا وكتابه برنامج يكون نواه لجميع الدروس القادمه إن شاء الله ؟

على بركة الله نبداء :

برامج الوندوس تقسم تحتوى على ثلاث اشياء, واجه المستخدم User Interface و اوامر Instructions و اخيراً بيانات Data.

فى هذا البرنامج نحتاج لعمل 3 ملفات ونسميها على النحو التالى

skeleton.asm
skeleton.inc
skeleton.rc
make.bat

سنقوم بكتابة البرنامج بالكامل على notepad, وبذالك لن نحتاج إلى اي برامج إضافيه سوى الكومبايلر masm32 و Resource Editor و linker . كل هذه الادوات متوفره فى masm32 والتى تم شرحها فى اماكن عديده على هذا المنتدى.

نبداء بالملحقات ونفترض اننا نريد ان نقوم بعمل 4 قوائم على النحو التالى , ملف ,صور , الوان , مساعده.

فى قائمة ملف نريد ان نكون فتح , حفظ و انواع

انواع تقسم إلى ثالثه انواع وهى نوع اول , نوع ثانى ونوع ثالث

فى قائمة صور نضيف صوره اولى, صوره ثانيه و صوره ثالثه

فى قائمة الوان لون اول, لون ثانى و لون ثالث

واخيراً فى قائمة مساعده نضيف عن البرنامج

كل هذا سنحفظه فى الملحقات resorces والتى سنكتبها فى الملف skeleton.rc على النحو التالى :

#include "c:\masm32\include\resource.h"

#define         MAINMENU            301

#define         MI_OPEN             101
#define         MI_SAVE             102
#define         MI_MENU11           103
#define         MI_MENU12           104
#define         MI_MENU13           105
#define         MI_MENU21           106
#define         MI_MENU22           107
#define         MI_MENU23           108
#define         MI_MENU31           109
#define         MI_MENU32           110
#define         MI_MENU33           111
#define         MI_MENU34           112
#define         MI_ABOUT            113

MAINMENU    MENU DISCARDABLE
BEGIN
   POPUP   "ملف"
   BEGIN
       MENUITEM "فتح", MI_OPEN
       MENUITEM "حفظ ", MI_SAVE
       POPUP "نوع"
       BEGIN
           MENUITEM "نوع اول", MI_MENU11
           MENUITEM "نوع ثانى", MI_MENU12
           MENUITEM "نوع ثالث", MI_MENU13
       END
   END
   POPUP "صور"
   BEGIN
       MENUITEM "صوره اولى", MI_MENU21
       MENUITEM "صوره ثانيه", MI_MENU22
       MENUITEM "صوره ثالثه", MI_MENU23
   END
   POPUP "الوان"
   BEGIN
       MENUITEM "لون اول", MI_MENU31
       MENUITEM "لون ثانى", MI_MENU32
       MENUITEM "لون ثالث", MI_MENU33
       MENUITEM "لون رابع", MI_MENU34
   END
   POPUP "مساعده"
   BEGIN
       MENUITEM "عن البرنامج", MI_ABOUT
   END
END

اول سطر هو ليمكننا من إستخدام التعبيرات مثل POPUP و MENUITEM الخ.

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

كلمة MENU هى نوع الملحق الذى نريد ان نقوم بعمله, لذالك نكتب على النحو التالى :

MAINMENU    MENU DISCARDABLE

والان بعدد ان حددنا نوع الملحق, نبدا بكلمة BEGIN فى بناء محتويات الملحق

كلمة POPUP تقوم بعمل عنوان القائمه وهى فى هذه الحاله كلمة ملف, ثم نقوم مره اخرى بعليه بدء لكن هذه المره داخل القائمه, وكل ما هو بين كلمة BEGIN و END الاولى, سيندرج تحت قائمة ملف.

بهذه الطريقه السهله يمكنك عمل قوائم لنافذتك, لاحظ ان كل محتويات القوائم تحمل الاسم الذى خصصناه لها فى البدايه, على سبيل المثال :

#define         MI_OPEN             101
...
       MENUITEM "فتح", MI_OPEN

ننتقل الان للملف الثانى وهو skeleton.inc هذا الملف هو ملف مساعده لا اكثر ولا اقل, نريد القيام بترجمة ما ادرجناه فى ملف الملحقات بحيث يتسنى للكمبايلر فهمه, لان ما كتبناه فى ملف المحقات كان بلغه السى. تعالو ننظر إلى محتويات الملف الثانى:

MAINMENU        equ 301

MI_OPEN         equ 101
MI_SAVE         equ 102
MI_MENU11       equ 103
MI_MENU12       equ 104
MI_MENU13       equ 105
MI_MENU21       equ 106
MI_MENU22       equ 107
MI_MENU23       equ 108
MI_MENU31       equ 109
MI_MENU32       equ 110
MI_MENU33       equ 111
MI_MENU34       equ 112
MI_ABOUT        equ 113

كما تلاحظون اعزائى تحويل الملحقات من لغة السى إلى الاسمبلى سهل جداً, كل ما تحتاج القيام به هو ترجمه بعض السطور مثال على ذالك

بالسى

#define         MI_OPEN             101

تصبح بالاسمبلى

MI_OPEN         equ 101

لاحظ ان كل ما ذكرناه يندرج تحت ما اسميناه بالقواعد data.

الان لننظر إلى محتويات الملف الثالث وهو skeleton.asm:

;===============================================================================
;START
;===============================================================================
.486
.model  flat, stdcall
option  casemap: none

includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\user32.lib

include  c:\masm32\include\kernel32.inc
include  c:\masm32\include\user32.inc

include  c:\masm32\include\windows.inc
include  resorces\skeleton.inc

WinMain  PROTO STDCALL :DWORD, :DWORD, :DWORD, :DWORD
WndProc  PROTO STDCALL :DWORD, :DWORD, :DWORD, :DWORD

;===============================================================================
;DATA
;===============================================================================

.data
AppName  db  "النواه",0
ClassName  db  "نواة الاسمبلى",0

.data?
hInstance  dd  ?
hMenu                   dd      ?
;===============================================================================
;CODE
;===============================================================================
.code
start:
invoke  GetModuleHandle, NULL
mov  hInstance, eax

       invoke  WinMain, hInstance, NULL, NULL, SW_SHOWNORMAL
invoke  ExitProcess,eax

;-----------------------------------------------------------------
; WinMain
;-----------------------------------------------------------------
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
mov    wc.cbSize,SIZEOF WNDCLASSEX
mov    wc.style, CS_HREDRAW or CS_VREDRAW
mov    wc.lpfnWndProc, OFFSET WndProc
mov    wc.cbClsExtra,NULL
mov    wc.cbWndExtra,NULL
push  hInstance
pop    wc.hInstance
mov    wc.hbrBackground,COLOR_WINDOW
mov    wc.lpszMenuName, NULL
mov    wc.lpszClassName,OFFSET ClassName
mov    wc.hIcon, 0
mov    wc.hIconSm, 0
invoke  LoadCursor,NULL,IDC_ARROW
mov    wc.hCursor,eax
invoke  RegisterClassEx, addr wc
invoke  LoadMenu, hInstance, MAINMENU;load menu
   mov     hMenu, eax                   ;store handle

INVOKE  CreateWindowEx,WS_EX_LAYOUTRTL,ADDR ClassName,ADDR AppName,\
           WS_OVERLAPPEDWINDOW-WS_MAXIMIZEBOX-WS_SIZEBOX,\
           CW_USEDEFAULT, CW_USEDEFAULT,258,350,NULL,hMenu,\
           hInst,NULL
mov    hwnd,eax
invoke  ShowWindow, hwnd, CmdShow
invoke  UpdateWindow, hwnd
.WHILE  TRUE
 invoke  GetMessage, ADDR msg,NULL,0,0
 .BREAK  .IF (!eax)
 invoke  TranslateMessage, ADDR msg
 invoke  DispatchMessage, ADDR msg
.ENDW
mov     eax,msg.wParam
ret
WinMain endp

;-----------------------------------------------------------------
; Window procedure
;-----------------------------------------------------------------
WndProc proc hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
mov eax, uMsg

.IF eax==WM_DESTROY
 invoke PostQuitMessage, NULL
.ELSE
 invoke  DefWindowProc,hWnd,uMsg,wParam,lParam  
 ret
.ENDIF
ret
WndProc endp



end start

قمت بتقسم البرنامج إلى ثلاث فقرات الاولى START وهى الفقره التى تحتوى على نوع المعالج والمكتبات التى نريد ان نستخدمها فى البرنامج, بالاضافه إلى اسماء الوصلات Procedures التى ننوى إدراجها فى برنامجنا لاحقاً.

الفقره الثانيه هى قسم المتغيرات والتى تندرج تحت قائمة البيانات, والتى تنقسم إلى قسمين, قسم للبيانات التى نعطيها قيمه قبل عمل البرنامج وقسم يعطى قيمه لاحقاً اثناء عمل البرنامج و يوضع له علامة إستفهام بدل القيمه.

القسم الاخير هو قسم الاوامر instructions إذا حصلت على عدد كافى من المهتمين ساقوم بإكمال الشرح, ارجو المشاركه وإبداء الراى, اريد ايضاً إقتراحات لبرامج نقوم بكتابتها كما ارجو ان يتبرع احد لعمل ايقونه للبرنامج و ايقونات للقوائم.

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

ما كان من توفيق فمن الله عز وجل وما كان من خطاء او نسيان فمن نفسى ومن الشيطان والله ولى التوفيق.

والسلام

skeleton.zip

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

أخ أحمد

فقط سؤال بسيط

أذا كان عندي مشاريع مجهزه للغة الأسمبلي أغلبها (16بت اسمبلى)

فقط أريد أن أعرف من أي يبدأ هذا المشروع حين تشغيله ومن أين ينتهي

بمعنى في الدلفي مثلا هناك أحداث معينه تتحكم بالبرنامج

حدث تشغيل حدث ظهور حدث إغلاق

ماذا عن هذه اللغه

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

(كل اللى أشوفه أكواد ورموز وأشياء مبهمه)

وأرجوا أن تواصل الدروس

شكرا

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

حياك الله اخى دلفى وانا سعيد جداً بمشاركتك.

فى لغه الدلفى او السى++ هناك اشياء كثيره مخفيه تجدث جلف الكواليس, من ضمن هذه الاشياء واجه المستخدم, هذه هو الجزئيه التى شرحتها حتى الان, اما الجزء الباقى من البرنامج فكنت انوى ان اشرحه فى الدرس القادم, ولكن طالما انت مستعجل وتريد ان تعرف, فبر مجة الوندوس لا تختلف فى الاسمبلى عنها فى الدلفى او فى السى++.

نالاحظ مثلا المتغيرات فى السى نكتب هكذا

int x =0;
char*y;

فى الاسمبلى تكتب هكذا

x dw 0
y db ?

بالنسبة للبرنامج فكل برامج الوندوز تبداء بالحصول على العنوان Handle , كذالك الحال فى الاسمبلى انظر إلى هذا الكود :

invoke  GetModuleHandle, NULL
mov  hInstance, eax

GetModuleHandle هو من ضمن ال API الموجده فى برمجه الوندوز, ثم نقوم بوضع القيمه والتى نحصل عليها فى المسجل eax فى متغير نسميه hinstance.

نفس الكود بلغة السى++ يصبح كالتالى.

hInstance= GetModuleHandle(NULL);

يمكنك الان مقارنة برنامج مكتوب بالدلفى او السى++ مع البرنامج الذى كتبناه بلغه الاسمبلى ستجد انه ليس هناك فرق كبير.

لو كان لديك اى اسئله اخى انا تحت الخدمه إن شاء الله.

والسلام

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

ممتاااز

ولو كان 16 بايت تكون بدايته بالشكل هذا

أسفل المشروع

end startpro

بحيث تكون startpro

proc معين في المشروع

؟؟

طيب ممكن سؤال ثاني

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

procedure startpro(hInstance:string; Reason:dword; Reserve:dword);
begin

end;

ونفس الكود تقريبا في الأسمبلي بالشكل هذا

startpro proc hInstance:HINSTANCE, Reason:dword, Reserve:dword

startpro endp

طيب الآن في الدلفي لو استدعينا الإجراء بالشكل هذا

startpro;

راح يكون خطأ

لكن في الأسمبلي لو استدعينا الإجراء بالشكل هذا

end startpro

هل سيكون صحيح ؟

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

لإستدعاء الاجراء لابد ان ترسل الملحقات المذكوره فى البروسيجر على سبيل المثال:

startpro proc hInstance:HINSTANCE, Reason:dword, Reserve:dword
...
startpro endp

تستدعيه بهذه الطريقه :

invoke startpro,hInstance,Reason,Reserve

هو نفس الطريقه المستخدمه فى كل لغات البرمجه, و اظن هى الطريقه المستخدمه فى الدلفى ايضاً.

ارجو ان يكون هذا هو الرد على سؤالك .

والسلام

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

هل يوجد فرق بين

end startpro

invoke startpro

تم تعديل بواسطه <>دلفي<>
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

اخى دلفى end startpro هى بمثابه end; فى الدلفى, للإستدعاء نستخدم invoke فى الاسمبلى.

كما تفضلت وذكرت :

procedure startpro(hInstance:string; Reason:dword; Reserve:dword);
begin
...
end;

تعادل فى الاسمبلى

startpro proc hInstance:HINSTANCE, Reason:dword, Reserve:dword
...
startpro endp

والسلام

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

طيب :)

ممكن لو سمحت تشوف الرابط هذا

http://www.1t.2t.3t.4t.com/assemply9.html

في المثال أسفل يوجد نفس الشي

END MAIN  ;start the program control from MAIN procedure

وفي الأعلى يوجد

MAIN PROC 
.....
MAIN ENDP

وآسف لو أزعجتك

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

بالعكس مافى إزعاش اخى الحبيب, اخيراً وجدت من يهتم بهذه الدروس ولله الحمد.

اولاً دروس الاخ احمد عز هو عن الاسمبلى 16 بت, ولو لاحظت هناك ENDP و END.

ENDP معناها END PROCEDURE بينما END هو للبرنامج كله.

فى البرنامج الذى وضعته هناك كلمة start فى بداية الكود وهى نقطة بداية البرنامج, وتنتهى عندما نختمها بكلمة END start.

بعد الدخول من نقطة البدايه start يقوم البرنامج بالحصول على عنوان البرنامج Handle , ثم يستدعى WinMain:

start:
invoke  GetModuleHandle, NULL
mov  hInstance, eax

      invoke  WinMain, hInstance, NULL, NULL, SW_SHOWNORMAL
invoke  ExitProcess,eax

واخيراً يقوم بالخروج من البرنامج ExitProcess.

لذالك علينا ان نشرح الذى يحدث فى WinMain لان البرنامج برمته موجود فى هذه الوصله.

ولك منى اجمل تحيه على حماسك .

والسلام

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

ممتااااز

انا يمكن خلطت الأمور بين الدلفي والأسمبلي

لأنه في الدلفي اذا كنت بتبرمج برنامج من نوع CONSOLE APP شكل المشروع

يكون كذا

procedure any:
begin
..
end;
procedure any2:
begin
..
end;

وفي أسفل المشروع

begin
any:
any2:
end.

يعني نقطة البدايه في الأسفل والإستدعائات لأعلى

وكنت متوقع نفس الشي في الأسمبلي لدرجة إني صدقت ان END. الإجراء اللى بعدها يكون بدايه

icon6.gif

لكن طلع العكــس

شكرررررا الآن فهمت على مايبدوا :)

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

حياك الله اخى

فى الاسمبلى يمكنك إستدعاء الوصله قبل او بعد الوصله, لاننا قد اعطينا الكمبايلر علم مسبق بوجود تلك الوصله, لو الحظت فى بدية البرنامج ستجد السطرين التاليين :

WinMain  PROTO STDCALL :DWORD, :DWORD, :DWORD, :DWORD
WndProc  PROTO STDCALL :DWORD, :DWORD, :DWORD, :DWORD

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

انا فهمت قصدك الان فى الباسكال والدلفى لابد ان تكون الوصله موجوده قبل المكان الذى تتم فيه الدعوه, ولكن على ما اذكر فى الباسكال هناك إمكانيه لإعلام المترجم بان الوصله موجوده لاحقاً فى البرنامج لكن لا اذكر الطريقه فانا قد هجرت الباسكال والدلفى من اكثر من ثمان سنوات, واخر عهدى بالدلفى كان على ايام دلفى 2.

والسلام

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

حياكم الله مره اخرى, كنت اتمنى ان ارى مشاركات عديده فى هذا الموضوع وخصوصاً ان الموضوع مهم ومبسط إلى اقصى حد, عموماً سؤاصل شرح البرنامج وإذا لم اجد التجاوب الكافى ساتوقف عند هذه النقطه.

توقفنا المره السابقه عند الاوامر Instructions و الذى يرمز له ب code, فى داخل ال code نجد هذه الفقره

.code
start:
invoke  GetModuleHandle, NULL
mov  hInstance, eax

      invoke  WinMain, hInstance, NULL, NULL, SW_SHOWNORMAL
invoke  ExitProcess,eax

البرنامج كله يبدا وينتهى فى هذه الفقره, بداية البرنامج نسميها start, اول ما نقوم به هو الحصول على عنوان البرنامج بوسطه GetModuleHandel والذى يقوم بتحديد عنوان البرنامج ومن ثم نقوم بحفظ العنوان فى المتغير hInstance .

نستدعى بعد ذالك الوصله WinMain ونرسل معها بعض الاوامر مثل عنوان البرنامج والذى حصلنا عليه من الفقره السابقه hInstance , المعطيات التاليه هى هو على النحو التالى , NULL الاولى تعنى انا لا نهتم باوامر سابقه حيث ان البرنامج لا يحتوى على اوامر سابقه , و NULL الثانيه تعنى اننا لا نهتم بالاوامر المضافه إلى إسم البرنامج command line, والامر الاخير معناه اننا نريد إظهار النافذه بعد إعدادها.

واخيراً نقوم بالخروج من البرنامج بإصدار الامر ExitProcess .

والان ندهب إلى لب البرنامج WinMain والذى يقوم بصناعة النافذه و التحكم بالاوامر التى يتلقاها.

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
mov    wc.cbSize,SIZEOF WNDCLASSEX
mov    wc.style, CS_HREDRAW or CS_VREDRAW
mov    wc.lpfnWndProc, OFFSET WndProc
mov    wc.cbClsExtra,NULL
mov    wc.cbWndExtra,NULL
push   hInstance
pop    wc.hInstance
mov    wc.hbrBackground,COLOR_WINDOW
mov    wc.lpszMenuName, NULL
mov    wc.lpszClassName,OFFSET ClassName
mov    wc.hIcon, 0
mov    wc.hIconSm, 0
invoke  LoadCursor,NULL,IDC_ARROW
mov    wc.hCursor,eax
invoke  RegisterClassEx, addr wc
invoke  LoadMenu, hInstance, MAINMENU;load menu
   mov     hMenu, eax                  ;store handle

INVOKE  CreateWindowEx,WS_EX_LAYOUTRTL,ADDR ClassName,ADDR AppName,\
          WS_OVERLAPPEDWINDOW-WS_MAXIMIZEBOX-WS_SIZEBOX,\
          CW_USEDEFAULT, CW_USEDEFAULT,258,350,NULL,hMenu,\
          hInst,NULL
mov    hwnd,eax
invoke  ShowWindow, hwnd, CmdShow
invoke  UpdateWindow, hwnd
.WHILE  TRUE
invoke  GetMessage, ADDR msg,NULL,0,0
.BREAK  .IF (!eax)
invoke  TranslateMessage, ADDR msg
invoke  DispatchMessage, ADDR msg
.ENDW

نقوم اولاً بتعين بعض المتغيرات على النحو التالى :

wc هى محتويات النافذه, وهى عباره عن معطيات structure لمحتويات النافذه وتكتب هكذا : LOCAL wc:WNDCLASSEX

الداله msg هى الداله المسؤله عن الاوامر التى تتلقاها النافذه مثل تغير حجم النافذه او إختيار احد القوائم وتكتب هكذا: LOCAL msg:MSG

واخيراً عنوان النافذه والذى سوف نقوم يحفظه فى داله نسميها hwnd وتكتب هكذا: LOCAL hwnd:HWND.

بعد الانتها من الدوال نقوم بإعطاء الدوال القيم المنشوده, الداله wc هى عباره عن structure, لن اقوم بشرح كل المعطيات فى هذه الداله لانها كثيره جداً ولكن اشرح الاجزاء المهمه فى هذه الداله.

الداله wc هى محتويات النافذه ,

mov wc.lpfnWndProc, OFFSET WndProc

هذه الداله على سبيل المثال تخبر النافذه ماذا تفعل بالاوامر التى تحصل عليها, وهى عنوان الوصله التى يرسل إليها الامر لترجمته إلى تنفيذ الامر.

وهذه الداله :

mov wc.hbrBackground,COLOR_WINDOW

تحدد لون خلفية النافذه.

يعد ان حددنا شكل النافذه نقوم بتسجيلها بالامر التالى:

invoke RegisterClassEx, addr wc

حتى يتسنى لوندوز التعرف على محتوياتها.

ثم نقوم باحضار القوائم menu من الملف الذى حددنا فى شكلها على النحو التالى

invoke LoadMenu, hInstance, MAINMENU;load menu

ونحفظه فى المتغير hMenu, هكذا : mov hMenu, eax

واخيراً نطلب من وندوز ان يقوم بعمل النافذه بواسطة الامر CreateWindowEx وفى هذا الامر نرسل العديد من الملحقات, على سبيل المثال عرض وطول النافذه 258 عرض و 350 طول, كذالك نرسل الملحق WS_EX_LAYOUTRTL والذى يجعل النافذه معربه , والامر ADDR AppName الذى يضع لنا عنوان النافذه , لمعرفه المزيد عن CreateWindowEx عليك بالرجوع إلى Windows API والتى تجدها فى www.MSDN.com .

بعد ذالك نحفظ عنوان النافذه فى المتغير hwnd ونقوم باظهارها وتجديدها:

mov hwnd,eax

invoke ShowWindow, hwnd, CmdShow

invoke UpdateWindow, hwnd

والان بعد ان قمنا بعمل النافذه علينا للتحكم بها ان نعالج جميع الاوامر الصادره إليها, و ذالك على النحو التالى:

فى loop دائم نقوم بمعالجة جميع الاوامر إلى ان تاتينا إشاره بإنها البرنامج:

WHILE  TRUE
invoke  GetMessage, ADDR msg,NULL,0,0
.BREAK  .IF (!eax)
invoke  TranslateMessage, ADDR msg
invoke  DispatchMessage, ADDR msg
.ENDW

اولاً نحصل على الامر بالوصله GetMessage إذا كان الامر إنهاء نخرج من loop وننهى البرنامج بالعوده الى ُExitProcess, إذا لم يكن كذالك قمنا بترجمة وتنفيذ الامر.

والان الوصله التى تعالج الاوامر :

WndProc proc hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
mov eax, uMsg

.IF eax==WM_DESTROY
invoke PostQuitMessage, NULL
.ELSE
invoke  DefWindowProc,hWnd,uMsg,wParam,lParam  
ret
.ENDIF
ret
WndProc endp

كل ما تقوم به هذه الوصله فى الوقت الحالى هو الخروج من البرنامج إذا قام المستخدم بالضعط على علامة X فى اعلى النافذه وهو الامر : invoke PostQuitMessage, NULL. فى اى حاله اخى ليس هناك اوامر محدده.

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

ما كان من توفيق فمن الله عز وجل وما كان من خطاء او نسيان فمن نفسى ومن الشيطان والله ولى التوفيق.

والسلام

تم تعديل بواسطه احمد غريب
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

طالما اصبح الموضوع من المعلقات واصبح مثبت , فهناك من اهتم به ولذالك نواصل الدوروس بحول الله تعالى, اشكر المشرف المجهول الذى قام بتثبيت الموضوع.

كما وعدت فى المره السابقه سنقوم هذه المره باضافة ايقونه للبرنامج و قائمة ايقونات لواجهة المستخدم, نبدا اولاً بايقونة البرنامج والذى يتكون من ايقونتين. ايقونه كبيره وهى التى نراها فى الاكسبلورر و ايقونه صغيره تظهر فى اعلى النافذه وعند عند تصغيرها.

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

لاضافت هتين الايقونتين نحتاج إلى تعريف البرناج عليهما من خلال وضعهما ضمن الملحقات skeleton.rc على النحو التالى :

#define        ICONBIG              200
#define        ICONSMALL            201

ICONBIG        ICON    DISCARDABLE     "resorces\\big.ico"
ICONSMALL      ICON    DISCARDABLE     "resorces\\small.ico"

وفى skeleton.inc نترجم إسم المتغير إلى لغه الاسمبلى هكذا:

ICONBIG	equ 200
ICONSMALL equ 201

الان لدينا فى الملحقات الايقونتين جاهزه للإستخدام, نقوم بعد ذالك بإعلام البرناج عنهما على النحو التالى:

invoke  LoadIcon, hInstance, ICONBIG
mov     wc.hIcon, eax
invoke  LoadIcon, hInstance, ICONSMALL
mov     wc.hIconSm, eax

إذا قمت الان بعملية كمبايل للبرنامج ستجد ان البرنامج حصل على ايقونه تعبر عن محتوى البرنامج, العمليه اسهل ما يكون.

ننتقل الان لعمل ايقونات واجة المستخدم:

لإضافت ايوقونات الواجه نحتاج إلى تصميم صوره فى برنامج Paint على سبيل المثال, وقد اخترت ان يكون طول الايقونه 16 نقطه وعرضها كذالك 16 نقطه.

فى هذا المثال ساضع 7 ايقونات, من الافضل وضع جميع الايقونات فى صوره واحده طولها 16 نقطه وعرضها 16 x عدد الايقونات, انظر الصوره المرفقه حتى تفهم ما اقصد.

وبعد ان إنتهينا من تصميم الصوره, يجب ان نضعها فى الملحقات skeleton.rc على النحو التالى:

#define        BMPTOOLBAR           400
BMPTOOLBAR BITMAP  DISCARDABLE     "resorces\\Toolbaricons.bmp"

وفى skeleton.inc نترجم إسم المتغير إلى لغه الاسمبلى هكذا:

BMPTOOLBAR	equ 400

والان اصبحت الملحقات جاهزه للإستخدام, وما علينا إلى إستدعائها من البرنامج.

لستدعاء قائمة الايقونات علينا اولاً ان نحدد ترتينها فى النافذه, وذالك على النحو التالى:

فى قسم المعطيات نقوم بانشاء الجدول التالى:

ToolbarButtons  TBBUTTON    <0, MI_MENU21, TBSTATE_ENABLED+TBSTATE_CHECKED, TBSTYLE_CHECKGROUP,0, NULL, NULL>
               TBBUTTON    <1, MI_MENU22, TBSTATE_ENABLED, TBSTYLE_CHECKGROUP,0, NULL, NULL>
               TBBUTTON    <2, MI_MENU23, TBSTATE_ENABLED, TBSTYLE_CHECKGROUP,0, NULL, NULL>
 TBBUTTON    <NULL, NULL, NULL, TBSTYLE_SEP, NULL, NULL>;--- seperator
 TBBUTTON    <3, MI_MENU31, TBSTATE_ENABLED+TBSTATE_CHECKED, TBSTYLE_CHECKGROUP,0, NULL, NULL>
               TBBUTTON    <4, MI_MENU32, TBSTATE_ENABLED, TBSTYLE_CHECKGROUP,0, NULL, NULL>
               TBBUTTON    <5, MI_MENU33, TBSTATE_ENABLED, TBSTYLE_CHECKGROUP,0, NULL, NULL>
 TBBUTTON    <6, MI_MENU34, TBSTATE_ENABLED, TBSTYLE_CHECKGROUP,0, NULL, NULL>

ربما يكون شكل الجدول معقداً ولكن لو لاحظنا نجد ان الجدول ما هو إلى عدد من الكلمات المكرره, دعونا ناخذ السطر الاول منه ونفحصه بدقه:

TBBUTTON    <0, MI_MENU21, TBSTATE_ENABLED+TBSTATE_CHECKED, TBSTYLE_CHECKGROUP,0, NULL, NULL>

هذا السطر يحتوى على مكونات وشكل الايقونه الاولى فى القائمه,TBBUTTON هى عباره عن structure تحتوى على القيم التى نريد ان نعطيها للايقونا, الرقم 0 فى بداية السطر ترمز للصوره الاولى فى الصوره الطويله التى قمنا بتصميمها, MI_MENU21 هى الامر الذى سترتبط به هذه الايقونه, كما تلاحظون هو نفس الامر الذى تقوم به احد الاختيارات فى القائمه الوان.

الخانه التاليه هى لتحديد شكل الايقونه TBSTATE_ENABLED+TBSTATE_CHECKED الكلمه الاولى قبل علامة الزائد TBSTATE_ENABLED معناها ان الايقونه مفعله, اى انه يمكن للمستخدم الضغط عليها, والكلمه الثانيه TBSTATE_CHECKED تعنى ان الايقونه تكون مضغوطه عند بداء البرنامج.

الخانه التاليه TBSTYLE_CHECKGROUP تعنى ان الايقونه هى جزء من مجموعه, اى انه عند القيام بالضغط عليها يتم رفع ايقونه اخرى من نفس المجموعه.

على نفس المنوال يتم تصميم بقية الايقونات, هناك ملاحظه بسيطه, لو لاحظنا نجد ان هذا السطر :

TBBUTTON    <NULL, NULL, NULL, TBSTYLE_SEP, NULL, NULL>;--- seperator

يختلف عن بقية الايقونات, وذالك لان هذه السطر لايقوم بإنشاء ايقونه, وإنما حاجز بين الايقونات.

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

بعد ان قمنا بتحديد القوائم علينا الان ان نستخدما فى برنامجنا, وللوصول إلى ذالك نحتاج ان نستخدم الوصله CreateToolbarEx, هذه الوصله موجوده فى المكتبه التى تدعى comctl32.lib, لذاك لا بد ان نضيف هذه المكتبه إلى مجموعة المكتبات التى نستخدمها كى تصبح على النحو التالى:

 includelib	c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\user32.lib
includelib  c:\masm32\lib\comctl32.lib
include c:\masm32\include\kernel32.inc
include c:\masm32\include\user32.inc
include      c:\masm32\include\comctl32.inc
include c:\masm32\include\windows.inc
include resorces\skeleton.inc

والان يكمننا ان نستخدم الوصله على هذا النحو :

.ELSEIF eax==WM_CREATE
 invoke  CreateToolbarEx, hWnd, WS_CHILD + WS_VISIBLE + WS_BORDER,\
        IDTOOLBAR, 7, hInstance, BMPTOOLBAR, ADDR ToolbarButtons,\
       8, 16, 16, 16, 16, SIZEOF TBBUTTON
 mov     hToolbar, eax
 invoke  ShowWindow, hToolbar, 5

نقول للنافذه فى حال تم عمل النافذه WM_CREATE قم بعمل قائمه ايقونات invoke CreateToolbarEx ثم اظهرها فى الشاشه invoke ShowWindow.

المالك للقائمه هى نافذت البرنامج hWnd, وكلمة WS_CHILD تعنى انها جزء من نافذه وليست قائمه بذاتها, والارقام هى على النحو التالى 7 تعنى ان لدينا صوره بها سبع ايقونات 8 تعنى اننا نود رسم 8 ايقونات 7 ايقونات + الفاصله seperator, لدينا ايضاً 4 مرات 16 وتعنى ان لدينا صوره 16 فى 16 ونود ان نقوم بعمل ايقونه 16 فى 16.

لمعرفت المزيد عن CreateToolbarEx عليك بمراجعه MSDN او طرح اسئله فى هذا الموضوع وبعون الله ساجيب انا او احد الاخوه فى المنتدى عليها.

ما رايكم فى الدروس حتى الان هل هناك تعليق, إعتراض على صعوبة او سهولة الشرح ؟

ما كان من توفيق فمن الله عز وجل وما كان من خطاء او نسيان فمن نفسى ومن الشيطان والله ولى التوفيق.

والسلام

skeleton.zip

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

الله يبارك فيك يا احمد على هذا المجهود و الشرح.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

حياك الله اخى عماد, كنت اتمنى ان يشارك الاخوه فى هذه الدروس بانقد البناء او الاقتراح, ولكن املى هو ان يستفاد من هذه الدروس حتى ولو بعد حين.

لاحظت ان عدد المشاهدات للدرس كبيره جداً, ففى خلال اقل من شهر تم المرور على الدروس اكثر من 250 مره, وهذا ما يجعلنى استمر فى المواصله.

هذه الدروس اكتبها بدون اى ترتيب مسبق, فهى مجرد خواطر اقوم بوضعها هنا, فإذا كان هناك اى فكره لاى اخ من الاخوه فى المنتدى, فليتفضل مشكوراً بطرحها حتى تعم الفائده ولكم منى اجمل تحيه.

والسلام

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

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

الله الله الله ياسلالالالالالالالالالام ..ماشاء الله تبارك الله ..بما إنني مبتدأ عجبني الدرس كثيراً وفهمت أشياءً الحمدلله وأشياءً أجدها طلاسم أو غرائب لم أستوعبها جيداً ولم اعرف هل هي تحفظ عن ظهر قلب مثل أموامر السي بلس cin>> أو cout أو ماذا؟؟

أتمنى أن توضح لي ياستاذي الكريم

وتسلم والله يأخي ويأستاذي الكريم على هذه الدروس الأكثر من روووووووووووووعه

أنا عيبي الكبير انني أتصفح في المنتدى وأقرأ جزء من الموضوع ثم أحفظ الصفحة لدي في الجهاز ....حتى تكدسة لدي المواضيع ومن غير قراءه ...واليوم قررت أن أدرس درس درس وأنظم المعلومات وأفهم الاسمبيلي 23 بت جيداً

وإلا وانا أجد هذا الدرس أو بالأصح الكنز الجميل من الكنوز الموجود في هذا المنتدى الرائع

أتمنى أن تستمر والله في تكملة السلسلة لهذه الدروس وأن لا تحرمنا من متعة التعلم والفائده

ويالله أنا واحد من الطلاب المتتبعين لموضوعكم هذا أتمنى أن تستمر إذا سمحت وتكرمت

وفي امان الله

الأمان

تم تعديل بواسطه al_aman
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

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

اخي الكريم احمد :lol:

الحقيقة يعتبر هذا الموضوع من افضل المواضيع الذي قراتها حتى الان و اكثرها بساطة

و رغم ذلك فلدي بعض الاسئلة

:D

MsgCaption db "اول برنامج اسمبلى",0

حسب ما فهمتMsgCaption

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

و db

معناها بايت واحد فلماذا اخترناها هي بالذات

موضوع الذاكرة مهم على ما يبدوا و يجب فراءة الموضوع العديد من المرات

فيما يخص البرنامج لم اجد مشاكل في الملفين الاولين لكن لدي العديد من الاسئلة فيما يخص ملف الكود منها

هل تعتبر الوصلتين WinMain و Wnd proc

كبرنامجين صغيرين في البرنامج الام

والوصلة الثانية ليست مذكورة في البرنامج الام فكيف يتم استدعاؤها

و كيف يمكنني التعديل في النافذة أي كيف يمكنني التعديل في الدالة wc

invoke ExitProcess,eax

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

و ارى ان الوصلة الثانية التي تعالج الاوامر هزيلة فكيف يمكننا تسمينها بالاوامر

لقد واجهتني مشكلة عند القيام بالكمبايلر للكود وهي لم يفهم هذا البارمتر

WS_EX_LAYOUTRTL

مما اضطرني بالفيام بالنافذة باللغة الانقليزية...لو كانت بالعربية لكانت اجمل

فهل يمكن ان يكون جهازي لا يدعم العربية

لقد قمت بهذا البرنامج و بنفصه الايقونات التي ساحاول زيادتها

وهو يعتبر نسخة طبق الاصل للكود الذي ذكرته وساحاول التعديل فيه و اجابتك على اسئلتي ستساعدني

و كيف يمكننا اضافه ملف صوتي للبرنامج

اثقلت عليك باسئلتي

جازاك الله خيرا اخي على هذا البرنامج الاكثر من رائع ;)

languages.zip

تم تعديل بواسطه محمد فراس
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
زوار
This topic is now closed to further replies.

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .