مروری بر برنامه‌نویسی رویدادگرا

‌مواظب باشید!

برنامه‌نویسی رخدادگرا یکی از الگوهای برنامه‌نویسی است که جریان برنامه را از طریق رخدادها ‌(Event)‌ کنترل می‌کند. این رخدادها می‌توانند از سمت دستگاه‌های ورودی مثل ماوس و کیبورد صادر شوند یا از طریق پیغام‌های صادر شده یک نخ یا فرآیند باشند. در این مقاله قصد داریم در مورد رخدادها و کنترل آنها در سیستم عامل ویندوز صحبت کنیم.
کد خبر: ۳۰۷۵۰۴

برای روشن‌تر شدن موضوع بگذارید یک مثال بزنیم: یک برنامه ‌Word‌ را باز می‌کنید و شروع به تایپ می‌کنید. مطالب تایپ شده همان لحظه نمایش داده می‌شوند. این عمل چطور اتفاق می‌افتد؟

وقتی شما کلیدی از صفحه کلید را فشار دهید، از طرف کیبورد یک وقفه صادر می‌شود که به سیستم عامل می‌فهماند که فلان کلید زده شده است. سیستم عامل با یک مکانیزم درونی پیغامی به نام ‌ WM_KEYDOWN‌ را در صف پیغام‌هاقرار می‌دهد. حال برنامه ورد این پیغام را دریافت کرده و مقدار کلید زده شده را در صفحه نمایش چاپ می‌کند. خوب، برنامه ورد این کار را چگونه انجام می‌دهد؟

وقتی شما یک برنامه ویندوزی می‌نویسید به یک فراخواننده ‌(Callback)‌ برخورد می‌کنید که وقتی پیغامی از طرف سیستم عامل صادر شد، توسط این تابع هندل می‌شود و عملیات مورد نظر انجام می‌شود. پس قبل از این‌که بحث را دنبال کنیم، بگذارید کمی در مورد مفهوم فراخواننده صحبت کنیم: فرض کنید شما یک برنامه نوشته‌اید که قصد دارد یک‌سری داده را مرتب کند و می‌خواهید در هر مرحله به‌یک روش آنها را مرتب کنید.

یک راه استفاده از تابع‌های مختلف برای مرتب کردن آن‌ها است. این روش ساده و درست است، اما فرض کنید شما کد خود را در یک کتابخانه قرار داده‌اید و برنامه‌نویس دیگری که قرار است از کتابخانه شما استفاده کند، نمی‌خواهد از متدهای مرتب‌سازی شما استفاده کند. در این‌جا کتابخانه شما در انجام این عمل ناتوان است‌، خب چه کار کنیم که دیگر برنامه نویسان بتوانند برای مرتب‌سازی از روش‌های دلخواه خودشان استفاده کنند؟

برای این‌کار شما نیاز به‌تعریف یک اشاره‌گر به‌تابع ‌(Pointer To Function)‌ دارید. برنامه‌نویس‌های دیگر با مقداردهی آن می‌توانند روش مرتب‌سازی خود را استفاده کنند برای تعریف اشاره‌گر به تابع در ‌C++‌ به روش زیر عمل می‌کنیم:

مقدار ‌returnType‌ نوع داده برگشتی را مشخص می‌کند. ‌callbackName‌ نام فراخواننده است و مقدارهای ‌ 1param‌¢‌2param‌ نشان‌دهنده متغییرهای ورودی‌اند. وقتی شما یک تابع را به یک فراخواننده می‌دهید، باید الگوی تابع مطابق با الگوی فراخواننده باشد. مانند کد زیر:

همان‌طور که مشاهده می‌کنید تابع ‌Callback‌ از الگوی ‌fp‌ تبعیت می‌کند یعنی یک ‌int‌ را به‌عنوان ورودی و یک ‌double‌ را به‌عنوان خروجی قبول می‌کند. بسیار خب حال که با فراخواننده آشنا شدیم، برویم سراغ اصل موضوع که گرفتن مقدار پیغام صادر شده توسط سیستم عامل است. ‌ ‌

شما به یک شیء از کلاس ‌ WNDCLASS‌(این کلاس نشان‌دهنده یک پنجره است) برای کنترل کردن پیغام‌های سیستم عامل نیاز دارید. فیلد ‌lpfnWndProc‌ را از کلاس‌WNDCLASS‌ مقداردهی کنید این فیلد یک اشاره‌گر به تابع است و از این الگو تبعیت می‌کند:

برای تعریف مقادیر ورودی و خروجی به لینک پاورقی رجوع کنید. ‌ ‌

به‌طور خلاصه ‌HWND‌ یک عدد صحیح است که کنترل‌کننده پنجره یا یک کنترل را در خود نگهداری می‌کند که پیغام برای آن صادر شده است. با مقدار ‌HWND‌ می‌توانیم تشخیص دهیم که پیغام برای کدام کنترل صادر شده است.

حال باید مقدار پیغام را بازیابی کنیم برای این‌کار با توجه به‌پیغام صادر شده مقدار ‌LPARAM‌ یا ‌WPARAM‌ را بازیابی می‌کنیم برای مثال ‌WM_KEYDOWN‌ شما با بازیابی ‌LPARAM‌ می‌توانید تشخیص دهید که کدام کلید فشار داده شده است‌. دیدید که کار سختی را برای هندل کردن پیغام‌ها و نمایش مقدار آن در صفحه نمایش داریم. این مشکل در زبان‌های ویژوال (زبان‌هایی که قابلیت ساخت ‌GUI‌ رابط کاربری را دارند) معمولا وجود ندارد و اشیای موجود در این زبان‌ها به‌صورت داخلی تمام کارها را انجام می‌دهند.

به‌طور مثال شما می‌توانید با قرار دادن یک باکس متنی، مقدار وارد شده توسط صفحه کلید را نمایش دهید. ولی خب ممکن است بخواهید که کاربر در تکست باکس فقط عدد وارد کند.

فرض کنید که این کار را با زبان‌های مثل ‌C‌ قرار باشد انجام دهیم. خب باید شما مقدار ‌WM_KEYDOWN‌ را بازیابی کنید و بعد آن را اعتبارسنجی کنید. در زبان‌های ویژوال با مقداردهی رخداد مربوط به ‌KeyDown‌، ‌می‌توانید مقدار کلید زده شده را بررسی کنید. ‌ ‌

این رخداد در واقع یک نماینده است و نماینده خود یک اشاره‌گر به تابع است و رخداد یک شیء از یک مقدار پیش‌فرض دارند که اگر رخداد توسط برنامه‌نویس مقداردهی نشد مقدار پیش‌فرض آنها فراخوانی می‌شود و کاربر می‌تواند آنرا مقداردهی کند و از آن استفاده کند. یا این‌که با ارث‌بری و بازنویسی متد مربوط به کنترل بدون مقداردهی رخداد متد خود را اجرا کند و یک کنترل سفارشی درست کند. مثلا باکس متنی که فقط عدد را به عنوان ورودی قبول کند.

مرجع: ‌http://msdn.com

امیربهاالدین سبط‌الشیخ

newsQrCode
ارسال نظرات در انتظار بررسی: ۰ انتشار یافته: ۰

نیازمندی ها