مدونة سلوان الهلالي

تطوير ألعاب - برمجة - علم نفس

توسعة فيجوال ستوديو: SourceCreator

لو سألت اي مبرمج سي++ ما هو اكبر نشاط مضيع للوقت عند العمل على مشاريع سي++؟

بالنسبة لي فهو انشاء ملفات الكود المصدرية والرأسية باستمرار لكل صنف، ثم كتابة الهيكل الرئيسي للصنف في الملف الرأسي، ثم ملئ الملف المصدري،… بعد عدة اصناف يصبح الموضوع غير جميل ابداً.. تصوروا عمل نفس الخطوات تماماً كل مرة لـ 50 صنف، الكثير من الجهد الضائع.

 

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

اعتقد ان سي++ هي اللغة الوحيدة التي لا زالت كما هي تقريباً في هذه النقطة بالذات منذ سنوات.

 

الآن، انا احاول العودة لسي++ بعد فترة من عدم الاستخدام، وأجد نفسي في مواجهة نفس المشكلة القديمة.. حسناًـ حان وقت التعامل معها…

 

ماذا احتاج لكي اجعل الموضوع اسهل؟

احتاج لأداة تستطيع انشاء ملفات الاصناف بشكل اوتوماتيكي، ثم ملئها بكود موحّد لتعريف الصنف، ثم اضافتها للمشروع في فيجوال ستوديو.

فيجوال ستوديو يأتي مع قدرة ممتازة للتخصيص، وابسط طريقة لانشاء ادوات عملية هي عن طريق الماكروات (Macros) (لا علاقة لها بماكروات سي)، حيث يأتي مدمجاً مع فيجوال ستوديو بيئة تطوير كاملة خاصة بالماكرو، كذلك يمكن تسجيل نشاط معين في ماكرو بشكل اوتوماتيكي (يمكن الدخول لكل ادوات الماكرو عن طريق Tools –> Macros).

 

القيت نظرة سريعة على الماكروات، ولكن لم يعجبني الامر، اولاً لأن اللغة المستخدمة هي لغة بيسك وثانياً، يبدو ان الماكرو مخصص للمهام البسيطة ولكن قد يكون ذلك هو انطباعي لأن الامثلة المقدمة بسيطة جداً كما أني لم اعمل على لغة بيسك منذ سنة 2005.

 

لذلك انتقلت للطريقة الاخرى، وهي اكثر قوة بالتأكيد، انشاء التوسعات (Add-ins) باستخدام فيجوال ستوديو (عند انشاء مشروع جديد اختر Visual Studio Add-in من Extensibility)، اول ميزة لهذه الطريقة هي امكانية كتابة التوسعات باستخدام اي لغة برمجة مدعومة، اخترت سي شارب.

المزايا الاخرى هي امكانية بناء نوافذ Windows Forms اعتيادية وكأنك تعمل على تطبيق عادي، وكذلك يمكن فحص عمل التوسعة وحتى عمل Debugging من داخل فيجوال ستوديو، حيث يقوم فيجوال ستوديو بتشغيل فيجوال ستوديو آخر لكي تجرب فيه التوسعة!

 

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

 

يمكن تشغيل الأداة من قائمة Tools لفيجوال ستوديو وهي تحمل الاسم Source Creator، يجب ان يكون هنالك مشروع سي++ مفتوح فعلاً لكي تعمل، ستظهر النافذة الآتية لحظة التشغيل:

 

 Source CreatorWindow

 

يمكنك ان تحدد المشروع إن كان هنالك اكثر من مشروع مفتوح من حقل Project، الاداة ستختار دائماً اول مشروع مفتوح تجده بشكل اوتوماتيكي.

حقل Class Name و Base Class Name هما لأسم الصنف واسم الصنف الأب.

عندما تقوم بأدخال اسم الصنف، تولّد الأداة بشكل اوتوماتيكي اسماء للملف الرأسي و المصدري، يمكنك بالطبع تغيير أسماء الملفات كما يعجبك.

عندما تنقر على Finish، سوف يتم انشاء الملف الرأسي والمصدري للصنف ثم اضافتهما لمجلّدي Source Files و Header Files (الأداة ستنشئهم إن لم تجدهم).

 

ولكن ماذا عن محتوى الملف الرأسي والمصدري؟

إن تم استخدام الأداة بشكل مباشر كما هي، سوف يتم ملئ الملفات باستخدام هذا الهيكل البسيط:

 

للملف الرأسي:
   1: #pragma once
   2:  
   3: class ClassName : BaseClass
   4: {
   5: public:
   6:     ClassName();
   7:     virtual ~ClassName();
   8:  
   9: private:
  10:  
  11: };

 

للملف المصدري:
   1: #include "HeaderFile.h"
   2:  
   3: ClassName::ClassName()
   4: {
   5: }
   6:  
   7: ClassName::~ClassName()
   8: {
   9: }

 

ولكن، هذه العملية لا تحل المشكلة تماماً، حيث ان تعريف الصنف لا يكون بهذه البساطة عادة.

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

  • hfile.template
  • cppfile.template

بعد انشاءهما قم بإضافتهما للمشروع في فيجوال ستوديو، يجب ان يكون موقعهما تحت المشروع مباشرة وليس في داخل أي مجلد، ويمكنك تعريف قالب مختلف لكل مشروع.

 

ملف القالب الخاص بالملفات الرأسية يمكن تعريفه بهذا الشكل (مثال):

   1: #ifndef _{ClassDefName}_HEADER_
   2: #define _{ClassDefName}_HEADER_
   3:  
   4: #include <libheader.h>
   5: #include "something1.h"
   6: #include "something2.h"
   7:  
   8: class {ClassName} : {BaseName}
   9: {
  10: public:
  11:     {ClassName}()
  12:     {
  13:     }
  14:     
  15:     virtual ~{ClassName}()
  16:     {
  17:     }
  18:     
  19:     void DoSomething()
  20:     {
  21:     }
  22:     
  23: private:
  24:     bool        someFlag;
  25:     
  26: };
  27:  
  28: #endif

اما القالب الخاص بالملفات المصدرية فيبدو هكذا (مثال):

   1: #include "{ClassHeader}"
   2:  
   3: {ClassName}::{ClassName}()
   4: {
   5: }
   6:  
   7: {ClassName}::~{ClassName}()
   8: {
   9: }
  10:  
  11: void {ClassName}::DoSomething()
  12: {
  13:     if(someFlag)
  14:     {
  15:         printf("What do you want me to do?");
  16:     }
  17: }

 

بعد اضافة القوالب، إن قمت بتشغيل الأداة، سوف يتم استخدام القوالب اوتوماتيكياًَ.

 

حالياً، تدعم التوسعة الثوابت الآتية:

  • {ClassDefName}
  • {ClassName}
  • {BaseName}
  • {ClassHeader}

ومن السهل جداً اضافة ثوابت جديدة او تعديل الثوابت الموجودة من داخل كود التوسعة (لكن لا تنسى اعادة بناءها ثم تحديث ملف SourceCreator.dll لديك).

 

وفي النهاية، بعد انشاء الملفات، سوف تقوم الأداة بفتحها في فيجوال ستوديو، فقط لكي تعرف كم انت مدلّل… :)

 

تحميل الكود الكامل مع التوسعة جاهزة للاستخدام (public domain)

 

للتنصيب قم بنسخ الملفين: SourceCreator.Addin و SourceCreator.dll الى المسار الآتي الموجود لديك: My Documents\Visual Studio 2008\Addins

عند تشغيل فيجوال ستوديو، ستجد الاداة في قائمة Tools هكذا:

 

Source Creator

إن لم تجدها، فهي غير مفعّلة على الأكثر، لتفعيلها ادخل من Tools واختر Add-in Manager، قم بالتأشير امام التوسعة وإن أردت يمكنك تأشير الخيار Startup ايضاً لكي يتم تحميل التوسعة اوتوماتيكياً عند تشغيل فيجوال ستوديو:

Add-in Manager

 

إن واجهتك اي مشاكل في الاستخدام، فلا تتردد في طرحها هنا!

 

ملاحظة مهمة: استخدمت فيجوال ستوديو 2008 لإنشاء التوسعة، هل تدعم الاصدارات الاقدم او الاحدث؟ لا علم لي!

التعليقات (1) -

  • وسام البهنسي

    15/10/2010 06:21:32 م | الرد

    عمل ممتاز يا سلوان!

    لقد مررتُ بنفس تجربتك، لكني أخذتُ طريق الماكرو والفيجوال بيسك. سأضيف تدوينة إن شاء الله أضع فيها الماكرو الخاص بي (والذي يحوي بعض المزايا الإضافية غير إعداد ملفات h. و cpp.) كي تطلع عليه.

أضف تعليقاً

Loading