دورة ماك للعرب - برمجة Apple
القسم الأول من أقسام Carbon - المبتدئ
الوحدة الثانية - الدرس الأول
المدخل إلى الـ Carbon
الإثنين الموافق 6-محرم- 1429هـ 14-1-2008م
_________________________________________________
المصدر: كتاب (داخل Carbon) - تأليف أبو بكر، جميع الحقوق محفوظة لماك للعرب فقط.
المثال البرمجي المرفق في الأصل لـ
Apple مكتوب بلغة
Pascal. قمت بتحويله إلى لغة
C.
_________________________________________________
ملاحظة: قبل البدء في هذا الدرس، يجب عليك قراءة الدرس الأول من دروس لغة C والذي سبق نشره على هذا الرابط:
انقر هنا. وذلك ليسهل استيعاب هذا الدرس.
تمهيد:- نبدأ دراستنا لبرمجة حواسب الماكنتوش في هذه الوحدة بشرح التنظيم العام لأجزاء نظام التشغيل، والتي تعرف -في السابق قبل صدور نظام X وبالتحديد في عام 1992م- بأنها مجموعة كبيرة من الروتينات يتم استخدامها لتسهيل عملية تطوير تطبيقات الماكنتوش، ولدى صدور نظام التشغيل 8 أصبحت تعرف باسم Carbon.
- ويقدّم نظام التشغيل -بالإضافة إلى ذلك- روتينات تستخدمها لإنشاء وإدارة الأقسام الهامة في واجهة استخدام تطبيقك. وتعرض هذه الوحدة التنظيم العام لنظام التشغيل من خلال مناقشتها لمثال تطبيقي بسيط جدا.
- إن تقنية Carbon في غاية الأهمية، وتُعْرَفُ بأنها مكتبة أپل للتقنية Apple Technical Library، إذ تحتوي على جميع الروتينات وتعاريف الأنماط الخاصة بإدارات نظام التشغيل، ولقد تجاوز عددها عشرات الألاف، ويصعب جدا حصرها في موضوع واحد، ولأنها مكتبة وليست لغة برمجة بحد ذاتها فباستطاعتنا استخدام الروتينات و الأنماط في أي لغة برمجة سواء كانت Pascal أو C. وفي دورتنا التعليمية سنقتصر على استخدام لغة C مع مكتبة Carbon وهو ما نسميه بـ C Carbon.
لنبدأ ورشة العمل معا.
ورشة العمل:- قم بفتح برنامج Xcode، أنشئ مشروع جديد من نوع Carbon Aplication كما هو موضح في الدرس الأول من دروس لغة C، أعط المشروع هذا الاسم: GreetMe.
- قم بفتح الملف main.c وامسح الشيفرة (النص البرمجي) بالكامل.
- اكتب البرنامج التالي بدقة تامة -لاحظ أن الأرقام كتبت لتكون مرجعا فقط ولا تكتب في البرمجة مطلقا-:
كود:
( 1)// Great Me - My First Application using Carbon.
( 2)#include <Carbon/Carbon.h>
( 3)
( 4)int main()
( 5){
( 6) WindowRef gWindow; // pointer to a window record
( 7) Str255 gString = "\pHello, World!"; // the string to displ
( 8) Rect gRect; // the window's rectangle
( 9)
(10) SetRect(&gRect, 100, 100, 800, 400); // set the position of the window
(11)
(12) // create a window
(13) gWindow = NewWindow(nil, &gRect, "\p", TRUE, dBoxProc, (WindowPtr)-1, FALSE, 0);
(14)
(15) SetPortWindowPort (gWindow); // set the current drawing port
(16)
(17) MoveTo(15, 30); // set the position of the pen
(18) TextSize(24); // set the size of the font
(19) TextFont (kFontIDTimes); // set the font to times
(20) DrawString (gString); // draw the string
(21)
(22) RunApplicationEventLoop(); // loop until the user quit
(23)}
- قم الأن بتنفيذ البرنامج عن طريق اختيار Build and Run من قائمة Build. بعد ذلك ستظهر لك نافذة بشكل مربع حوار مكتوب في الزاوية العلوية اليسرى هذه العبارة: Hello World!.
الدراسة والتحليل:- سبق شرح الروتين الأساسي في الدرس الأول من دروس لغة C، وسيتم التركيز على تقنية Carbon فقط هنا.
- تجاهل السطر (2) سيتم شرحه في الدرس الثاني من دروس لغة C لأنه من أوامر اللغة ولا علاقة له بتقنية Carbon.
- السطر رقم (6) تم فيه تعريف المتغير gWindow ونوعه WindowRef، وهذا النوع يشير إلى نمط سجل النافذة المراد إنشاؤها.
- السطر رقم (7) تم فيه تعريف ا لمتغير gString ونوعه Str255، وتم إعطاؤه القيمة الافتراضية وهي الجملة: Hello World!.
- السطر رقم (8) تم فيه تعريف المتغير gRect ونوعه Rect.
- المتغير الأول gWindow نوعه WindowRef، وهذا النوع مساو تماما للنوع WindowPtr، ويمكنك استخدام أي منهما هنا، وهما إشارة إلى نمط سجل النافذة، وهذا النمط تم تعريفه في إدارة النوافذ Window Manager. (سيتم شرح الأنماط بالتفصيل بعد أن ندرسها في الدرس الثاني من دروس لغة C).
- المتغير الثاني gString نوعه Str255، وهذا النوع هو نمط يعرّف الجملة المكونة من الأحرف، وعدد الأحرف المسموح بها كحد أقصى هو 255 حرف فقط.
ولعلك تتساءل لماذا وضعنا الحرف الخاص (\p) قبل بداية الجملة؟ والسبب في ذلك أن هذا النمط تم تعريفه في نظام التشغيل باستخدام لغة Pascal، وهيئة الجملة في لغة Pascal تختلف عن هيئة الجملة في لغة C. ويخبر هذا الحرف نظام التشغيل أن هيئة الجملة تتطابق مع هيئة جملة Pascal. سيتم شرح الفرق بين الهيئتين في دروس لغة C.
- المتغير الثالث gRect نوعه Rect، وهو نمط تم فيه تعريف الشكل الرباعي «المستطيل»، ويتكون المستطيل من أربعة أضلاع، ولذلك تم تمرير أربع قيم رياضية لتمثل إحداثيات الأضلاع.
- وفي السطر (10) تم استدعاء الروتين SetRect، ووظيفة هذا الروتين هو إعداد الشكل الرباعي بناء على الوسائط الخمسة المعطاة له، الوسيطة الأولى عبارة عن عنوان المتغير gRect إلى المستطيل المطلوب إعداده، والوسائط الأربعة الرقمية هي إحداثيا أضلاع المستطيل.
- لنأخذ بعين الاعتبار الاستدعاء الذي يقوم بإنشاء النافذة التي ستظهر فيها عبارة التحية:
gWindow = NewWindow(nil, &gRect, "\p", TRUE, dBoxProc, (WindowPtr)-1, FALSE, 0);
إن استدعاء هذا الروتين (تذكر أن نوعه عملية) NewWindow بهذا الشكل يجعله ينشئ نافذة (Window) في المكان المحدد وفوق جميع النوافذ الموجودة على الشاشة. وهو مثال جيد عن أنواع الروتينات التي يزودنا بها نظام التشيغل، ومن أهم ميزات هذه الروتينات أنها تبسط عملية إنشاء واجهة تطبيقات الماكنتوش المعروفة بالواقعية والحقيقة. وباستخدام هذه الروتينات ستجعل شكل واجهة برنامجك التطبيقي أقرب ما يكون إلى واجهة المستخدم الرسومية الخاصة بنظام تشغيل الماكنتوش.
- لنلق نظرة عن قرب إلى الاستدعاء السابق للروتين (العملية) NewWindow. نجد أن العملية NewWindow تتطلب ثمانية وسائط وهي كما يلي:
- الوسيطة الأولى: nil:
هي عنوان نمط سجل النافذة ، وهو سجل يوضح بناء النافذة، ويحتوي على معلومات النافذة الجديدة، تمرير هذه القيمة nil كعنوان لسجل النافذة يُعْلِمُ نظام التشغيل بأن يقوم بتخصيص الحجم المطلوب من الذاكر لحفظ هذا السجل بنفسه.
- الوسيطة الثانية: &gRect:
الوسيطة gRect تعني الإطار (الشكل الرباعي -المستطيل-) الذي يحصر النافذة، وقيم إحداثيات أضلاع الإطار تم تعيينها بالاستدعاء السابق للروتين SetRect، الذي بدوره حدَّدَ الزوايتين العليا-اليسرى و السفلى-اليمنى للمستطيل.
- الوسيطة الثالثة: "\p":
عنوان النافذة، وهو العنوان الذي يظهر في منتصف النافذة. تجد أننا لم نحدد العنوان، لذلك النافذة بدون عنوان، وتسمى بالجملة الفارغة Empty String لخلوها من الأحرف. سبق الحديث عن الحرف الخاص: \p.
- الوسيطة الرابعة: TRUE:
وهي عبارة عن تنويه: لإخبار إدارة النوافذ ما إذا كانت النافذة ستظهر على الشاشة فور إنشائها تلقائيا أم لا. تم تمرير القيمة TRUE لهذه الوسيطة لتنويه إدارة النوافذ على أن النافذة يجب أن تكون مرئية فور إنشائها.
- الوسيطة الخامسة: dBoxProc:
توضح نوع النافذة المراد إنشاؤها، توفر واجهة المستخدم الرسومية في نظام الماكنتوش أنواعا عديدة من النوافذ وذات أغراض متنوعة. بالنسبة للغرض الحالي من النافذة، يناسب تماما أن تكون على شكل مربع صندوق الحوار القياسي المشروط (Standard Modal Dialog Box). والقيمة dBoxProc تحدد هذا النوع من النوافذ.
- الوسيطة السادسة: (WindowPtr)-1:
تحدد الوسيطة النافذة التي تريد أن تجعلها فوق النافذة الجديدة، بمعنى آخر النافذة الجديدة ستكون خلف النافذة المحددة في الوسيطة، وتم تمرير القيمة (WindowPtr)-1 لتكون النافذة الجديدة فوق جميع النوافذ. إذا أردت أن تكون النافذة خلف جميع النوافذ قم بتمرير القيمة nil.
- الوسيطة السابعة: FALSE:
عبارة عن تنويه بخصوص النافذة ما إذا كانت تحتوي على مربع الإقفال (Close Box) أو لا. تم تمرير القيمة FALSE للتنويه على أن النافذة الجديدة لا تحتوي على مربع الإقفال.
- الوسيطة الثامنة: 0:
قيمة مرجعية خاصة ببرنامجك، ويتم حفظ هذه القيمة في سجل النافذة في حقل خاص بها، وهي مفيدة جدا في حال كانت النافذة تحتوي على معلومات خاصة و مرتبطة بها كالوثائق في محرر النصوص. تم تمرير القيمة 0 لأنه لا توجد أي معلومات متعلقة أو مرتبطة بالنافذة الجديدة.
- بعد ذلك تعود العملية NewWindow بإشارة إلى النافذة التي تم إنشاؤها، وتستخدم هذه الإشارة للتعامل مع النافذة، ويشمل التعامل على التحريك أو النقل أو الإخفاء أو الإظهار أوالإغلاق.. إلخ.
ملاحظة: هذا النوع من النوافذ dBoxProc لا تظهر فيه عنوانيها، ولذلك تم تمرير الجملة الفارغة كعنوان.
- وفي السطر (15) تم تحديد النافذة لتكون ميناء الرسم الحالي عن طريق استدعاء الروتين SetPortWindowPort حتى نمتكن من رسم النصوص فيها.
- وفي السطر (17) تم وضع قلم الرسم عند إحداثيات النقطة المحددة عن طريق استدعاء الروتين MoveTo.
- وفي السطر (18) تم تحديد مقاس الخط (البنط) ليكون 24.
- رفي السطر (19) تم تحديد الخط ليكون Times باستدعاء الروتين TextFont.
- وفي السطر (20) تم رسم الجملة باستدعاء الروتين DrawString.
- وفي السطر (22) تم استدعاء الروتين RunApplicationEventLoop الخاص بتنفيذ حلقة الأحداث، التي توفرها إدارة الأحداث الكاربونية. ويقصد بالأحداث تفاعل المستخدم مع البرنامج، فمثلا نقرة زر الفأرة، أو ضغط مفتاح معين من لوحة المفاتيح، أو إدخال قرص ليزري.. الخ. ولو حُذِفَ هذا السطر لما انتظر البرنامج حتى نختار Quit من قائمة GreetMe وسيقوم بعملية الإنهاء بعد إنشاء النافذة على الفور.. فم بتجربة ذلك.
ملاحظة:- التحذيرات التي تظهر عند تنفيذ البرنامج على شكل مثلثات صفراء اللون صغيرة سببها أننا نستخدم تقنية الرسم QuickDraw الخاصة بنظام Classic، أما تقنية الرسم الخاصة بنظام X هي Quartz، ولقد توقفت Apple عن استخدام تقنية QuickDraw منذ صدور نظام التشغيل Mac OS 10.4 إلا أنها ما زالت جزءا من نظام التشغيل حتى يومنا هذا. ولكن لا بأس من تعلم QuickDraw فإنها أسهل وفيها شرح للمبادئ بشكل ممتاز، كما تساعدنا في فهم تنقية Quartz.
- في الدرس الثاني من دروس لغة C سنتناول موضوعات مهمة جدا، كي نتمكن من تناول موضوعات كبيرة في تنقية Carbon بإذن الله. والله ولي التوفيق.
الأسئلة:
س1: (10 نقاط)
قم الأن بإنشاء أكثر من نافذة تظهر معا، واجعل كل واحدة منها بموقع مختلف تماما ومقاس مختلف كما تم توضيح طريقة إنشاء النافذة في المثال المعطى، تذكر أن كل نافذة بحاجة إلى موقع مراعيا ما يلي أثناء الإنشاء:
- 1- استخدم هذه الأنواع من النوافذ في الوسيطة الخامسة:
documentProc
dBoxProc
plainDBox
altDBoxProc
noGrowDocProc
movableDBoxProc
zoomDocProc
zoomNoGrow
floatProc
floatGrowProc
floatZoomProc
floatZoomGrowProc
floatSideProc
floatSideGrowProc
floatSideZoomProc
floatSideZoomGrowProc
- 2- قم أيضا بإعطاء النوافذ التي تحتوي على -شريط عنوان- عناوين مختلفة.
- 3- إجعل بعض النوافذ لا تظهر تلقائيا، وقم بإظهارها عن طريق إستدعاء الروتين: ShowWindow، وهو على النحو التالي:
إذا كانت النافذة gWindow كما في المثال السابق، فإن إظهارها سيكون بهذا الاستدعاء: ShowWindow(gWindow);
- 4- في النافذة التي نوعها documentProc اجعلها مرة تحتوي على مربع الإقفال ومرة لا تحتوي على مربع الإقفال.
- 5- إطبع هذه الجملة في كل النوافذ التي أنشأتها: "This is my First application using Carbon: Greeting Me." وبحجوم مختلفة وأماكن مختلفة.
س2: (10 نقاط)
(هذا السؤال للإخوة الذين لديهم إلمام ومعرفة سابقة في البرمجة خصوصا في لغة
C، وأرجو من المبتدئين المحاولة في تنفيذه.)
- العبارة التي تم رسمها على النافذة في المثال السابق: "Hello World!" في الزاوية العليا-اليسرى للنافذة، قم بجعلها في منتصف النافذة تماما (أفقيا وعلويا). تلميح: استخدم الروتين التالي لمعرفة عرض الجملة بالبكسلات:
كود:
short StringWidth (Str255 s);
بانتظار استفساراتكم وأسئلتكم وإجاباتكم، وبالتوفيق إن شاء الله.