سلسلة من المقالات، احاول فيها تحفيز مبرمجي Visual Basic x.0 العرب الى مواكبة التيار والهجرة بلا عودة الى احد لغات اطار عمل NET Framework.
قد يعارضني الكثير من المبرمجين حول فكرة تخصيص فقرة عن النماذج والأدوات Forms and Controls، وذلك لانهما لا تتبع (تقنيا) للغة البرمجة VB6. هذا الكلام صحيح في اغلب لغات البرمجة المرئية Visual Languages، حيث تكون النماذج والادوات ماهي الى فئات من مكتبات مرافقة للغة، ولكن مع VB6 فالوضع يختلف قليلا، والدليل ان المجموعة Forms ستكون في الذاكرة في (كل) برامجك المنجزة بـ VB6 حتى لو لم تستخدم نافذة نموذج واحدة، بالاضافة الى كائنات اخرى غير مستخدمة. ومن جانب اخر، دعونا نكون واقعيين قدر الامكان ولنتجرد من عواطفنا واسألكم سؤال: ماهو VB6 دون النماذج والأدوات؟
من هذا المنطلق، سأتحدث اليوم عن النماذج والأدوات ونرى رمز حضارة إمبراطورية VB6 من رؤية سلبية:
1) الادوات لا زالت تعتمد ASCII
مع Windows NT، كانت بداية لرؤية مستقبلية واستراتيجية تاريخية بدأتها Microsoft، وهي فلسفة تدويل التطبيقات Internationalizing Applications ، حيث تقتضي هذه الفلسفة، الفصل التام بين الشيفرات المصدرية، وبين الاعدادات الإقليمية Regional Settings ولغة واجهة الاستخدام. ومن هذا المبدأ، بدأت نظم Windows NT هذا التوجه باعتماد الترميز العالمي UNICODE، ليكون حجر الاساس في تمثيل البيانات لجميع المبرمجين.
VB6 قد ادرك (مشكورا) هذا التوجه، ولكنه (كما ذكرت) يطبق ما يسمى التقليد الأعمى حيث ان جميع البيانات الحرفية (من النوع String) تعتمد ترميز UNICODE لتمثيل البيانات، ولكن النماذج والادوات لازلت تحت الاستعمار ASCII. وأعتقد ان الكثير من المبرمجين قد واجه الكثير من الصعوبات في عرض الحروف العربية على الأدوات ان تم لصقها من تطبيقات اخرى، او استخلاصها من نظم قواعد بيانات، وذلك (بالتحديد) ان كان نظام التشغيل لايدعم اللغة العربية مع تطبيقات ASCII، فلكي اتمكن من استخدام برنامج عربي يعتمد توزيع ASCII، علي دائما اللجوء الى لوحة التحكم Control Panel وتغيير الاعدادات لهذه النوعية من البرامج.
اما مع Windows Forms .NET (والتي تستخدمها بـ VB.NET)، فلن تحمل أي هم حول هذه القضية، اذ ان جميع النماذج والادوات تعتمد ترميز UNICODE بكل كفاءة.
2) الحاجة الملحة الى التصنيف الفرعي Subclassing
الأحداث Events التي تدعهما نماذج VB6 قليلة واصبحت غير كافية، السبب الذي حد من مبرمجي VB6 الى تقديم طلب اللجوء السياسي الى التصنيف الفرعي SubClassing. الغرض من هذا هو قنص الرسائل القادمة من نظام التشغيل لاتمام المهام المطلوبة في الوقت المناسب، وبهذا تتمكن من قنص جميع الاحداث التي تريدها.
ولكن مع Windows Forms .NET، فلست بحاجة الى التصنيف الفرعي وذلك لوجود جميع الاحداث التي تقنص رسائل نظام التشغيل نيابة عنك.
3) تقنية المرآة Mirroring
كان حلمي استخدام تقنية المرآة في VB6 لتطوير واجهات استخدام عربية السمات وخالصة المعاني، ولكن مع -الاسف الشديد- نهاية هذا الحلم اكتشفتها بعد الاستيقاظ من منامي، حيث تتطلب هذه التقنية (حتى تعمل بشكل صحيح) تغيير نمط النافذة الموسع Window Extended Style لحظة انشاء النافذة Create، و VB6 لايدعم حدث الانشاء، حيث ان اول احداثه هو Load والذي يتم تفجيره بعد انشاء النافذة، اما ان حاولت استخدام المشيد Initialize فلن يفيدك ذلك، اذ ان هذا المشيد يتبع لكائن النافذة Form Object وسيتم تنفيذه قبل الانشاء الفعلي للنافذة.
مرت الأيام، وقمت بمراسلة الكثير من المبرمجين طالبا من يعطف علي بكم شيفرة مصدرية، ولكن كل الاجابات تقول لا يمكنك الا توديع النماذج والعودة الى الاجراء CreateWindow (وهو احد اشهر اجراءات API).
قضيت اكثر من اسبوع، وكتبت برنامج يستخدم الاجراء CreateWindow حتى زاد عدد الشيفرات المصدرية عن المئات، وبعد تفكير جدي في الموضوع اكبر، اكتشفت ان العودة الى نومي واكمال مشاهدة الحلم افضل بعشرات المرات!
لن اطيل الحديث عن معاناتي (الي ايده في المية مش زي الي ايده في النار)، ولكن سأبشركم ببساطة ان لحظة انشاء النافذة يمكنك قنصها في Windows Forms .NET بـ VB.NET عن طريق الخاصية CreateParams وهي قابلة لاعادة القيادة Overridable.
4) نماذج MDI
عند الحديث عن نماذج MDI، فأسلوب VB6 -الغريب جدا- يعتمد على تحديد نافذة نموذج (واحدة فقط) من النوع MDI، وربط كافة النماذج الابنة Child وقت التصميم بها.
ولكن مع Windows Forms .NET، فيمكنك ربط نماذج MDI بنماذج ابناء وقت التنفيذ ايضا. ليس هذا فقط، بل يمكنك تغيير مليكة النماذج في أي وقت وفي أي مكان دون أي مشاكل. ويمكن لاي نافذة ان تكون MDI في أي وقت وان تكون (نفس النافذة) ابنة Child ايضا في وقت، كما تستطيع عرض اكثر من نافذة MDI في تطبيق واحد.
المزيد ايضا، لا يمكنك وضع الادوات على نماذج MDI، وقد تحتاج الى استخدام اداة PictureBox لعمل ذلك، اذا كان هذا الحل فكرته مرنة جدا، فتذكر متطلبات اشرطة التمرير الذي تتطلب منك كتابة عشرات الشفرات المصدرية ليتم وزنها بالشكل الصحيح، هذا ان علمت ان الاداة PictureBox سيتم محاذاتها ( اعلى او اسفل النافذة) بشكل تلقائي رغما عن انفك.
5) النماذج كفئات
تنصحك اغلب كتب البرمجة بالتعامل مع النماذج كفئات Classes، فهي تمكنك من تغليف Encapsulate الشيفرات وانشاء كائنات منها. ان كانت النماذج –كما تزعمون- فئات تقليدية، فهل يمكنني تعريف الواجهات Interfaces بها؟؟ وان كان يمكن فماذا عن COM؟ هل استطيع تبادل كائنات النماذج بين مكونات COM؟ طبعا لا. فان قمت بتطوير نافذة نموذج في مكتبة DLL، لن تستطيع تضمينها في مشاريعك الخارجية، ويبقى الحل الوحيد الذي يربطك بهذه النافذة هو استخدام فئات الجسور Bridge Classes وهو اسلوب اثبت فشله الذريع –خاصة مع الفئات الكبيرة.
ولكن مع Windows Forms .NET فالنماذج هي فئات حقيقية بكل ما تحمله كلمة فئة من معنى، ويمكنك ربطها واستخدامها بين المشاريع المختلفة كما تتعامل مع الكائنات الاخرى دون أي مشاكل.
6) وراثة النماذج
كما ذكرت في ردودي السابقة، الوراثة غير مدعومة في VB6، مما يعني ان وراثة النماذج Form Inheritance ليست مدعومة ايضا. وكما ذكرت ايضا، انني لن اتحدث عن الوراثة وما الذي تجنيه منها.
ان كنت تعتقد ان قوالب النماذج Form Templates قد تحاكي الوراثة، فيؤسفني اخبارك ان اعتقادك ليس في محله، فقوالب النماذج ماهي الا ميكانيكة تقوم بتوليد الشيفرات نيابة عنك وقت التصميم وليس التنفيذ، وان اكتشفت احد الأخطاء عليك اعادة تعديل هذه الاخطأء في كافة النماذج المستخدمة.
اما مع Windows Forms .NET فالنماذج –كما ذكرت قبل قليل- هي فئات حقيقة، وبالتالي يمكنك وراثتها كما ترث الاجيال من جذورها. وعند اكتشافك لاي خطأ في النافذية القاعدية Base Form، فيكفي تعديل هذا الخطأ فيها وسيتم تطبيقه على كافة النماذج المشتقة منها Derived Forms.
وماذا عن وراثة الادوات Controls؟؟ ايضا VB6 لايمكنك من تطوير الاداة، لذلك قد تضطر الى اللجوء الى اسلوب القاء الاحداث Event Casting ولكنه محصور على الاحداث التي توفرها وتدعهما الاداة فقط، كما انه يخالف قاعدة التغليف Encapsulation والذي يفصل الشيفرات المصدرية على اكثر من فئة، مما يزيد تعقيد الشيفرة.
ولكن مع VB.NET، فيكفي استخدام الكلمة المحجوزة Inherits وارفاقها باسم فئة الادوات التي تود اشتقاقها وراثية.
7) النماذج المحلية Localized Forms
في الفقرات السابقة ذكرت استراتيجية تدويل التطبيقات وطريقة انجازها، حيث تقتضي الفصل التام بين الشيفرات المصدرية ولغة واجهة الاستخدام او الاعدادات الاقليمية الاخرى. في VB6 كان يعتمد على ما يسمى ملفات المصادر Resource Files والتي اظهرت ضعفها الكبير، يكفي ان عملية تحريرها لا زالت تعتمد على الكتابة اليدوية في احد جداول هذه المصادر، ونحن الان نتحدث عن البرمجة المرئية Visual Programming.
ليس هذا فقط، بل ان اقصى ما تستطيع عمله هو تغيير القيم الحرفية على الادوات، حيث تقوم (انت بنفسك) بقراءة النصوص في ملفات المصادر وبرمجتها ليتم عرضها على جبهة الادوات، والتي –في اقصى الاحوال- استبدال قيم الخاصية Caption.
ولكن مع Windows Forms.NET فحسبك اسناد القيمة True الى الخاصية Localizable وستصبح نافذة النموذج محلية، حيث ان قيم خصائص الادوات ليست محصورة على الخاصية Text، بل تشمل اغلب الخصائص التي تتأثر بالاعدادات الاقليمية المحلية، كخصائص الموقع والحجم. وضع في عين الاعتبار، انك لن تحتاج الى فتح ملفات المصادر لتحرير النصوص ومن ثم كتابة الشيفرات، اذ ان كل ما ستفعله هو نفس الاسلوب المرئي في تصميم النماذج بنافذة مصمم النماذج –دون كتابة حرف واحد من الشيفرة المصدرية، ويمكنك اعداد التصاميم المختلفة لكافة الاعدادات الاقليمية المحلية في الخاصية Language.
هذه (بعض) المقتطفات من نماذج وادوات VB6، وهناك المئات من الفضائح والشوائب والقصور في نماذج VB6!
-- تركي