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

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

Arash_j13

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

قسمت شروع هر برنامه در دلفی این طوریه

begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
البته دلفی در ابتدا یه سری توابع دیگه رو فراخوانی می کنه که به اونها کاریی نداریم
آبجکت application یه شی از کلاس TApplication هست که در یونیت forms تعریف شده و VCL اون رو به طور خودکار می سازه دو خط اول مربوط به بار گذاری برنامه است که بهشون کاری نداریم اجرای حلقه الی برنامه از خط Application.Run اتفاق می افتد این متد حلقه اصلی رو تشکیل میده

کد:
 procedure TApplication.Run;
begin
  FRunning := True;
  try
    AddExitProc(DoneApplication);
    if FMainForm <> nil then
    begin
      case CmdShow of
        SW_SHOWMINNOACTIVE: FMainForm.FWindowState := wsMinimized;
        SW_SHOWMAXIMIZED: MainForm.WindowState := wsMaximized;
      end;
      if FShowMainForm then
        if FMainForm.FWindowState = wsMinimized then
          Minimize else
          FMainForm.Visible := True;
      repeat
        try
          HandleMessage;
        except
          HandleException(Self);
        end;
      until Terminated;
    end;
  finally
    FRunning := False;
  end;
end;

این متد ابتدا توابع خروج رو بررسی می کنه فرم رو برای نمایش تنظیم می کنه و اگه لازم باشه نمایشش می ده تا به این جا برسه

repeat
try
HandleMessage;
except
HandleException(Self);
end;
until Terminated;
این همون حلقه اصلی هست شرط خروج حلقه زمانی است که فیلد Terminated از این کلاس برابر true شود
درون این حلقه یک بلوک پاسخ گویی به خطا وجود دارد تا از بسته شدن برنام در صورت بروز خطا جلوگیری کند
این نوع بلوک ها مشابه C++ هست در واقع از روی C++ کپی برداری شده پس باید آشنا باشه

شما می بینید که متد handleMessage در هر بار حلقه فراخوانی می شه این متد باعث می شه تا برنامه منتظر پیغام های ویندوز بمونه و اونها رو پردازش کنه
برای اینکار از تابع WaitMessage که از سری توابع windows API هست استفاده می شه فراخوانی این تابع باعث می شه که برنامه در زمانی که پیغامی بهش نرسیده بی جهت از CPU استفاده نکنه

به این صورت این حلقه ادامه پیدا می کنه و برنامه زنده به نظر می رسه
 

saeedsmk

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


بعد از اجرا برنامه ، تابع اولیه برنامه توسط ویندوز صدا زده میشود .سپس برنامه به وسیله RegisterClassEx کلاس ویندوز ما را ریجستر میکند . به عبارت ساده تر کلاس ما به ویندوز معرفی میشود . در خواص اصلی کلاس تعریف شده یک عضو وجود دارد که توسط ان تابع callback تعریف میشود . و این تابع درصورت بروز اتفاقی فعال شده و عملیات مناسب را اجرا مینماید .

اما برای اينکه برنامه بتونه با برنامه های ديگر همزمان اجرا بشه دو راه حل وجود داره
يکی اينکه اين ويندوز زمانی که فعال است يعنی اکتيو شده است به ورودی جواب بگويد
و ديگری اينکه ويندوز تمامی ورودی ها را جمع کرده و سپس بر اساس نوع ورودی و محل اتفاق آن ورودی رو به کلاس اصلی برنامه ارائه کنه .


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


- ببینید هر کلاسی که تعریف میشه ( ریجستر میشود ) یک عدد یکتا دریافت میکنه که به ان pid گفته میشود . و هر ویندوز و یا بچه ویندوزی هم یک شماره شناسی میگیره که به ان hwnd گفته میشه .محل وقوع رویداد یعنی مسیج تولید شده باید به چه pid و چه hwnd فرستاده شود . شما وقتی روی دکمه ای کلیک میکنید پیغام wm_command تولید میشود .حال یندوز این پیغام را به pid و hwnd پنجره ای که دکمه روی ان قرار داشته است میفرستد. محل وقوع ما در این حالت دکمه کلیک شده با کد شناسایی خود، hwnd دکمه، در پنجره برنامه مورد نظر با کد شناسای خود ، hwndویندوز مان ، از برنامه اجرایی با کد شناسایی pid است.

- نوع ورودی نوع انفاقی است که افتاده است
مثلا کلیک کردن باعث ایجاد سه رویداد رفتن پایین دکمه موس – کلیک شدن و بالا رفتن دکمه موس است . پس این پیغام ها با wm شروع میشوند .( یعنی عمل فیزیکی انجام شده کلیک ای شده – دکمه فشرده شده –پنجره ریسایز شده و ....) بعضی دیگر از پیغامها برای انجام عمل غیر فیزیکی استفاده میشود مثل EM_SETSEL که وظیفه ان مارک کردن یک تکه متن است به قول خودمون سلکت کردن ان . البته این دسته بندی کامل نیست و ناقص است فقط برای دریافت مطلب تبقه بندی شد تا بتونم مفهوم رو برسونم .

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

- در واقعه این جوری نیست اما با راه حل زیر میتوان این مورد را شبیه سازی نمود:
در ویندوز محلی ( لیستس ) نحوه قرار گرفتن پنجره برنامه های را که روی صفحه دسکتاپ قرار دارند ( یعنی اجرا شده است) را نگهداری میکند در واقعه لیست z order برنامه های در حال اجرا در این محل نگه داری میشود. و با تغییر وضعیت و یا فعال شدن برنامه ای این لیست تغییر میکند.( چون z order برنامه تغییر نموده است ) اگر برنامه ای اکتیو باشد z order ان یک است و گرنه z order ان عددی غیر از یک است لذا میتوان از این خاصیت برای پی بردن به اکتیو یا پسیو بودن برنامه استفاده نمود ونحوه جواب گویی به پیغام ها را بر اساس نوع وضعیت پیدا نمود.

رويداد شناسايي هم نمي دانم چيست

رویداد insializing یا در وی بی، همان form_load است .

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


- این تابع همان تابع callback است و در واقعه پروسس مسیج های رسیده را بر عهده دارد .
- این تابع همانطور که گفتم جزء این کلاس است و نه داخل ان . درون هیچ کلاسی چیزی قرار ندارد( کلاس یک بدنه اولیه است) بلکه ادرس اجزا وجود دارند که کلاس مثل تکه های چتر که توسط بدنه چتر به هم وصل شده اند ، اجزا را به هم متصل کرده و یک مجموعه را میسازدکه داری توابع و مقدارهای مخصوص خود ( که از هیچ جا بجز درون توابع کلاس به ان ها دسترسی نیست ) و مقدار های عمومی است.

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

saalek

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

http://www.flazx.com/category73.php

درود.
.
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
سالك: تاپيك زير را بخوانيد . خيلي به هضم بحثهاي اينجا كمك مي كند. .
آدرس:
http://www.barnamenevis.org/forum/showthread.php?t=27889

نمونه بحث:
از :
Inprise

اگر ميخواهي بدوني Callback دقيقا" چيه : بسياري از توابع آرگومانهائي رو به عنوان ورودي قبول ميكنند فرآيندي روي بعضي از اونها انجام ميشه و تغييراتي در اثر اين فرايند روي بعضي ديگه انجام ميشه و نهايتا يك خروجي توليد ميشه . مثلا توسط يك تابع با سه ورودي ، دو ورودي اول محاسبه و نتيجه در ورودي سوم به عنوان خروجي نهائي قرار داده ميشه و در صورت موفقيت آميز بودن عمليات يك عدد صحيح از تابع بازگردانده ميشه . اين روند بصورت سنتي به وفور تو پياده سازي API هاي ويندوز استفاده شده . گاهي لازمه براي تكميل عمليات يك تابع بجاي دريافت آرگومانهائي مثل رشته يا عدد صحيح ، يك تابع ، تابع ديگري رو به عنوان آرگومان بپذيره . مثال اول : تابع اصلي ميخواد تابعي رو بگيره و اونو صدا بزنه و خروجي اش رو تو آرگومان دوم خودش قرار بده و يك صفر هم به نشان موفقيت برگردونه . مثال دوم : تابعي ميخواد آرگومان اولش رو بگيره و محاسباتي روش انجام بده و اگر شرطي برقرار بود آرگومان دوم كه خودش تابع ديگري است رو فراخواني كنه و پس از اتمام ، يك صفر به نشان موفقيت برگردونه ؛ در اين حالتها به تابعي كه به عنوان آرگومان به تابع ديگري براي مقصود مشخصي پاس ميشه Callback Function ميگن ؛ يعني تابعي كه صدا زده ميشه و محتوياتش اجرا ميشه و سپس كنترل به برنامه اصلي برميگرده . براي يك نمونه تابع EnumWindows رو ببين و مثالهاي مربوطه رو مطالعه كن ؛

تو معرفي چنين توابعي معمولا" مغلطه متداولي اتفاق ميفته ؛ عده اي خيال ميكنند كه تابع Callback توسط ويندوز فراخواني ميشه در حاليكه اينطور نيست . اگر تابع كال بك تو برنامهء خودت پياده سازي شده باشه ، آدرس آفست شروعش از طريق IAT دريافت و كنترل به اون محل منتقل ميشه و اگر اون تابع بالفرض يك API ديگه باشه ، چون هنگام فراخواني برنامه ات ، تمام DLL هاي مورد نظر ( بصورت مجازي ) به فضاي آدرسي برنامه ات منتقل شده اند ، و هر كدام آدرس ثابت و مشخصي دارند ( با استثنائاتي ) كنترل باز هم توسط برنامه ات بطور خودكار به آفست شروع API منتقل ميشه . شايد چون اغلب استفاده از Callback ها توسط برنامه نويسان ويندوز به استفاده از API محدود شده ، خيليها تصور ميكنن فراخواني Callback API توسط ويندوز انجام ميشه ، در حاليكه اينطور نيست ، اين فقط يكي از توابع ويندوزه كه توسط برنامهء مالك ، فراخواني ميشه .
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
با سلام به همه دوستان و تشكر از راهنمايي هايي كه تا بحال شده.
آقا سعيد من نظرم اينه كه شما يكسري كلمه كليدي مثل callback به من بدهيد تا من سرچ كنم (در فرومها و سايتهاي خارجي)و اين بحث را جمع بندي كنيم. چون منابع فارسي راجع به ويژوال سي خيلي كم پيدا ميشه.

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

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

saeedsmk

مدیر بازنشسته
تاریخ عضویت
6 سپتامبر 2003
نوشته‌ها
1,518
لایک‌ها
4
در مرود callback ميشه گفت هم توسط ويندوز اجرا ميشه هم نميشه !!!!!!
ببنيد وقتي اتفاقي ميافته اين اتفاق توسط ويندوز به برنامه فرستاده شده و سپس توسط لوپ مسيج برنامه به برنامه انتقال داده ميشه و در نهايت تابع اي كه مسئوليت تفسير كلي مسيچ ها رو داره احضار ميشه ( همون تابع callback)
.WHILE TRUE ; Enter message loop
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
هنگامي كه توسط لوپ مسيچ ، مسيچ ترنسفر ميشه به برنامه ( يعني اينكه مسيچي دريافت شده ) ( اين تابع يكي از توابع هسته است ) و در نتيجه هسته ميره ميبينه تابع ساختار يافته چيه( همون callback) و اون رو اجرا ميكنه پس ويندوز در اين حالت callback رو صدا ميزنه و هم اينكه ميشه گفت تابع ترنسفر ما باعث صدا زده شدن اين تابع ميشه
در كل هيچ فرقي نداره كه كدوم يكي درست است رسيدن مسيچ ها به اين كال بك و اجرا شدن دستورات در نهايت از اهميت برخوردار ميباشد
-----------------
سالك جان من زياد با vc آشنايي ندارم . فكر ديگر دوستان بتونن بيشتر كمك كنن مثل اقا مصطفي اما در مورد كلمات كليدي تا آنجايي كه يادمه :
stdcall__
cdecl ـــ
MFC
API آشنايي با اين توابع كمك زيادي حتي كليدي در حين برنامه نويسيه و بهتر حين برنامه نويسي به آنها اشاره كنيد
WNDCLASS و همچين عبارتي كه حين تعريف فرم ها استفاده ميشه ( HWND و ‍PID و...)
و...
 

Roby

کاربر فعال فوتبال<br> عضو تحریریه مجله فوتبال
کاربر فعال
تاریخ عضویت
20 ژوئن 2005
نوشته‌ها
1,263
لایک‌ها
1,395
به نظر من اگه قصد ایجاد تاپیک آموزشی برای ویژوال سی رو دارید باید قبل از هرچیز حیطه کار رو مشخص کنید
ویژوال سی اآنقدر گسترده است که کمتر کسی پیدا میشه که به همه ابزارها و انواع پروژه های اون کاملا مسلط باشه
ضمنا برای یادگیری ویژوال سی صرفا خوندن کتابهای مرتبط با این زبان کافی نیست بلکه لازمه تا در کنار اون با یکسری مفاهیم برنامه نویسی ویندوز و برخی جنبه های سیستم عامل آشنا باشید
خلاصه بگم کاری نیست که بشه بصورت کلی و توی یک تاپیک اون رو انجام داد اول باید خطوط حرکت کاملا مشخص و تعزیف بشه بعد روی یک اسلوب مشخص پیش بریم . حتی لازمه برای برخی مباحث تاپیک های مجزایی ایجاد بشه و در اونها بحث و گفتگو راجع به اون مبحث ادامه پیدا کنه
 

saalek

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

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
روشهاي كاربردي ويژوال سي را در تاپيك زير ادامه مي دهيم.
http://forum.persiantools.com/showthread.php?t=47755

و جو علمي اين تاپيك را حفظ مي كنيم.
و همراه با پيش رفتن در كاربرد در اين تاپيك روي جنبه عمقي كار هم درايت پيدا مي كنيم.
ممنون از دوستاني كه اينجا مطلب گذاشتند.
.
 

saalek110

Registered User
تاریخ عضویت
10 آپریل 2007
نوشته‌ها
212
لایک‌ها
1
http://cnx.org/content/m14425/latest/

سایت خوبی برای یادگیری ویژوال سی. اولش مفاهیم گفته بعد کاربردی.

VC++ Tutorial for Beginners​

a9.gif
 
بالا