ببین قربون شکلت، بعضی وقتا لازمه یه تابع، یه تابع دیگه رو از طریق آدرسش صدا بزنه. چرا؟ چون که وقتی تابع اول رو می نویسیم، هنوز نمی دونیم داخل تابع دوم چه خبره. مثلا، شما فرض کن یه تابعی نوشتی که سعی می کنه تک تک پورتهای سریال روی کامپیوتر رو باز کنه تا ببینه که کدوم در دسترسه، و می خوای که هر پورتی که تست می شه، مطلع بشی. یه راهش اینه که بگی هر پورت که تست شد یه پیغام به یه پنجره خاص بفرسته، اما اگه برنامه ت کنسولی بود چی؟ بنابراین وقتی تابع شمارنده رو می نویسی، یه پارامتر اون رو به اشاره گر به یه تابع با یه prototype مشخص در نظر می گیری. مثلا پارامتر اول تابع beginthread_ از نوع زیر هست:
void( __cdecl *start_address )( void * )
یعنی تابعی که مقدار برگشتی اون void و پارامتر اون *void می باشد. البته beginthread_ که می دونی تابع شمارنده نیست، فقط به عنوان یه مثال آوردم. حالا تو ویندوز یه سری از توابع (به ویژه توابع شمارنده) هستن که با هر بار شمارش یه تابع دیگه رو از روی اشاره گرش صدا می زنن تا اون تابع با اون مورد شمارش شده (در اینجا پنجره فرزند شمارش شده) هر کاری که صلاح می دونه انجام بده. Calling convention این نوع از توابع رو CALLBACK در نظر می گیرن.
Prototype تابع EnumChildWindows به صورت زیره:
BOOL EnumChildWindows(
HWND hWndParent, // handle to parent window
WNDENUMPROC lpEnumFunc, // callback function
LPARAM lParam // application-defined value
);
و تابع CALLBACK اون:
BOOL CALLBACK EnumChildProc(
HWND hwnd, // handle to child window
LPARAM lParam // application-defined value
);
بازم اگه سوالی هست در خدمتیم.
با تشکر از MSDN