برگزیده های پرشین تولز

ويژوال سي -- مفاهيم

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
همان طور كه از اسم تاپيك معلومه ، قصد استفاده از دانش دوستان را داريم و بي مدد ايشان اين تاپيك بي معناست.
آدرس تاپيك اصلي:


.
.
.
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
من به عنوان كسي كه مقداري با سي آشنايي دارد و علاقه مند يادگيري ويژوال سي است ، چند تا سئوال دارم:

در سي يكسري ساختار داريم ، مثل حلقه و struct و كلاس و مابقي ، كه مثل اسكلتي مي ماند براي ساختمان.

بعدش يك سري توابع آماده در كتابخانه ها داريم .
كه شايد اين توابع يك قسمت اضافه باشه بر خود سي ، يعني سي فقط همان توابع كليدي باشد و توابع ، براي راحتي برنامه نويس به كامپايلر سنجاق شده .
يعني نوعي وسيله تبليغي فروشنده كامپايلر باشد.

حالا من كمي ساختارها و توابع سي را بلدم.
و كلا اين جوري دستم اومده كه بايد اول ساختارها را بشناسم و بعد درون ساختارها از توابع استفاده كنم. كه تقريبا توابع سي همه كار براي ما انجام مي دهند.

= == == == === ==== === ==== ====
حالا برويم سر اصل مطلب، يعني ويژوال سي:
در ويژوال سي مسلما اوضاع از حالت ساده سي پيچيده تر است . مثلا يك دليلش اين مي تونه باشه كه با ويندوز ارتباط برقرار مي كنه.

حالا اولين سئوالم اينه. البته حالت سئوال هم نداره. اون اينه كه چطور يك نگاهي به طرز كدنويسي در ويژوال سي داشته باشيم.

الف آيا آنجا هم مثل سي ، تابع ها هستند؟
ب ساختارهاي آنجا چه تفاوتي دارند با ساختارهاي سي. آيا اصلا ساختار مشخصي وجود دارد؟
ج كلاسهاي آنجا چه فرقي با كلاسهاي سي دارد. البته هنوز كلاسهاي سي را هم من بلد نيستم. اگر خواستيد اين سئوال را جواب ندهيد.
د من كمي به ويژوال بيسيك آشنايي دارم. آيا پاسخ به رويدادها ، مثل ويژوال بيسيك است؟ و ميشه مثل ويژوال بيسيك كل كدها را به چند قسمت تقسيم كرد و يك قسمت را پاسخ به رويدادها(مثل كليك) دانست؟
ه وظيفه wizard ها چيه؟ آيا فقط كارشون اينه كه بسته هايي از كدهاي از قبل نوشته شده را به برنامه ما اضافه مي كنند؟

اگر منبعي داشتيد كه پاسخ مرا بهتر مي شد توسط آن داد بگوييد.
.
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
بسم الله الرحمن الرحيم.
قبل از اين كه اساتيد از راه برسند تا به سئوالات جواب بدهند ، من كمي محيط ويژوال سي را مي گويم.
فعلا چون مي ترسم باز به كتاب sams پناه مي برم. ولي بعدا ممكنه باز مثل تاپيكهاي ديگر ، از هر منبعي ، سخني، بشود.

البته فعلا اول معرفي محيط را مي گوييم. ولي اگر ديدم راحته كار در محيط ويژوال سي ، كلا اديتور خود را از ((توربو سي)) به ((ويژوال سي)) تغيير مي دهيم . اما اگر ديديم كه نه ، زيادي دردسر دارد ، تمرينات سي را در همان ((توربو سي)) ادامه مي دهيم.

علت اين كه من تمايل به تغيير كامپايلر دارم اينه كه از محيط هاي dos ئي فراري ام. البته همه فراري اند. بعد از كمي آشنايي به محيط ((ويژوال سي)) من دستم باز ميشه بروم دنبال سورس ويژوال سي و كار در ويژوال سي راحت تر ميشه.

به اميد خدا.
.
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها

Welcome to Sams Teach Yourself Visual C++ 6 in 21 Days.

اين اسم اين كتاب بود. Ebook است و 6 مگا. من دانلود نكرده ام. يك سي دي بود پر آموزش و اين هم داخلش بود.

فعلا فصل اولش را آپلود كردم. البته نياز به مراجعه نيست. چه متن و چه عكس را من در تاپيك نقل مي كنم.

http://saalekj.250free.com/vcsams/ch01/ch01.htm
 

Arash_j13

Registered User
تاریخ عضویت
18 فوریه 2005
نوشته‌ها
778
لایک‌ها
2
محل سکونت
مشهد
د مرود ویژوال سی من چند از سوال ها رو نصفه و نیمه جوابش رو بلدم

زبان در ویژوال همان C++ خودمان است

در مورد رویداد ها
بهتره شما برای برنامه نویسی با ویژوال سی دیدتون به برنامه نویسی رو از برنامه نویسی ساخت پافته به برنامه نویسی شی گرای تغییر بدید چون ساختار ویژوال این گونه است که هر هر چیزی یه آبجکت هست و هر پنجره (منظور از پنجره تمام اجزای سیستمی ویندوز مثل باتن ادیت یا حتی ویندو ها) یه تابع داره برای پردازش یغام ها شما باید این تابع رو کنرتل کنید
 

saeedsmk

مدیر بازنشسته
تاریخ عضویت
6 سپتامبر 2003
نوشته‌ها
1,518
لایک‌ها
4
سلام
بله ساختار ها و توابع و بقيه چيز ها در vc وجود دارند ( سازگاري تا 98 درصد با c++)
منظورت از اين سئوال رو نفهميدم ؛آيا اصلا ساختار مشخصي ؛
ساختار ها بر اساس شي گرايي يا ابجت نويسي ساخته شده اند البته حالت معمولي هم موجود است در كل ميشه گفت يه مقداري تفاوت هاي بر اساس تفاوت برنامه تحت داس و ويندوز بين كد ها وجود داره
تمامي برنامه هاي تحت ويندوز كه داري پنجره هستند خاصيت جواب گويي به evnt ها رو دارن دارند مگر اينكه به حالت كنسولي نوشته شده باشند
شما هنگامي كه ميخواهيد يك برنامه بسازيد در بشتر موارد ساخت فرم ها و منوها و ديگر اجزا بصورت عمومي وقت گير هستند و بايد تك تك ايجاد شوند . اما با كمك ويزاردها شما توانايي ساخت حالت هاي پيش فرض رو سريع داريد و بعد با تغييرات متناسب با هدف ميتونيد اون پروژه رو با نياز هاتون به سرعت هماهنگ كنيد . در كر ويزاردها به شما كمك ميكنن تا در وقت صرفه جويي نماييد و در بعضي از موارد با اشتباهات جزئي و كلافه كننده دست و پنجه نرم نكنيد. كد ها معمولا در بيشتر برنامه هاي تحت ويندوز ثابت اند( منظورم كد هاي اصلي است ) پس اين ويزاردها اين كدها را به پروژه شما اضافه ميكنند

يه توضيح نه چندان مزتبط و كلي
هنگامي كه يك برنامه تحت ويندوز رو اجرا ميكنيد . بجز توابع اوليه و ... در بيستر موارد برنامه به رويداد ها پاسخ ميگويد .
شما هنگامي كه يه برنامه تحت ويندوز مينويسيد ( نه حالت كنسولي ) يه تابع مركزي تعريف مكنيد كه كار اين تابع در واقع هندل كردن مسيج هاي رسيده از ويندوز است ( چون سيستم حالت مولتي پروسس دارد) . بر اساس اين مسيج ها و تعريف هاي انجام شده برنامه عملي را انجام ميدهد . اگر مسيج ايكس از طرف ويندوز فرستاده شود و در تابع اصلي با دريافت اين مسيج عملي بايد انجام شود ميگويند كه رويداد برنامه ريزي شده اي اتفاق افتاده است . در اين حالت است كد برنامه نويسي شده از قبل فعال ميگردد. و برنامه به اين مسيج جواب ميدهد
در كل برنامه شما از يك هسته پروسس كننده مسيج و توابع برنامه نويس شده توسط برنامه نويس كه در برابر بعضي از مسيج ها عملي را انجام ميدهد و توابع پيش فرض ويندوز تشكيل شده است. احتمال دارد شما براي مسيجي تابعي در نظر نگرفته باشيد ( مثلا رويداد ريسايز شدن فرم) ويندوز تابع پيش فرض را صدا زده و فرم شما را ريسايز ميكند

اميدوارم كمك كنه
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
به نقل از mohammad_110 :
VC++ رو اجرا کنید . بعد یک پروژه MFC ایجاد کنید ، به tab مربوط به فایلها برید همونطور که گفته بودید می بینید که به ازای هر کلاس یک فایل cpp. و یک فایل h. ایجاد شده . در فایل h. معمولا تعریف کلی کلاس مطرح میشه مثل تعریف متغییر ها و شکل کلی توابع و خصوصی و عمومی بودن اونها ، ولی در cpp. متن اصلی توابع کلاس مطرح میشه .

با سلام و با تشكر از دوستان عزيز.
من تمام صحبتهاي شما را فهميدم و به خواسته خود رسيدم. صحبتهاي آقا سعيد را ميشه يك خلاصه اي از ويژوال سي دانست.
البته من انتظار ندارم كه يك فرد مبتدي بتواند صحبتهاي شما را درك كند.
و من رابط بين شما و خواننده خواهم بود.
يعني بعدا موبمو تك تك كلماتي را كه شما بكار برده ايد ، دوباره تكرار و بحث ميشه.
من تابحال كدنويسي در ويژوال سي كار نكرده ام.
ولي با اصطلاحاتي كه آقا سعيد به كار برد اشنا هستم. يك سري ((سي دي)) آموزش ويژوال سي را گوش كردم(بدون تمرين) و تمام مفاهيم كمي برايم آشناست.
و راهنمايي محمد برايم جالب بود. شايد خيلي ها خواسته اند ويژوال سي كار كنند ولي وقتي يك ويزارد كوهي از كد مي ريزه جلوي آدم ، آدم جا مي خوره. من كه اين طوري بودم. بقيه را نمي دانم.
من خط دهي اوليه را گرفتم. از فرمايشات آرش فهميدم كه مثل ويژوال بيسيك است قضيه يعني هر شي به رويدادي پاسخ مي دهد. البته آقا سعيد هم اين قضيه را فرموده بود. ولي من از آرش جان اين را گرفتم.
مي خواهم بگويم كه دو جمله مشابه مي تواند تاثيرات مختلف داشته باشد. از گفته يك نفر چيزي من نمي فهمم و وقتي همان حرف را فرد دوم مي زند ، ما مي فهميم. اين بخاطر ارتباطات روحي است نه شكل ظاهري كلمات.
در كل مي خواهم بگويم من چندين كتاب آموزش ويژوال سي دارم. اگر بخواهم خودم بخوانم، بايد 1 سال وقت بگذارم. چون اين روح منه كه جملات زنده را از جملات مرده كتاب بايد بسازه. ولي با كمك گرفتن از دوستان من به راحتي با ذهن زنده دوستان ارتباط برقرار مي كنم و سريع كار مي رود جلو.
نمي خواستم وارد بحث روح و اينها بشوم. ولي ما در قضيه آموزش اين چيزها را نديده مي گيريم و بي جهت فقط به خود فشار مياوريم و بازده و سرعت كاري هم نداريم.
نكته اي كه محمد عزيز در طبقه بندي كدها در فايلهاي مختلف گفت خيلي برام جالب بود.
پس من سعي مي كنم كه كدنويسي را شروع كنيم و بعد آنجا از حمايتهاي دوستان بهره بگيريم.
فقط آرش جان برنامه ساخت يافته و فرقش با رويداد گرا را اگر ميشه بيشتر توضيح بدهيد. من حدودي مي تونم بگم ها ولي فكر كنم زبان شما گويا تر است چون احاطه بيشتري داريد.
چون ما وقتي داريم از سي به سمت ويژوال ها مي رويم ، اين اتفاق هم مي افتد.يعني از برنامه ساخت يافته ، به حالت رويدادگرا مي رويم.
حالا من دو جمله مي گم اگر غلط بود يا به جنبه هايي توجه نشده بود ، تصحيح كنيد.
در برنامه هاي ساخت يافته ، مثل همين سي كه تاحالا كار مي كرديم. ، برنامه از خط اول شروع به اجرا مي كند ، و مي رود تا....برسد به خط آخر. و ما با حلقه و شرط و ...و بقيه ساختارها ، جريان رو به پايين اجرا را كنترل مي كنيم.
يعني گاهي كنترل را به بالا دوباره پرتاب مي كنيم و گاهي به پايين تر مي فرستيم. مثل بازي مارپله. كه يكسري نردبان و مار دارد. بعضي ها كنترل را بالا مي فرستند بعضي پايين. ولي كنترل بايد از خانه اول حركت كند و به خانه آخر برسد.
ولي در برنامه هاي رويدادگرا-- البته من ويژوال سي كار نكرده ام ، از ويژوال بيسيك دارم مي گم -- هر ابزار مثل دكمه و فرم و چيزهاي ديگه خودش مي تواند كنترل را به كار اندازد.
من ساخت يافته ها را مثل رودخانه اي مي دانم كه فقط يك سرچشمه دارد ولي رويدادگرا را مثل محوطه اي مي دانم كه از هر جا چشمه اي جوشيده و بايد آب همه را كنترل كرد تا هرز نرود.
در مثال رودخانه شما بايد از اب پر قدرت رودخانه همه نيازهاي خود را برطرف كنيد ، مثلا به توابع و كلاسهاي برنامه خود جاري كنيد كنترل را تا جان بگيرند(اجرا شوند) ولي در رويدادگرا هر ابزار خودش پادشاهي است كه كنترل به آن هم داده شده است.
.
 

saeedsmk

مدیر بازنشسته
تاریخ عضویت
6 سپتامبر 2003
نوشته‌ها
1,518
لایک‌ها
4
مثال رود خانه خيلي جالب بود . مثال قشنگي بود .
 

Arash_j13

Registered User
تاریخ عضویت
18 فوریه 2005
نوشته‌ها
778
لایک‌ها
2
محل سکونت
مشهد
سالک جان مثال رودخانه خیلی خوب تقریبا یه چیزی تو همین مایه هاست

البته من نگفتم رویدادگرا گفتم شی گرا (oop)

یه توضیح کوچولو هم همین جا بگم
برنامه نویسی رویدادگرا هم به صورت خطی اجرا می شه فقط اون وسط توی یه حلقه گیر می کنه که شرط خاتمه ی حلقه بستن برنامه است و توی این حلقه منتظر پیغام ها ویندوز می می مونه
 

mohammad_110

کاربر فعال برنامه نویسی
کاربر فعال
تاریخ عضویت
22 ژانویه 2006
نوشته‌ها
60
لایک‌ها
0
سلام

امروز یخورده خیالم از اخراجی راحت شد.:D

یه نکته که شاید همه بدونند ولی بد نیست گفته بشه :

ما در ++C کلی تابع داشتیم ، ولی باید حتما تابع main در برنامه وجود داشته باشه . در واقع اولین تابعی که در ++C اجرا میشه تابع main هست.

اما در ++VC ما تابع main نداریم . در عوض حتما باید شیئی از کلاس CWinApp ایجاد کنیم . بدون این شیئ برنامه اجرا نمی شود. و در واقع یه جورایی این شیئ در ++VC ، کار تابع main در ++C رو انجام میده .

باور نمی کنید می تونید یک پروژه MFC ایجاد کنید (از هر نوعی که دوست دارید) . بعد برای مطمئن شدن از درست بودن برنامه یک بار اون رو اجرا کنید. حالا از tab مربوط به class view روی شاخه Globals کلیک کنید ، بعد روی شیئ theApp دبل کلیک کنید . خطی که کرسر در آنجا قرار می گیرد را با // به توضیحات تبدیل کنید . حالا برنامه را اجرا کنید . می بینیم که برنامه بدون error و یا warnning کامپایل می شود ولی اجرا نمی شود و یک error از طرف windows می گیریم.

در واقع این شیئ theApp از مشتقات کلاس CWinApp بوجود آمده . اگر اسم پروژه ای که ایجاد کردید Myproject باشد . حتما کلاسی با نام CMyprojectApp خواهید داشت. این کلاس از CWinApp مشتق شده و شیئ theApp هم از کلاس CMyprojectApp بوجود آمده است.

برنامه های ++VC بیشتر شبیه به یه مشت کلاس میاد که با هم کار می کنند ، شبیه به ++C که بیشتر یه مشت تابع بودند که با هم کار می کردند.

در ++VC هر کلاس مخصوص به کار خاصی بوجود اومده و سعی میشه تمام کارهای مربوط به اون قسمت فقط توسط همون تابع انجام بشه . وقتی شما تابع پاسخ به رویدادی رو می خواهید ایجاد کنید، این پاسخ به رویداد ممکن است که مربوط به دکمه ای باشد که در فرمی قرار دارد و این فرم حتما مربوط به کلاسی میشه بنابراین تابع پاسخ به رویداد کلیک شدن این دکمه ، در این کلاس قرار می گیرد .

اگر یک پروژه MFC از نوع Dialog Base ایجاد کنید و به class view نگاه کنیم ، سه کلاس می بینیم :
CAboutDlg : که در همه برنامه های MFC وجود داره و مربوط به دیالوگ توضیحات در مورد نویسنده برنامه میشه
CMyprojectApp : که در همه برنامه ها هست و راجع بهش صحبت کردیم
CMyprojectDlg : که در برنامه های Dialog Base وجود داره و مربوط به دیالوگ اصلی میشه و وقتی برنامه رو اجرا می کنیم دیده میشه .

(به نحوه اسم گذاری کلاسها هم توجه کنید که برای کلاسهای مربوط به دیالوگ سه حرف Dlg در انتهای اسم اضافه میشه)

اگر پروژه Single Document ایجاد کنید این کلاسها رو می بینیم:
CAboutDlg
CMyprojectApp
CMainFrame: که اگر به توابعش نگاه کنیم بنظر میاد مربوط به قاب دور برنامه میشه و toolbar ها و Status bar در اون قرار می گیرند.
CMyprojectDoc : که درست یادم نمیاد چکار میکنه . ولی توابع سریالی کردن داده ها برای ذخیره شدن در فایل در این کلاس قرار میگیره .مثلا اگر یک برنامه نقاشی نوشتیم و می خواهیم اونرو ذخیره کنیم، تغییرات لازم رو می تونیم در این کلاس ایجاد کنیم .
CMyprojectView : کنترل چیزی که در صفحه به نمایش میاد رو بعهده داره . مثلا اگر چیزی بخوایم بنویسیم یا شکلی بکشیم حتما باید در این کلاس تغییرات ایجاد کنیم .
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
شي گرا با رويداد گرا فرقش چيه آرش جان؟

محمد جان اين بار هم با پست خوبت مواضع دشمن را حسابي كوبيدي. مثل پست قبلت.
دشمن منظور كدهاي ترسناك ويژوال سي است.
.
 

mohammad_110

کاربر فعال برنامه نویسی
کاربر فعال
تاریخ عضویت
22 ژانویه 2006
نوشته‌ها
60
لایک‌ها
0
به نقل از saalek :
ج كلاسهاي آنجا چه فرقي با كلاسهاي سي دارد. البته هنوز كلاسهاي سي را هم من بلد نيستم. اگر خواستيد اين سئوال را جواب ندهيد.

همونطور که می دونید سعی میشه وقتی ورژن جدیدی از برنامه به بازار میاد سازگاری خودش رو با ورژن قبلی حفظ کنه . پس هر چیزی که در مورد کلاسها در ++C استفاده میشد با احتمال 99 درصد در ++VC هم اجرا میشه . البته ممکنه در ++VC قواعد کاملتری وجود داشته باشه که من یادم نمیاد.

اما در VC++.net قواعد خیلی کاملتر و هیجان انگیزتری برای کلاسها وجود داره که باعث میشه کارهایی رو که قدیم خودمون باید رعایت می کردیم بصورت قاعده مندی در بیاد.



د من كمي به ويژوال بيسيك آشنايي دارم. آيا پاسخ به رويدادها ، مثل ويژوال بيسيك است؟ و ميشه مثل ويژوال بيسيك كل كدها را به چند قسمت تقسيم كرد و يك قسمت را پاسخ به رويدادها(مثل كليك) دانست؟

ویژوال بیسیک بنظر من بیشتر ماژول گرا هست (اون پستهای تاریخی در تاپیک شیئ گرایی رو نگاه کنید) و هم اینکه یه جورایی شبیه به همین ++VC هستش . به نظر میاد که تمام توابع و متغییر ها در یک صفحه داره نوشته میشه در حالیکه این صفحه مربوط به توابع و متغییر های فرم هست. به نظر میاد که این صفحه که متغییرها و توابع فرم در اون نوشته میشه چیزی شبیه به فایهای cpp. در ++VC باشه.
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
محمد جان من پست شما را هنوز نخوانده ام. پست خودم را ارسال مي كنم بعد پست شما را مي خوانم.
================
يك مقدار سعي مي كنم به سئوالي كه از آرش كردم خودم جواب دهم . البته ممكنه تصوراتم از پايه غلط باشه. ميگم تا اصلاح بشه.

اولا : آيا براي پاسخ به يك رويداد ، يك شي لازمه؟
اگر اين طوري باشه ، تمام برنامه هاي رويدادگرا ، شي گرا هم هستند.

دوما : c++ شي گراست. ما يك شي گربه ساختيم در تاپيك قبلي.(حالا اگر كلاس را بشه شي در نظر گرفت.)
حالا اگر بياييم گربه را به رويداد ماوس حساس كنيم ، آيا برنامه ما رويدادگرا ميشه؟ فكر نمي كنم.(چون باز يك رودخانه داريم نه ((چشمه ها)) را.)
پس چه پارامتري بايد برنامه داشته باشه كه بشه گفت رويدادگرا؟
من فكر مي كنم كه همه زير سر ويندوز و اون حلقه پيامها داره كه آرش جان و آقا سعيد گفتند.
يعني هر برنامه اي كه با آن حلقه پيامها ارتباط برقرار كنه ميشه رويدادگرا. و اين قضيه هم من نتوانستم حل كنم كه آيا همه برنامه هاي رويدادگرا ، الزاما بايد شي گرا باشند يا نه.

راستي وي بي آن حلقه پيامهايش كجاست؟ ايا مخفي است يا كلا مكانيسم در وي بي با وي سي فرق داره؟
 

mostafa_gm

Registered User
تاریخ عضویت
4 آپریل 2005
نوشته‌ها
1,863
لایک‌ها
438
محل سکونت
My House
البته تو ++VC به جاي main ميتونيم winmain داشته باشيم.
 

Arash_j13

Registered User
تاریخ عضویت
18 فوریه 2005
نوشته‌ها
778
لایک‌ها
2
محل سکونت
مشهد
سالک جان بزارید من جواب هایی که به سوالت خودتون دادید رو تصحیح کنم البته تا جایی که بلد باشم

اولا : آيا براي پاسخ به يك رويداد ، يك شي لازمه؟
اگر اين طوري باشه ، تمام برنامه هاي رويدادگرا ، شي گرا هم هستند.

این جواب غلطه چون برای پاسخ گویی به رویداد های یه تابع هم کافیه
البته زبان هایی که ما می شناسیم به صورت توکار این تابع رو درون یک کلاس تعریف می کنن
بزارید بیشتر توضیح بدم
وقتی شما با RegisterClass یه کلاس جدید رو ثبت می کنید یه ساختار بهش می فرستید که به این صورت تعریف می شه

کد:
typedef struct _WNDCLASS {   
    UINT    style; 
    WNDPROC lpfnWndProc; 
    int     cbClsExtra; 
    int     cbWndExtra; 
    HANDLE  hInstance; 
    HICON   hIcon; 
    HCURSOR hCursor; 
    HBRUSH  hbrBackground; 
    LPCTSTR lpszMenuName; 
    LPCTSTR lpszClassName; 
}

فیلد دوم از این ساختار یه تابع callback هست که به این صورت تعریف می شه

کد:
LRESULT CALLBACK WindowProc(

    HWND hwnd,	// handle of window
    UINT uMsg,	// message identifier
    WPARAM wParam,	// first message parameter
    LPARAM lParam 	// second message parameter
   );
این تابع وضیفه پاسخ گویی به پیغام های ویندوز رو داره

پس می بیند که شما به یک شی نیاز ندارید در مورد این توابع اگه خواستید می شه بعدا صحبت کرد فقط همین قدر بگم که این توابع API ویندوز وظیفه ثبت کلاس برای ساخت یک جز جدید از ویندوز را دارن


در مورد رویداد گرایی هم باید بگم تقریبا تمام برنامه های ویژوال تحت ویندوز و حتی بعضی از برنامه های کنسول رویداد گرا هستن رویداد گرا به این معنی است که برنامه منتظر ایتفاق رویداد باشه این رویداد توی ویندوز با پیغامهایی که به هندل می رسه(معولا هندل درون یک کلاس مخفی می شه) اتفاق می یفته و اون کلاس برای سادگی برنامه اجزاه تعریف یه سری توابع رو میده که رویداد های رو کنترل کنن و در صورت بروز هر رویداد اجرا رو به یکی از این توابع منتقل می کنه


(حالا اگر كلاس را بشه شي در نظر گرفت.)
یه دوستی داشتم که مثال جالبی می زد
می گفت یه شیرینی و قالبش رو در نظر بگیرید کلاس قالب شیرینی و شی(object) خود شیرینی هست

در مورد حلقه اصلی برنامه من اطلاع زیادی در مورد نحوه برخورد ویژوال سی ندارم ولی اگه منظورتون کلی باشه می تونم توی دلفی براتون توضیح بدم VCL چگونه این حلقه رو ایجاد می کنه

و در مورد ویژوال بیسیک هم بهتره با این بحث قاطیش نکنید چون گیج کنند ه می شه چون ویژوال بیسیک یه زبان مفسری هست تمام اعمال مربوط به اجرای برنامه حلقه اصلی و پاسخ گوییی به برنامه رو مفسر انجام میده و هر جا لازم باشه کد ویژوال بیسیک که برای پاسخ گویی به رویداد نوشته شده رو تفسیر می کنه ولی در اصل مفسر ویژوال بیسیک که به سی نوشته شده با ویندوز طرف هست نه برنامه ی شما
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
خيلي ممنون.
قضيه ويژوال بيسيك برام خيلي جالب شد. البته قبلا هم د اين مورد از شما زياد سئوال كردم ولي كم كم دارم به جواب نهايي خود مي رسم. حالا كه دوستان ديگه هم اينجا در ويژوال بيسيك مسلطند ، اين سئوال را اول دارم كه :

آن مفسر ، كجا قرار دارد؟ چيزي كه خودم الان تصورمه اينه كه وقتي كدها در ويژوال بيسيك تفسير مي شوند( نه كامپايل – قبلا خودتان گفتيد) كلا بي سواديش اين ميشه كه جمع و جور مي شوند تا exe ساخته بشه ، به نظر من همين جاست كه بايست مفسر هم كنارش جاسازي بشه. يعني ميكروسافت آمده كلك زده. قبلا در qbasic و gwbasic و ... بايد موقع اجراي برنامه ما ، مادر آن هم موجود بود كه مادر همان محيطي بود كه در ان كدها را نوشته بوديم. ( البته فكر كنم بعدا qbasic يا يكي ديگه بود شايد ، توانايي ساخت exe بي نياز به مادر را هم داده بود)
حالا كلك ميكروسافت در ويژوال بيسيك اينه كه مادر را به شكل مفسر در exe بسته بندي مي كند. و هيچ كامپايلي نداريم. ( يا شايد نيمه كامپايل كه زياد مهم نيست و كاري بهش نداريم.)
و فرمايش شما اينه كه همان مفسر ، تمام ارتباطات با ويندوز را برقرار مي كنه.

آخه مي دونيد ، براي من سئوال بود كه چرا در پنجره كدنويسي ويژوال بيسيك ، مثل whiteboard پاكيزه است ولي در پنجره كد نويسي ويژوال سي براي نوشتن يك hello اين همه كد موجود است.

== == == == == = = == = =
راجع به اشتباه من كه بجاي object گفتم كلاس ، هم بي دقتي بوده و مثال قالب شيريني شما خيلي گوياست. يعني قالب شيريني ، آبجكت نيست ، شيريني ئي كه با آن پخته مي شود ، آبجكت است. البته من خودم در تاپيك سي تاكيد كردم روي اين قضيه ، ولي اينجا اشتباه لپي بود.
= = = = = = == = = == = ==
من گفتم كه اگر كلاسي بسازيم و يكي از توابع آن به رويدادها حساس باشه ، ( در ساخت كلاس در سي منظورمه نه ويژوال سي) ، ما برنامه رويدادگرا نخواهيم داشت و فقط يك تابع حساس به يك رويداد داريم.

و وقتي رويدادگرا هست برنامه كه آن حلقه دريافت پيامها از ويندوز ساخته بشه. و در ويژوال سي ما بايستي اين حلقه را خودمان بسازيم.
البته فكر كنم به طور اتوماتيك يا ويزاردها در ويژوال سي ساخته ميشه و ما فقط ازش استفاده مي كنيم. البته ما مي توانيم آن را تغيير دهيم. و اگر هم تغيير نداديم حداقل آن را مي بينيم.

ولي در ويژوال بيسيك چنين حلقه اي اگر وجود هم داشته باشه ، ما نمي بينيمش و شما فرموديد درون مفسر چنين مكانيسمهايي قرار دارد.
=============
اگر حوصله اش را داشتيد آن حلقه را در دلفي بنويسيد.
خيلي هم از پست قبلي اتان ممنون. خيلي زحمت كشيديد.
ولي من از آن كدها چيزي نفهميدم چون هنوز كدنويسي كار نكرده ام ولي خيلي با دقت چند بار خواندم .
اگر لازم مي دانيد بيشتر توضيح دهيد و گرنه كه بعدا مشروح بگيم.
.
 

saeedsmk

مدیر بازنشسته
تاریخ عضویت
6 سپتامبر 2003
نوشته‌ها
1,518
لایک‌ها
4
سلام
خوب هستید
در مورد رویداد گرای و شی گرایی پرسیده بودید
هنگامی که یک برنامه ویندوز اجرا میشه یک کلاس تعریف میشه که خودش رو به عنوان یک گیرنده پروسس معرفی میکنه .
اما برای اینکه برنامه بتونه با برنامه های دیگر همزمان اجرا بشه دو راه حل وجود داره
یکی اینکه این وندوز زمانی که فعال است یعنی اکتیو شده است به ورودی جواب بگوید
و دیگری اینکه ویندوز تمامی ورودی ها را جمع کرده و سپس بر اساس نوع ورودی و محل اتفاق ان ورودی رو به کلاس اصلی برنامه ارائه کنه .
در روش اول خود ممکنه اتفاقاتی بیوفتند که احتیاج است در زمانی که برنامه فعال نیست هم برنامه یکسری کار راانجام دهد مثلا اتفاق رسیدن زمان اجرا یک تایمر یا
در یک دیکشنری مقیم در حافظه زمانی که اطلاعاتی را در حافظه کپی کرده ایم و منتظر نمایش اطلاعات هستیم
پس بهترین راه راه حل دوم است .با اینکار ما باید برای کلاس خود یک تابع تعریف کنیم که این تابع به تمامی اتفاق ها جواب بگوید از اتفاق شناسایی - لود - غیر اکتیو - کلیک و.....به این تابع تابع اصلی یا تابع ریجستر شده برنامه گفته میشود
تا اینجا یکسری اطلاعات بدست اورده شد.
این اتفاقات انقدر زیاد است که این تابع نمیتواند تمامی انها را پوشش دهد. همانطور که میدانید هر کلاسی که از کلاس ای تعریف میشه خواصی رو از مادر خودش به ارث میبره. خوب این کلاسی که در بالا اشاره شد ، کلاس فایل های اجرایی است . در کلاس فایل های اجرایی برای همه اتفاقات از پیش تعریف شده یک پروسه پیش فرض تعریف شده است ( برای انهایی که بازهم نباید کار خاصی انجام دهد تابعی تعریف شده که داخل این تابع هیچ چیزی نیست و در عمل با اجرا شدن این تابع هیچ عملی انجام نمگیر. ولی جواب گویی به این اتفاق باز هم احاظ شده است )خوب چرا گفتم اتفاقات از پیش تعریف شده چون شما میتونید خودتون یک اتفاق برای برنامه تون تعریف کنید که به انها اتفاقات یوزر تایپ گفته میشه ( ممکنه در ترجمه بعضی از اسمها مشکل پیدا کنه . منظورم از گفتن این حرف ها فقط فهمیدن چگونگی کاراکردن برنامه است ). خوب فکر کنم یه بینش کلی پیدا کردید.
در مورد اینکه آیا هر برنامه رویداد گر شی گرا هم هست ؟
ببیند هر شی توی کلاسی تعریف میشه تمامی بچه پنجره ها( ادیت باکس ها – تصاویر و ....) وپنجره ها و دیگر مواردتوی وین 32 بیتی از کلاسهای مادرخودشون تعریف میشوند و در نتیجه یک شی هم هستند . لذا برنامه شی گرایی یعنی برنامه نویسی چگونگی پاسخ به اتفاقات هر شی در صورت لزوم و ارتباط شی ها با هم در صورت لزوم . اما رویداد گرایی یعنی جواب گویی به هر اتفاقی که برای برنامه میافتد .
شما فرض کنید یک برنامه نوشته اید که در بک گراند قرار دارد و هیچ پنجره و یا بچه پنجره ای ندارد اما تمامی رویدادهای موس و کی برد را کپچر کرده و در فایلی ذخیره مینماید . این برنامه را حتی میتوان با vb و یا vc نوشت . اما از انجایی برنامه شما بر اساس اشیاء و روابط حاکم بین انها کار نمیکند برنامه شما فقط رویداد گرا است ( شما براساس برنامه فقط رویداد کیبرد و موس را چک کرده اید). اما اگر همین برنامه پنجره ای داشت و در این پنجره مسیر فایل و ... را تنظیم میکردی برنامه شما بصورت شی گرا در میامد .
حال به مثال زیز که جالب است را توجه کنید این برنامه یک مسیج باکس تعریف میکند و خود برنامه رویدادگرا و سی گرا نیست . اما شی که تولید کرده هم شی گرا هم رویداد گرا است .
386
کد:
.model flat,stdcall 
option casemap:none 
include \masm32\include\windows.inc 
include \masm32\include\kernel32.inc 
includelib \masm32\lib\kernel32.lib 
include \masm32\include\user32.inc 
includelib \masm32\lib\user32.lib 
.data 
MsgBoxCaption  db "Iczelion Tutorial No.2",0 
MsgBoxText       db "Win32 Assembly is Great!",0 
.code 
start: 
invoke MessageBox, NULL, addr MsgBoxText, addr MsgBoxCaption, MB_OK 
invoke ExitProcess, NULL 
end start
اما در مورد vb :
شما یک مفسر دارید یعنی ( که کار همان کدهای زیادی که توی vc تولید شده اند اما درvb برنامه جدید دیه نمیشوند و یک سری کارهای دیگر) که همان فایل msvb هست در vb6 این فایل MSVBVM60.DLL کار های مفسری رو انجام میدهد .
یعنی اینکه مثل تمامی برنامه های رویداد گرا یک تابع از توابع فایل های اجرایی ریجستر یا تعریف میکند و یک پروسه اصلی نیز معرفی مینماید و...

راستی کد زیر هم یک برنامه پایه 32 بیتی رو توی اسمبلی معرفی میکنهکه تابع callback رو دازه و حلقه جواب گویی به رویدادها رو داره
کد:
.386 
.model flat,stdcall 
option casemap:none 
include \masm32\include\windows.inc 
include \masm32\include\user32.inc 
includelib \masm32\lib\user32.lib            ; calls to functions in user32.lib and kernel32.lib 
include \masm32\include\kernel32.inc 
includelib \masm32\lib\kernel32.lib 
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD 
.DATA                     ; initialized data 
ClassName db "SimpleWinClass",0        ; the name of our window class 
AppName db "Our First Window",0        ; the name of our window 
.DATA?                ; Uninitialized data 
hInstance HINSTANCE ?        ; Instance handle of our program 
CommandLine LPSTR ? 
.CODE                ; Here begins our code 
start: 
invoke GetModuleHandle, NULL            ; get the instance handle of our program. 
                                                                       ; Under Win32, hmodule==hinstance mov hInstance,eax 
mov hInstance,eax 
invoke GetCommandLine                        ; get the command line. You don't have to call this function IF 
                                                                       ; your program doesn't process the command line. 
mov CommandLine,eax 
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT        ; call the main function 
invoke ExitProcess, eax                           ; quit our program. The exit code is returned in eax from WinMain. 
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD 
    LOCAL wc:WNDCLASSEX                                            ; create local variables on stack 
    LOCAL msg:MSG 
    LOCAL hwnd:HWND 
    mov   wc.cbSize,SIZEOF WNDCLASSEX                   ; fill values in members of wc 
    mov   wc.style, CS_HREDRAW or CS_VREDRAW 
    mov   wc.lpfnWndProc, OFFSET WndProc 
    mov   wc.cbClsExtra,NULL 
    mov   wc.cbWndExtra,NULL 
    push  hInstance 
    pop   wc.hInstance 
    mov   wc.hbrBackground,COLOR_WINDOW+1 
    mov   wc.lpszMenuName,NULL 
    mov   wc.lpszClassName,OFFSET ClassName 
    invoke LoadIcon,NULL,IDI_APPLICATION 
    mov   wc.hIcon,eax 
    mov   wc.hIconSm,eax 
    invoke LoadCursor,NULL,IDC_ARROW 
    mov   wc.hCursor,eax 
    invoke RegisterClassEx, addr wc                       ; register our window class 
    invoke CreateWindowEx,NULL,\ 
                ADDR ClassName,\ 
                ADDR AppName,\ 
                WS_OVERLAPPEDWINDOW,\ 
                CW_USEDEFAULT,\ 
                CW_USEDEFAULT,\ 
                CW_USEDEFAULT,\ 
                CW_USEDEFAULT,\ 
                NULL,\ 
                NULL,\ 
                hInst,\ 
                NULL 
    mov   hwnd,eax 
    invoke ShowWindow, hwnd,CmdShow               ; display our window on desktop 
    invoke UpdateWindow, hwnd                                 ; refresh the client area 
    .WHILE TRUE                                                         ; Enter message loop 
                invoke GetMessage, ADDR msg,NULL,0,0 
                .BREAK .IF (!eax) 
                invoke TranslateMessage, ADDR msg 
                invoke DispatchMessage, ADDR msg 
   .ENDW 
    mov     eax,msg.wParam                                            ; return exit code in eax 
    ret 
WinMain endp 
[CENTER]شروع کد تابع جواب گو به رویداد ها [/CENTER]
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM 
    .IF uMsg==WM_DESTROY                           ; if the user closes our window 
        invoke PostQuitMessage,NULL             ; quit our application 
    .ELSE 
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam     ; Default message processing 
        ret 
    .ENDIF 
    xor eax,eax 
    ret 
WndProc endp 
end start
 

فایل های ضمیمه

  • tut03.zip
    880 بایت · نمایش ها: 7

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
با سلام.
من مفهوم شي گرايي و رويداد گرايي را گنگ بلد بودم. و اصرارم بر بحث براي همين بود كه هم خودم ياد بگيرم و هم يك بحث خوبي بشه براي پيش زمينه كار ويژوالي. كه هم رويدادگراست و هم شي گرا.
= = == = == = = = = = == =
راجع به ويژوال بيسيك ، خيلي اطلاعات خوبي داديد. واقعا لذت بردم.
من ديشب ديگه روم نشد اسم dll را بياورم . چون آنقدر راجع به اين dll ها آرش را سئوال پيچ كرده ام كه گفتم اگه باز بگم عصباني بشه. راستش مي خواستم ديشب بگم ارتباط اين dll ها با اين قضيه چيه. و اين كه چرا موقع exe ساختن كل dll ها را هم همراهش نمي كنند. شايد بخاطر حجم. بگذريم.
اصرار من براي مقايسه وي بي و وي سي براي اينه كه مي گويند نسبت كاربران اين دو 3 به 1 است. البته شما آمار بهتري داريد. اگر از من بپرسيد مي گويم 20 به 1 . با توجه به سايتها و وبلاگها و بحثهاي فرومها. و به خاطر آشنايي نسبتا بالاي هموطنان ، من خواستم مقايسه اي بشه. و يك دليل هم اين كه خودم هم با وي بي آشنام. و يكي هم اين كه هر دو از مجموعه ويژوال استوديو هستند و فقط تفاوت زبان دارند. كاش همراه اين مجموعه ويژوال پاسكال هم بود. راستي چرا ميكروسافت روي پاسكال دست نمي گذارد. مگر مخترع پاسكال بورلند است؟ دلفي من زياد بلد نيستم. و آرش جان مگر ما را به فيض برساند.
= = = = == = == = =
از بابت زحمت نوشتن برنامه ها هم بي نهايت ممنونم.
توضيحات راجع به روش پاسخ گويي به رويدادها هم خيلي خوب بود.
توضيح اين كه چطور يك برنامه مي تواند رويدادگرا باشد و شي گرا نباشد هم جالب بود.
به نظر من زياد لازم نبود بين اين دو تفكيك صورت بگيرد ولي اصرار من براي اين تفكيك براي اين بود كه هم اساتيد گرامي ، شي گرايي را تشريح كنند و هم رويدادگرايي را. خودم توانايي اين كار را ابدا نداشتم.

مثال ديكشنري و تايمر را خوب نفهميدم. باز چند بار مطالعه مي كنم ، اگر باز نفهميدم مي پرسم.
خيلي زحمت كشيديد. ممنون.
.
 

saeedsmk

مدیر بازنشسته
تاریخ عضویت
6 سپتامبر 2003
نوشته‌ها
1,518
لایک‌ها
4
سلام
خوب هستید
ببین شاید مشکل تایمر از اونجا آغاز بشه که تایمر خودش یک شیء .شما وقتی یک تایمر میسازید دستور set timer صدا زده میشه و شماره شناسایی برنامه ما به تابع مذکور فرستاده میشه و همچنین شماره تایمر که شما به تایمر اختصاص میدید و زمانی که باید تایمر فعال بشه ( همون مدت زمان تایمر ) و ادرس تابعی که باید در صورت رسیدن زمان و طی شدن زمان صدا زده بشه .خوب فرض کنید من تایمر ای رو طراحی کردم که بعد از 1 ساعت تابع x رو صدا بزنه . برنامه رو اجرا و بعد مینیمایز میکنم و مثلا وارد ورد میشم ( فرض بر این است که حالت بکار گرفته شده حالت یک باشد ). در صورتی که برنامه اکتیو پروسس کننده باشد چون زمان تایمر میرسه و بعد برنامه ای که شامل تایمره فعال نیست پس تابع مورد نظر صدا زده نمیشود ولی در حالت دوم یک مسیج به تابع اصلی یا callback ( اسم تابع اصلی برای این تابع درست نیست زیرا تابع اصلی تابعی است که کلاس برنامه را ریجیستر میکند ، اما چون من این توابع رو حین کرکینگ یاد گرفتم و بعد اسمبلی تحت ویندوز رو یاد گرفتم البته نه کامل هنوز بر اساس گفته کرکر ها که این تابع رو تابع اصل کاری میدونن من تابع Callback رو تابع اصلی میگوییم :D ) فرستاده میشه با پارامتر ادرس تابع ای که باید صدا زده بشه برنامه متوجه رسیدن زمان فعال شدن تابع تایمر شده و اون رو عمل میکنه

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

امیدوارم کمک کنه
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
درخواست رفع اشكال از پست اول.
شايد در پست دوم جواب داده باشيد. من مشغول كنار هم گذاشتن پست اول و دوم هستم تا جمع بندي كنم.
.
=============================================
برداشتها و سئوال من:
وقتي يك برنامه كه براي كار و ارتباط با ويندوز ساخته شده ، اجرا ميشود ، در ويندوز ؟(يا در خود برنامه ؟) يك كلاس ايجاد ميشه كه اين كلاس ، كارش اين است كه ، رويدادها را دريافت مي كند(؟) (يا مسئول مديريت پردازش هاست(؟) )
برداشت من اينه كه:
براي اينكه تمامي برنامه هاي اجرا شده در ويندوز (اجرا شده در كنار هم و همزمان) بدون مشكلي بتوانند با هم كار كنند ، دو راه وجود داره:
يكي اينكه هر برنامه(كه در حقيقت يك ويندوز يعني پنجره است) زماني كه اكتيو است(مثل وقتي با ماوس روي پنجره اش كليك شده) به ورودي ها جواب بدهد،
دوم اينكه ويندوز تمامي ورودي ها را جمع كند و بر اساس نوع ورودي و محل اتفاق ورودي ، آن ورودي را به كلاسهاي مختلف از برنامه هاي در حال اجراي مختلف بفرستد.

سئوال من اينه كه : محل وقوع رويداد يعني چه؟ يعني مثلا اگر پي 1 (برنامه اول) فعال بود و يك رويداد اتفاق افتاد ، محل روداد ميشه روي پي 1 ؟
سئوال دوم: نوع ورودي يعني چه؟ كيبورد و ماوس منظور است؟مثلا نوع دكمه كيبورد يا ماوس يا حركت ماوس؟
اينكه به برنامه هاي در حال اجراي مختلف فرستاده ميشه ، بر اساس چه عاملي است؟
آيا پذيرش خود برنامه مطرح است؟ يعني برنامه به ويندوز گفته كه فلان رويدادها را موقعي كه من اكتيو بودم به من بده و فلان رويدادها را موقعي كه من پسيو بودم بده.
اگر اين جوري باشه ، ما هم موقعي كه براي ويندوز داريم برنامه مي نويسيم ، بايد بتوانيم تعيين كنيم كه برنامه ساخته شده ما ، در دو حالت اكتيو و پسيو چه نوع ورودي هاي را از ويندوز بايد دريافت كند.

برداشت من اينه كه:
چون بايد برنامه ها در حالت پسيو هم قادر به شنيدن رويدادها باشند ، راه دوم بهتر است.
براي اينكار يك تابع تعريف مي شود كه نامش ((تابع رجيستر شده برنامه)) است.
كار اين تابع اين است كه به تمامي رويدادها جواب بدهد. كه غير اكتيو بودن هم يك رويداد محسوب مي شود (رويداد شناسايي هم نمي دانم چيست)

((( اين تابع)) ، آيا همان تابع رجيستر شده است؟
مگر اين تابع داخل همين كلاس (كه از والدش كلاس فايلهاي اجرايي) مشتق شده ، قرار ندارد؟
اگر قرار ندارد ، چه ارتباطي اين كلاس اين تابع با هم دارند؟
 
بالا