الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

استخدام ال CALLBACK مع الفئات CLASS

مغلق
بدأه mhammad في 27 مارس 2003 · 2 رد · 862 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

كيف تستخدم وظائف من نوع CALLBACK كوظائف أعضاء في فئة CLASS ؟

هناك الكثير من التوابع التي تقوم بعملية عد وارجاع قيم مفيدة مستخدمة في نظام التشغيل للمبرمج ، مثلا:

EnumWindows //تعيد قائمة بجميع النوافذ في النظام

EnumFonts //تعيد لائحة بأنماط الخطوط المستخدمة في الجهاز

EnumObjects // تعيد لائحة بالأقلام والفراشي الخ .. المستخدمة في device context معين

الخ ...

هذه التوابع تحتاج الى بارامتر وهو عبارة عن مؤشر الى تابع آخر من النوع CALLBACK ليقوم بعملية ارجاع القيم وارسالها الى التابع Enum ، هذه التوابع استخدامها سهل في السي ولكن قد تواجهك بعض المشاكل عند استخدامها في السي ++ مع الفئات .

مشكلة هذه التوابع أن لكل منها نموذج معين prototype معروف من قبل نظام التشغيل لانستطيع تغييره ومعرفة على أساس أنها توابع C أي قبل ظهور السي ++ والفئات ، في هذه الفقرة سوف أشرح لماذا لا نستطيع استخدام التوابع الأعضاء كتوابع CALLBACK

-البارامتر الخفي ( المؤشر this )

كيف تتعرف الفئات على التوابع والمتغيرات الأعضاء ، دعونا نأخذ مثال

CExample{

int nNum;

void print(char* ch);

BOOL CALLBACK EnumWndProc(HWND hwnd,LPARAM lparam);

}

.

.

CExample example;

void CExample::print(char* ch);

فغن المترجم يضيف لها المؤشر this كبارامتر اخير لكي يحدد الى أي فئة تنتمي فتصبح

void CExample::print(char* ch,(CExample*)&example);

nNum = 0;

تصبح

this->nNum = 0;

هنا المهم ان نعرف أن المترجم يضيف هذا البارامتر للوظائف والمتغيرات الأعضاء ومن خلاله تستطيع الوصول الى بعضها .

نعود هنا الى ال CALLBACK عند استخدام هذا التابع هكذا

BOOL CALLBACK CExample::EnumWndProc(HWND hwnd,LPARAM lparam);

فإنه سيتسبب بخطأ أثناء التنفيذ run time error ، والسبب أن نظام التشغيل يقبل بارامترين فقط لهذا التابع ولكن بما أنه هنا عضو في فئة فسيُلحق به المترجم بارامتر ثالث وهو this مما يؤدي الى اضافة قيمة عشوائية للتابع مما يتسبب بتحطيم البرنامج .access violation

الخلاصة : علينا أن نخبر المترجم أن لا يلحق المؤسر this لهذا التابع ، وهناك طريقتين لعمل ذلك :

1- تعريف التابع على أساس أنه nonmember function ليس عضو بأي فئة وبمعنى آخر global function عام .

طبعا التابع العام لا ينتمي لأي فئة وبالتالي لن يضيف له المترجم المؤشر this .

2- تعريف التابع على أساس أنه static function تابع ساكن .

التابع الساكن لا يأخذ المؤشر this لأنه ينشأ أول شئ في البرنامج ويستطيع أي تابع عضو ضمن الفئة الوصول اليه بدون تعريف غرض من الفئة .

على كل أرفقت هنا مثال لعمل EnumWindows واستخدمت الطريقة الأولى global function ، المثال باستخدام MFC ويعرض لك اسم النافذه والكلاس مع قيمة مقبض النافذة داخل أداة التحكم List control .

لمزيد من المعلومات حول الموضوع

http://msdn.microsoft.com/archive/default..../msdn_callb.asp

enum.zip

#2

ألف شكر أخي محمد على هذه المواضيع المفيدة..

وفي إنتظار المزيد.

#3

العفو أخ اسماعيل (f)(f)

هذا الموضوع مغلق.

مواضيع مشابهة