Learning About Computer & Internet
|
|
|
سخنی با شما با عرض سلام و خسته نباشید خدمت شما دوستان و کاربران محترم و با آرزوی توفیق روز افزون برای شما عزیزان و با آرزوی امیدواری ساعات خوب و خوش در این وبلاگ. لازم به ذکر است که مطالب به صورت گروه بندی شده در اختیار شما قرار گرفته است که در سمت چپ وبلاگ قرار گرفته است که در حدود 20 عنوان است در ضمن شما می توانید در زمان اجرا لینک های هر مطلب را برداشته و در زمان های بعدی برای دیدن آن مطلب فقط آن لینک را وارد کنید. برای دیدن مطالب گذشته از قسمت آرشیو ماه و سال مورد نظر در وارد کرده و مطالبی که در آن تاریخ وارد شده است مشاهده نمایید. همچنین برای مشاهده وبلاگ های دوستان و سایت های که کاربرد دارد از قسمت لینک های روزانه استفاده کنید. برای دسترسی سریع شما به اخبار روز در آخر وبلاگ اخبار به روز شده سایت ایتنا آورده شده است و لینک آموزشی یکی از سایت های آموزشی آورده شده است . خواشمند است نظرات یا همان انتقادات و پیشنهادات خود را در آخر هر مطلب ذکر کرده و ما را از بهبود کارمان مطلع فرمائید. موتورهای جستجوگر در قسمت های مختلف وبلاگ آورده شده است که نیاز به موتورهای جستجوگر جستجو کنید. برای ارائه مطالب به آدرس الکترونیکی در بالای وبلاگ مراجعه کرده و مطالب خود را در اختیار ما قرار داده تا با ذکر منابع و نویسنده آن را در صفحه اصلی قرار دهیم . لازم به ذکر است این وبلاگ در ابتدا پروژه ای برای درس مبانی اینترنت بود که در ادامه متوجه شدیم که علاقه شدیدی به طراحی وب پیدا کرده ام و آرزو دارم باعث و بانی آن هر کجا که هستند همراه با خانواده ایشان در زیر سایه امن الهی قرار گیرند. 1/10/1385 مصادف با ازدواج حضرت علی (علیه السلام) با بانو حضرت فاطمه (س) که مناسبت ارزشمند را به شما تبریک می گویم. موفق باشید .هادی قنبری نوشته شده توسط هادی قنبری | لینک ثابت |
نكات مفيد براي كار در محيط دلفي موضوع: DELPHI جمعه یکم دی 1385 22:4 محيط دلفي براي برنامه نويسي يكي از بهترين محيطهاي برنامه نويسي است گذشته از كاركرد داخلي و كمپايلر آن كه بسيار قوي و سريع است، محيط آن يعني IDE آنهم قدرت بسيار زيادي دارد كه باعث شده يكي از بهترين اديتورها باشد. در اين مقاله من سعي بر اين داشته ام تا با ارائه يك سري از نكات و كليدهاي ميانبر كه مي توانند براي كار در دلفي بسيار مفيد و كارا باشند، كمك كنم تا شما بتوانيد با قدرت بيشتر به برنامه نويسي و كار در اين محيط قدرتمند ادامه دهيد.
در قسمت اول مقاله كه در حال حاضر در مقابل شماست من يك سري از كليدهاي ميانبر و تركيبي مورد استفاده در IDE دلفي را بصورت ليست وار و همراه يك توضيح كوچك آورده ام. با توجه به اينكه اين مطالب حاصل تجربه هاي خودم در كار با دلفي (از 1 تا 7) بوده ممكنه كه يك سري موارد ديگري هم باشد كه من تا حالا برخورد نداشتم كه دوستان عزيز ميتونند به اين ليست اضافه كنند و نام خود را در انتهاي اين مقاله ذكر كنند و حتما يك نسخه از آن را براي من ارسال كنند. اميدوارم كه اين سري مقالات با كمك شما در اثر مرور زمان بهتر و مفيد تر شود. دوستان عزيز برنامه نويس ممكنه كه شما مدتها با دلفي مشغول برنامه نويسي بوده باشيد اما من يقين دارم كه در اين ليست نكات و روشهاي جديدي را خواهيد آموخت. قسمت اول - كليدهاي ميانبر و تركيبي: جستجو در متن بصورت مستقيم: براي اينكار كليدهاي Ctrl+E را بفشاريد و بدنبال آن شروع به تايپ كلمه مورد نظر كنيد نتيجه آن را خود ببينيد. براي اينكه به كلمه بعدي برويد كافيست كليد F3 را بزنيد. ايجاد فرورفتگي در كد: بعضي اوقات - كه خيلي هم پيش ميآيد - لازم است كه يك مقداري از متن را بصورت بلوك شده به جلو و يا عقب ببريم. منظور دندانه دار كردن متن است كه به خوانايي برنامه كمك مي كند. براي اينكار مي تونيد از كليد Ctrl +Shift+I براي جلو بردن و Ctrl+Shift+U براي عقب برگرداندن متن بلوك شده استفاده كنيد. پرش به قسمت تعريف يك شي (Object): براي اينكه ببنيد شي مورد نظرتون (از قبيل VCL, Procedure, Function,...) در كجا و چطور تعريف شده مي توانيد كليد Crtl رو پايين نگه داشته و روي شي مورد نظر Click كنيد. براي تغيير حالت كاراكترها: شما مي توانيد يك قسمت از متن (كه ممكن است با حروف بزرگ و يا كوچك تايپ شده باشد) را انتخاب كنيد و با زدن كليدهاي Ctrl+o+u به ترتيب تمامي حروف كوچك آن قسمت از متن را به حروف بزرگ و تمامي حروف بزرگ آنرا به حروف كوچك تبديل كنيد. براي تعيير حالت يك كلمه نيز ميتوانيد روي كلمه مورد نظر رفته و كليدهاي Ctrl+k+f براي بزرگ كردن و كليدهاي ctrl+k+e را براي كوچك كردن حروف آن كلمه بكار برد. درست كردن ماكرو متني: اين امكان بسيار مفيد است و مي توانيد بسياري از كارهاي نوشتاري را كاهش دهد با اينكار شما ميتوانيد يك سري از كارهاي تكراري كه روي متون انجام مي دهيد را بصورت ماكرو در آورده و از آنها به راحتي استفاده كنيد. براي شروع به ضبط ماكرو كليدهاي ctrl+shift+r را بفشاريد و آن سري كارهايي را كه مي خواهيد را انجام دهيد و سپس براي اينكه به كار ضبط ماكرو پايان دهيد كليدهاي ctrl+shift+r را دوباره بزنيد. حال براي استفاده از ماكرو كافيست در هر جا كه لازم بود كليدهاي Ctrl+Shift+P را بفشاريد. انتخاب متن بصورت مربعي: اگر شما از كهنه كارهاي كامپيوتر باشيد حتما از زمان داس يادتون هست كه برنامه اي بود به نام PE2 كه يكي از امكانات بسيار جالبش اين بود كه يك مربع از متن رو ميتوانستين انتخاب كنيد و آنرا كپي يا حذف كنيد. بله درست متوجه شديد در محيط دلفي هم شما اينكار را ميتوانيد انجام دهيد اما نه به مشكلي PE2 بلكه اينكار را ميتوانيد فقط با گرفتن كليد Alt و كشيدن موس روي متن انجام دهيد. هر چند ممكن است در نگاه اول زياد اين امكان مفيد به نظر نيايد ولي بعضي وقتهاي خيلي كار را راحت ميكنه، كه حتماً تجربه خواهيد كرد. گذاشتن علامت روي متن: اين كار كه به BookMark معروف است بسيار مفيد و كارا مي باشد. در هنگامي كه شما روي قسمتي از متن برنامه كار ميكنيد و مي خواهيد به يك قسمت ديگر برويد ممكن است براي برگشتن به مكان اول خود كمي مشكل پيدا كنيد. ولي شما ميتوانيد با زدن چند دكمه به محل مورد نظرتون باز گرديد. براي اينكار در خطي كه قصد داريد علامت بگذاريد كليدهاي Ctrl+Shift+0..9 را بفشاريد. منظور اينست كه كليدهاي ctrl+Shift را نگه داريد و يكي از اعداد 0 تا 9 را وارد كنيد تا آن خط به همان شماره علامت گذاري شود و سپس هر جا كه خواستيد برويد و سپس هر بار كه كليد Ctrl را نگه داريد و شماره مورد نظر را وارد كنيد به همان خط باز خواهيد گشت. البته توجه داشته باشيد كه فقط مي توانيد 10 خط را با اين روش علامت گذاري بكنيد و براي برداشتن علامت ها كافيست روي همان خط دوباره كليد Ctrl+shift و شمارهاي كه براي آن خط وارد كرده ايد را بفشاريد با اينكار علامت آن خط برداشته مي شود. ايجاد كلاس مورد نظر : شما هنگامي كه در قسمت Private و يا Public يك type، روال يا تابع درست كرديد لازم داريد كه قسمتي را براي قرار دادن كدهاي مربوط به آن روال يا تابع را ايجاد كنيد. براي اينكار شما پس از اينكه نام تابع را تايپ كرديد مي توانيد كليدهاي Ctrl+Shift+C را فشار دهيد تا دلفي يك قسمت براي نوشتن كدهاي مورد نظرتان ايجاد كند. ظاهر كردن پنجره Code insight : شما حتما به اهميت و مفيد بودن اين قسمت دلفي واقفيد كه در هنگام كد نويسي تا چه حد مي تواند كارها را راحت كند. بله در هنگام وارد كردن كدها بعد از وارد كردن نام يك كلاس و يا Object با زدن يك نقطه (.) پنجره Code Insight ظاهر مي شود. حال در بعضي وقتها شما ممكن است كه نقطه را قبلا وارد كرده باشيد و يا در مواقع ديگر اين پنجره ظاهر نشود. در اين صورت براي اينكه پنجره را ظاهر كنيد بايد دوباره نقطه را وارد كنيد ولي راه اسانتري هم وجود دارد و آن اينست كه كليدهاي Ctrl+Speacebar را فشار دهيد. ظاهر كردن پنجره Code Parameter: همانند بالا در هنگام ظاهر شدن Hint مربوط به راهنماي توابع كه معمولاً بعد از گذاشتن پرانتز مربوط ظاهر ميشود و در مورد پارامترهاي لازم مي باشد نيز مي توانيد از كليدهاي Ctrl+Shift+SpaceBar استفاده كنيد. رفتن از قسمت تعريف توابع و روالها به قسمت كد آنها: هميشه اين نياز وجود خواهد داشت كه شما در هنگامي كه داريد به دنبال يك روال در قسمت type ميگرديد بعد از پيدا كردن نام آن مي خواهيد كه خود آن تابع يا روال را نيز ببنيد. براي اينكار خوب حتما نام آن را جستجو ميكنيد ولي يك راه آسانتر اينست كه شما روي نام آن تابع قرار گيريد و كليدهاي Ctrl+Shift+Up/Down را بزنيد. در اينحالت اگر روي كد تابع باشيد به قسمت تعريف آن خواهيد رفت. خوب اين هم قسمت اول اين مقاله كه اميدوارم مفيد بوده باشد. من منتظر شنيدن نظرات و تجربيات شما هستم. استفاده از اين مقاله در سايتها و ديگر رسانه ها بشرط ذكر نام و نشاني نويسنده بلامانع مي باشد. نوشته شده توسط هادی قنبری | لینک ثابت |
ترفندهاي دلفي شماره 001 (IDN Exclusive Collection 001) موضوع: DELPHI جمعه یکم دی 1385 22:4 *** دو کد زير در دلفي 7 تحت ويندوزهاي 98، 2K و XP تست شده اند ***
يک روش ساده براي نمايش فايلهاي داخل يک folder همراه با Icon آنها و اعلام نوع فايل (استفاده از API) يک ListView، يک ImageList و يک Buttonروي فرم قرار دهيد. کد از نايتي unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls, ImgList, ShellAPI; type TForm1 = class(TForm) ImageList1: TImageList; Button1: TButton; ListView1: TListView; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure InsertFilesInList( strPath: String; ListView: TListView; ImageList: TImageList); var pFile: Integer; Icon: TIcon; SearchRec: TSearchRec; ListItem: TListItem; FileInfo: SHFILEINFO; begin // Create a temporary TIcon Icon := TIcon.Create; ListView.Items.BeginUpdate; try // search for the first file pFile := FindFirst(strPath + '*.*', faAnyFile, SearchRec); while pFile = 0 do begin with ListView do begin // On directories and volumes if ((SearchRec.Attr and FaDirectory <> FaDirectory) and (SearchRec.Attr and FaVolumeId <> FaVolumeID)) then begin ListItem := ListView.Items.Add; //Get The DisplayName SHGetFileInfo(PChar(strPath + SearchRec.Name), 0, FileInfo, SizeOf(FileInfo), SHGFI_DISPLAYNAME); Listitem.Caption := FileInfo.szDisplayName; // Get The TypeName SHGetFileInfo(PChar(strPath + SearchRec.Name), 0, FileInfo, SizeOf(FileInfo), SHGFI_TYPENAME); ListItem.SubItems.Add(FileInfo.szTypeName); //Get The Icon That Represents The File SHGetFileInfo(PChar(strPath + SearchRec.Name), 0, FileInfo, SizeOf(FileInfo), SHGFI_ICON or SHGFI_SMALLICON); Icon.Handle := FileInfo.hIcon; ListItem.ImageIndex := ImageList.AddIcon(Icon); // Destroy the Icon DestroyIcon(FileInfo.hIcon); end; end; pFile := FindNext(SearchRec); end; finally Icon.Free; ListView.Items.EndUpdate; end; end; procedure TForm1.Button1Click(Sender: TObject); begin // Assign a Imagelist to the ListView ListView1.SmallImages := ImageList1; // Show Listview in Report Style and add 2 Columns ListView1.ViewStyle := vsReport; ListView1.Columns.Add; ListView1.Columns.Add; InsertFilesInList('C:\', ListView1, ImageList1); end; end. گاهي بد نيست براي انجام بعضي کارها از خود سيستم کمک بگيريم. کد زير اندازه فايلي که انتخاب ميشود را بر ميگرداند. بد نيست، به درد Text-fileها ميخوره . يک Button، يک Label، يک OpenDialog روي فرم قرار دهيد. کد از کريس بري procedure TForm1.Button1Click(Sender: TObject); var SearchRec: TSearchRec; begin if OpenDialog1.Execute then if FindFirst(OpenDialog1.FileName, faAnyFile, SearchRec) = 0 then Label1.Caption := FloatToStrF(SearchRec.Size/1048576, ffFixed, 7, 2)+' MB'; FindClose(SearchRec); end; نوشته شده توسط هادی قنبری | لینک ثابت |
چگونه يك TRichEdit با پس زمينه Tile بسازيم؟ موضوع: DELPHI جمعه یکم دی 1385 22:3 به نظر مي آيد راهي براي Transparent كردن يك RichEdit عادي يا نقاشي كردن يك تصوير در پس زمينه آن به صورت Tile وجود ندارد.
اما در ويندوز 2000 يك راه عقبي وجود دارد كه با كمك آن مي شود اين كار رو انجام داد. در اين ويندوز شما مي توانيد كنترل خود را با استفاده از مقدار دهي ثابت WS_EX_LAYERED به استيل(Style)هاي توسعه يافته ويندوز و سپس فراخواني تابع APIي به نام SetLayeredWindowAttributes به صورت Transparent در بياوريد. مثال پايين يك كنترل TRichView با پراپرتي DrawStyle است. بسته به مقدار آن، كنترل پس زمينه Transparent خواهد داشت يا خودش را با alpha transparency نقاشي مي كند. constructor MyTransparentRichEdit.Create(AOwner: TComponent); begin inherited Create(AOwner); FDrawStyle := dsNormal; end; procedure MyTransparentRichEdit.CreateParams(var Params: TCreateParams); begin inherited CreateParams(Params); if not (csDesigning in ComponentState) then begin Params.Style := Params.Style or WS_POPUP; Params.ExStyle := Params.ExStyle + WS_EX_LAYERED; end; end; procedure MyTransparentRichEdit.CreateWnd; var XPoint: TPoint; begin if not (csDesigning in ComponentState) then begin XPoint := TWinControl(Owner).ClientToScreen(POINT(Left, Top)); Left := XPoint.X; Top := XPoint.Y; end; inherited CreateWnd; case FDrawStyle of ds_Transparent: SetLayeredWindowAttributes(Handle, ColorToRGB(Color), 255, LWA_COLORKEY); ds_NotDistinctly: SetLayeredWindowAttributes(Handle, 0, 150, LWA_ALPHA); end; end; procedure MyTransparentRichEdit.SetDrawStyle(AValue: TDrawStyle); begin if FDrawStyle <> AValue then begin FDrawStyle := AValue; RecreateWnd; end; end; نوشته شده توسط هادی قنبری | لینک ثابت |
چگونه از فايلهاى PDF در دلفى استفاده كنيم؟ موضوع: DELPHI جمعه یکم دی 1385 22:3 چگونه از فايلهاى PDF در دلفى استفاده كنيم؟
1. دلفى را آغاز كرده و Component | Import ActiveX Control را انتخاب كنيد. 2. به دنبال "(Acrobat Control for ActiveX (Version x.x" بگرديد و به Install را بزنيد. 3. نام پالتى كه كمپوننت مورد نظر بايد در آن نصب شود را انتخاب كنيد. 4. Install را كليك كنيد. 5. Packageي كه قرار است كمپوننت در آن نصب شود را انتخاب كنيد يا يك Package جديد براى كنترل جديد TPdf بسازيد. 6. بر روي OK كليك كنيد. 7. دلفى به شما پيغام مىدهد كه آيا مايل به Rebuild كردن Package جديد/تغييريافته هستيد؟ 8. Yes را كليك كنيد. دلفى به شما پيغام مىدهد كه كمپوننت TPdf نصب شده است. 9. Package را ببنديد و به دلفى اجازه دهيد كه آن را Save كند. 10. حالا كمپوننت در تب ActiveX موجود مىباشد. 13. كمپوننت TPdf را روي فرم بكشيد. 14. با استفاده از Object Inspector پراپرتي src را مطابق آدرس يك فايل PDF كه روى كامپيوتر شما يا وب موجود مىباشد قرار دهيد. حالا تنها كارى كه بايد انجام دهيد تغيير اندازه كمپوننت مورد نظر است. نكات: 1. اگر شما ActiveX مربوطه را نداريد، همين حالا آن را از سايت www.adobe.com داون لود كنيد. چون براي اين مثال ضرورى است. 2. ميتوانيد آخرين مرحله (مرحله 14) را در زمان اجرا يا RunTime انجام دهيد. بنابراين شما مىتوانيد هر فايلى را در اجرا باز كرده و آنرا تغيير اندازه دهيد. نوشته شده توسط هادی قنبری | لینک ثابت |
استفاده از Flash در دلفى موضوع: DELPHI جمعه یکم دی 1385 22:3 Flash يكي از فرمتهاي محبوب وب است و به راحتي مي توان براي ساخت Interfaceها در برنامه از آن استفاده كرد. بعضي از برنامه نويسان معتقدند استفاده از Flash سبب سنگين شدن برنامه، وابستگي برنامه به ActiveX فلش، امكان نداشتن تبادل اطلاعات بين Flash و دلفي و مشكلات ديگري مي شود.
در اين مقاله خواهيد ديد كه به راحتي تمامي اين مشكلات را مي توانيد رفع كنيد. نصب ActiveX فلش براي نصب ActiveX فلش به Component>Import ActiveX Control برويد. در ليست مربوطه به دنبال Shockwave Flash بگرديد. در صورتي كه آن را پيدا نكرديد. دكمه Add را زده و به آدرس زير برويد: WIN_DIRECTORY\System32\Macromed\Flash و فايل Flash.ocx را انتخاب كنيد و سپس Install را بزنيد.خوب ... تا به اينجا كار نصب اكتيوايكس فلش تمام است. كمپوننت مربوطه را ميتوانيد در پالت ActiveX پيدا كنيد. نكته: در صورتي كه شاخه مذكور در كامپيوتر شما وجود ندارد، احتمالا شما Flash Player را نصب نكردهايد. البته نگران نباشيد، با شيوه اي كه در اين مقاله ذكر شده كاربر شما بدون نياز به نصب Flash Player مي تواند برنامه شما را اجرا كند. استفاده از اكتيوايكس فلش اكتيوايكس فلش را ميتوانيد در پالت ActiveX پيدا كنيد. آن را روي فرمتان قرار دهيد. از پراپرتيMovie ميتوانيد براي Load كردن فايل SWF خود استفاده كنيد. به باقى پراپرتىهاى اكتيوايكس فلش دقت كنيد: (البته توضيحات پراپرتىها را به صورت انگليسى آوردهام. چون نوشتن آنها به صورت فارسى زياد جالب نيست. به خاطر اينكه پر از لغاتى هستند كه ترجمهشون غير ممكن است.) ReadyState (get only)
0=Loading, 1=Uninitialized, 2=Loaded, 3=Interactive, 4=Complete. TotalFrames (get only) Returns the total number of frames in the movie. This is not available until the movie has loaded. Wait for ReadyState = 4. FrameNum (get or set) The currently displayed frame of the movie. Setting this will advance or rewind the movie. Playing (get or set) True if the movie is currently playing, false if it is paused. Quality (get or set) The current rendering quality (0=Low, 1=High, 2=AutoLow, 3=AutoHigh). This is the same as the QUALITY parameter. ScaleMode (get or set) Scale mode (0=ShowAll, 1= NoBorder, 2 = ExactFit). This is the same as the SCALE parameter. AlignMode (get or set) The align mode consists of bit flags. (Left=+1, Right=+2, Top=+4, Bottom=+8). This is the same as the SALIGN parameter. BackgroundColor (get or set) Override the background color of a movie. An integer of the form red*65536+green*256+blue use -1 for the default movie color. Loop (get or set) True if the animation loops, false to play once. Same as the MOVIE parameter. Movie (get or set) The URL source for the Flash Player movie file. Setting this will load a new movie into the control. Same as the MOVIE parameter. متدها: Play() Start playing the animation. Stop() Stop playing the animation. Back() Go to the previous frame. Forward() Go to the next frame. Rewind() Go to the first frame. SetZoomRect(int left, int top, int right, int bottom) Zoom in on a rectangular area of the movie. Note that the units of the coordinates are in twips (1440 units per inch). To calculate a rectangle in Flash, set the ruler units to Points and multiply the coordinates by 20 to get TWIPS. Zoom(int percent) Zoom the view by a relative scale factor. Zoom(50) will double the size of the objects in the view. Zoom(200) will reduce the size of objects in the view by one half. Pan(int x, int y, int mode) Pan a zoomed in movie. The mode can be: 0 = pixels, 1 = % of window. نصب اكتيوايكس فلش روي كامپيوتر كاربر براي اين كه كاربر نهايي بتواند از برنامه شما استفاده كند بايد اكتيوايكس فلش را داشته باشد. در واقع شما بايد اكتيوايكس مربوطه را براي او نصب كند. روش كار به اين گونه است كه شما بايد چك كنيد كه آيا كاربر نهايي اكتيوايكس فلش را بر روي دستگاه خود نصب كرده است يا نه و در صورتي كه وي اين اكتيوايكس را ندارد برنامه شما بايد به طور اتوماتيك آن را نصب كنيد. براي پياده سازي اين روش ما بايد در ابتدا OCX فلش را با استفاده از Resourceها در فايل Exe خود مخلوط كنيم. در صورتي كه شما با Resourceها آشنايي نداريد نگران نباشيد. مراحل زير را انجام دهيد و باقي كار را به دلفي بسپاريد: 1- يك فايل Text بسازيد و اسم آن را SWFActivex.rc بگذاريد 2- خطوط زير را در آن قرار دهيد: FlashOCX EXTRA Flash.ocx و فايل Flash.ocx را از مسيري كه قبلا ذكر شد در شاخه پروژه خود قرار دهيد.3- آن را ضبط كنيد و با استفاده از BRCC32.EXE كه در شاخه Bin محل نصب دلفي وجود دارد، آن را كامپايل كنيد. (خط زير را در Command Line تايپ كنيد يا به سادگي فايل SWFActivex.rc را بر روي فايل BRCC32.EXE دراگ (Drag) كنيد. BRCC32.EXE MyExeRes.rc خوب حالا شما يك فايل Resource كامپايل شده داريد به نام SWFActivex.res داريد.4- خطوط زير را در در سورس كد فرم اصلي خود قرار دهيد: ... 5- حالا اين تابع را به كد خود اضافه كنيد:... implementation ... ... ... {$R *.dfm} {$R SWFActivex.RES} function GetResourceFile(S : string; FilePath : string) : Boolean; 6- اين تابع را نيز اضافه كنيد:var Res : TResourceStream; begin Result := True; if S <> '' then begin if FindResource(hInstance, PChar(S), Pchar('EXTRA')) = 0 then begin Result := False; Exit; end; try Res := TResourceStream.Create(hInstance, S, Pchar('EXTRA')); except Result := False; Exit; end; if FileExists(FilePath) then DeleteFile(FilePath); try Res.SaveToFile(FilePath); except Result := False; end; Res.Free; end; end; function GetSystemDir : string; 7- خوب! حالا بگذاريد به مهمترين قسمت قضيه يعني Register كردن OCX مربوطه بپردازيم. در ابتدا يونيت ActiveX را به ليست uses خود اضافه كنيد. سپس تابع زير را نيز به سورس خود اضافه نماييد.var SysPath : PChar; begin GetMem(SysPath, MAX_PATH + 1); GetSystemDirectory(SysPath, MAX_PATH); Result := StrPas(SysPath)+ '\'; FreeMem(SysPath, MAX_PATH + 1); end; function RegisterOCX( OCXFileName : string; Flag : Boolean) : Boolean; 8- اين سه متغيير را نيز به كد خود اضافه كنيد:var OCXHand: THandle; RegFunc: TDllRegisterServer; OCXFileNamePtr : PChar; begin Result := True; if not FileExists( OCXFileName ) then begin Result := False; Exit; end; GetMem(OCXFileNamePtr, Length(OCXFileName) + 1); StrPCopy(OCXFileNamePtr, OCXFileName); OCXHand:= LoadLibrary(OCXFileNamePtr); FreeMem(OCXFileNamePtr, Length(OCXFileName) + 1); OCXFileNamePtr := nil; if OCXHand = 0 then begin Result := False; Exit; end; if Flag then RegFunc:= GetProcAddress(OCXHand, 'DllRegisterServer') else RegFunc:= GetProcAddress(OCXHand, 'DllUnregisterServer'); if RegFunc = S_OK then Result := False; FreeLibrary(OCXHand); end; var 9- تابع زير را نيز اضافه كنيد:FilePath : string; FlashOCX: TShockwaveFlash; function CreateFlashOCX : Boolean; 10- كدهاي زير را به انتهاي فايل خود، قبل از .end اضافه كنيد:var FilePath : string; begin Result := True; FilePath := GetSystemDir + 'Macromed\Flash\Flash.ocx'; if not GetResourceFile('FlashOCX', FilePath) then begin Result := False; Exit; end; try FlashOCX := TShockwaveFlash.Create(nil); except if not RegisterOCX(FilePath, True) then Result := False else try FlashOCX := TShockwaveFlash.Create(nil); except Result := False; end; end; end; initialization CoInitialize(nil); if not CreateFlashOCX then ShowMessage('An Error Occured!' + #13 + 'Program dosent run correctly!'); finalization if Assigned(FlashOCX) then begin try FlashOCX.Free; FlashOCX := nil; except end; DeleteFile(FilePath); end; CoUninitialize; end. end. FlashOCX.Parent := Form1; Resize شدن درستFlashOCX.Movie := ExtractFilePath(Application.ExeName) + 'Main.swf'; FlashOCX.Play; يكي از مشكلاتي كه ممكن است با اكتيو ايكس فلش پيدا كنيد مشكل Resize شدن است. همه ما مي دانيم كه يكي از مهمترين مزاياي فلش برداري بودن آن است و اين برداري بودن سبب مي شود كه فايل فلش بتواند در هر اندازه به درستي نشان داده شود. ولي متاسفانه فرم خود را در RunTime تغييراندازه مي دهيد فايل Flash تغيير اندازه نمي يابد. در اين جا يك راه حل ساده براي حل اين مشكل بيان شده كه به خوبي كار ميكند. كافي است كمپوننت فلش را در يك پانل قرار دهيد و پراپرتي Align آن را برابر alClient بگذاريد. حالا پراپرتي Anchor پانل خود را به گونهاي تنظيم كنيد كه مايل هستيد كمپوننت فلش Resize شود. سپس در اونت OnResize فرم خود، خطوط زير را درج كنيد: FlashOCX.Parent := nil; غيرفعال كردن كليك سمت راستFlashOCX.Parent := Self; مساله ديگرى كه ذهن بسيارى از برنامهنويسان را مشغول مىكند منوى Popup فلش است. غيرفعال كردن اين منو بسيار ساده است. كافي است يك كمپوننت TApplicationEvents را روي فرم خود قرار دهيد و كد زير را در اونت OnMessage اين كمپوننت بنويسيد: if (Msg.message = WM_RBUTTONDOWN) and (Msg.hwnd := FlashOCX) thenيكى از مسائل بسيار مهم و اساسى ديگر برقرارى ارتباط بين Flash و دلفي است. فرض كنيد در فايل SWF خود چند Button داشته باشيد و بخواهيد وقتى كاربر روى هر كدام از اين اونتها كليك كرد فرم خاصى باز شود. در اين صورت چه بايد بكنيد. پياده سازى اين كار بسيار ساده است. كافى است در Flash براى هر كدام از دكمههاى خود يك Action تعريف كنيد و از دستور FSCommand استفاده نماييد. از يك مقدار دلخواه مثل fMatn يا fSearch استفاده كنيد و در دلفى نيز از اونت OnFSCommand به صورت زير استفاده كنيد: if command = 'fMain' then fMain.ShowModal; if command = 'fSearch' then fSearch.ShowModal; خوب! فكر كنم با توضيحاتى كه در اين مقاله اومده، قانع شده باشيد كه Flash يكى از بهترين راه حلها براى طراحى Interfaceهاست. تا مقاله بعد .... به اميد ديدار نوشته شده توسط هادی قنبری | لینک ثابت |
آشنايى با FastReport سادهترين و قوىترين كمپوننت گزارشسازى موضوع: DELPHI جمعه یکم دی 1385 22:2 كمي تاريخچه
FastReport قبلا با نام FreeReport عرضه مي شد و يك محصول رايگان بود. ولي بعدها به FastReport تغيير نام پيدا كرد و به صورت تجاري عرض گرديد. البته هنوز كمپوننت FreeReport توسعه مي يابد و نسخه هاي جديدتر آن را از سايت www.fastreport.com يا www.fastreport.ru مىتوانيد داون لود كنيد. آشنايي كلي با شكل گزارش سازي در FastReport اين كمپوننت يك محيط Report Desinger در اختيار شما قرار مي دهد كه با استفاده از آن مي توانيد Reportها را طراحي كنيد، اسكريپت نويسي كنيد و يا فرم هاي جديد براي انتخابي كردن گزارش خود ايجاد كنيد. براي وارد شدن به اين Report Desinger بايد از كمپوننت TfrReport استفاده كنيد. كافي است يك كمپوننت TfrReport روي فرم بگذاريد و روي آن دابل كليك كنيد يا كليد سمت راست را زده و گزينه Design Report را انتخاب كنيد. ممكن است اين محيط كه موسوم به Desinger است در ابتدا كمي شلوغ به نظر بيايد ولي در انتهاي اين مقاله آموزشي كاملا با استفاده از اين Desinger آشنا خواهيد شد. ![]() ساخت يك گزارش ساده يك كمپوننت TfrReport را روي فرم قرار دهيد و روى آن دابل كليك كنيد تا به محيط Report Designer برويم. خوب ... مىخواهيم براى شروع يك گزارش بسيار ساده بسازيم. از ToolBar سمت چپ گزينه Insert rectangle object را انتخاب كنيد. آيكن اين گزينه شبيه به آيكن كمپوننتMemo است. مىبينيد كه وقتى اين كمپوننت را در محل مربوطه قرار مىدهيد پنجره اى باز مي شود: ![]() خوب! اولين گزارش خودمون رو ساختيم. حالا به سادگى گزارش را Save كنيد و اسم اون رو بگذاريد Test. اين فايل رو در همون جايى ضبط كنيد كه پروژه تون در اونجا Save شده است. حالا Designer رو ببنديد و يك Button روي فرمتون بگذاريد و و در اونت OnClick آن كد زير رو بنويسيد: frReport1.LoadFromFile('Test.frf'); خوب! كار ساخت اولين گزارشمون تمام شد. ما خيلي ساده در ابتدا گزارشى را كه قبلا ساخته بوديم Load كرديم و بعدش هم از متد ShowReport براى نمايش گزارش استفاده كرديم. البته مىتوانستيم از متد PrintPreparedReportDlg براى چاپ مستقيم گزارش بدون نمايش پيشنمايش يا Preview استفاده كنيم.frReport1.ShowReport; نكته: در صورتى كه بخواهيم ميتوانم با True كردن پراپرتي StoredInDFM گزارش را در EXE خود ضبط كنيم. در آن صورت لازم نيست گزارش را ضبط كنيم و همچنين احتياجى نيست كه آن را در كد Load بكنيم. اين حالت تنها وقتى مفيد است كه برنامه شما فقط يك گزارش داشته باشد. خوب! ما تا حالا اصول استفاده از FastReport رو ياد گرفتيم. در باقي اين مقاله آموزشى گزارشهاى پيشرفتهترى مىسازيم و آرام آرام شما با FastReport احساس راحتى مىكنيد. ساخت يك گزارش ديگر خوب ... يك كمپوننت TTable رو از پالت BDE روى فرمتون قرار دهيد و پراپرتي DatabaseName آن را برابر DBDEMOS و پراپرتى TableName را برابر Biolife قرار دهيد. يك كمپوننت TfrReport و همچنين يك كمپوننت TfrDBDataSet روى فرم قرار دهيد و پراپرتى DataSet آن را برابر نام Table1 قرار دهيد و پراپرتى DataSet كمپوننت TfrReport را برابر frDBDataSet1 قرار بدهيد. حالا با كليك بر روى كمپوننت frReport1 وارد محيط Designer شده و Tools>Tools>Insert DB Fields را انتخاب كنيد. خوب شما انتخاب كنيد و آن را روي فرم قرار دهيد. پنجره اي شبيه به شكل زير نمايش داده مىشود: ![]() خوب تقريبا كارمان تمام است. اگر خوب نگاه كنيد مي بينيد كه دو باند روى فرم گزارش اضافه شد كه يكى Page Header و ديگرى Master Data نام دارد. File>Preview را انتخاب كنيد و ببينيد گزارش شما چه شكلى خواهد بود. گزارش خودتان را Save كنيد و از روشى كه قبلا ذكر شد براى نمايش گزارش در زمان اجرا يا Run-Time استفاده كنيد. ساخت گزارشهاى پيشرفتهتر به موارد زير توجه كنيد: 1- اگر بخواهيد از كمپوننتهايى مثل RichEdit - Chart - CheckBox و ... در گزارش خود استفاده كنيد بايد كمپوننت مربوطه را روى فرم برنامه خود قرار دهيد. 2- اگر بخواهيد امكان Export گزارش به فرمتهاى HTML - Text - CSV يا DOC را به برنامه خود بدهيد بايد كمپوننت مربوطه را روى فرم برنامه خود قرار دهيد. 3- اگر بخواهيد گزارش Master-Detailى بسازيد بايد از دو باند Master data و Detail data استفاده كنيد. 4- اگر بخواهيد مجموع مقادير يك فيلد رو در انتهاى يك گزارش بنويسيد بايد از يك باند Master footer استفاده كنيد و گزينه Insert rectangle object را انتخاب كنيد. سپس Insert Expression را انتخاب كنيد. Functions را انتخاب كنيد و از تابع Count براى انجام اين كار استفاده كنيد. همچنين مىتوانيد Variables را انتخاب كنيد و از مواردى همچون شماره صفحه، كل صفحات، تاريخ و ... استفاده كنيد. اميدوارم اين مقاله بتونه هر چند اندك شما رو با FastReport آشنا كنه پايان نوشته شده توسط هادی قنبری | لینک ثابت |
آموزش دلفی قسمت دوم موضوع: DELPHI جمعه یکم دی 1385 22:1 قسمت دوم
قبل از اين كه وارد محبث دستورات زبان پاسكال شويم، لازم است كه با مجموعه اي از عناصر و اشكال كد نويسي اين زبان آشنا شويم. سوالي كه من در اين فصل به دنبال پاسخ آن هستم اين است كه قواعد كلي براي نوشتن كد به زبان پاسكال چيست؟ پاسخ واحد و يكساني به اين سوال وجود ندارد زيرا كه سلايق مختلف مي تواند سبب ساخت اشكال گوناگوني از كدنويسي شد. با اين حال اصولي همچون توضيح نويسي، نوشتن با حروف بزرگ يا UpperCase، فاصلهها و ... وجود دارد كه شما بايد بدانيد. به طور كلي هدف تمامي انواع كد نويسي وضوح بيشتر است. مسئله مهم نوع كدنويسي شما نيست بلكه اين مهم است كه به سبك و سياق كدنويسي خود پايبند و وفادر باشيد. توضيحات در پاسكال، توضيحات را مي توان به هر يك از اشكال زير به كار برد: { اين يك توضيح است } (* اين يك توضيح ديگر است *) // اين يك توضيح يك خطي است و در انتهاي اين خط پايان مي يابد اولين حالت از همه كوتاهتر است و معمولا از همه بيشتر استفاده مي شود. حالت سوم نيز از ++C استعارفه گرفته شده است و تنها در نسخه هاي 32 بيتي دلفي عمل مي كند. توضيحات از اين نوع وقتي كه شما مي خواهيد توضيحات خلاصه اي را راجع به يك خط از كد بدهيد بسيار مفيد هستند.
داشتن سه حالت مختلف از توضيحات وقتي مفيد است كه بخواهيد توضيحات تو در تو داشته باشيد. اگر شما بخواهيد قطعات مختلفي از كد را به صورت توضيح دربياورد تا آنها را غيرفعال كنيد و اين خطوط حاوي يكسري توضيحات واقعي باشند، شما نمي توانيد از همان شكل توضيح استفاده كنيد. { ..... يكسري كد پاسكال در صورتي كه مي توانيد اين كد را به صورت زير بنويسيد { ...... يكسري كد پاسكال
استفاده از حروف بزرگ كامپايلر پاسكال مثل بسياري كامپايلرهاي ديگر به حروف بزرگ و كوچك حساس نيست. بنابراين نام Myname، MyName، myName و MYNAME همگي دقيقا يكي هستند. روي هم رفته، اين مساله صراحتا مثبت است، زيرا زبان هايي كه حساس به شكل حروف هستند سبب ايجاد خطاهاي بسياري خواهند شد. توجه داشته باشيد كه شما بايد از حروف بزرگ براي بيشتر قابل خواندن بودن كد استفاده كنيد. يك راه بسيار عالي براي اين مساله بزرگ تايپ كردن حروف اول كلمات است (شما نمي توانيد در بين نام متغييرها از فاصله استفاده كنيد). مثال: MyLongIdentifier بر خلاف BASIC، پاسكال به شما اجازه مي دهد كه چند خط كد را در يك خط طولاني بنويسيد. فقط كافي است در انتهاي هر خط از سيميكلون (؛) استفاده كنيد و پس از آن خط بعدي را بنويسيد. Highlight كردن نحوي براي ساده تز شدن خواندن و نوشتن كد هاي پاسكال، اديتور دلفي خاصيت به نام Highlight كردن نحوي يا Syntax Highlighting دارد. بنابر معناي هر يك از كلماتي كه شما در اديتور دلفي تايپ مي كنيد، هر كلمه رنگ تازه اي مي يابد. به طور پيش فرض كليدواژه ها سياه هستند، رشته ها و توضيحات به صورت رنگي و اغلب ايتاليك هستند و همين جور الي اخر. احتمالا كلمات رزرو شده، توضيحات و رشته ها بيشترين اجزايي هستند كه از اين خاصيت سود مي جويند. شما به يك نگاه مي توانيد از كليدواژه هاي اشتباه تايپ شده، رشته اي كه به درستي بسته نشده است و طول يك توضيح چند خطي آگاه شويد. شما مي توانيد به سادگي رنگ هاي استفاده شده به وسيله IDE دلفي را از طريق صفحه Editor Colors پنجره Environment Options تغيير دهيد. ( به شكل 2.1 نگاهي بياندازيد) اگر شما براي خودتان كار مي كنيد رنگهايي را كه بيشتر دوست مي داريد انتخاب كنيد. اگر شما با ساير برنامه نويسان به صورت گروهي كار مي كنيد همگي بايد يك رنگ بندي استاندارد را قبول كنيد. من متوجه شده ام كه كار كردن با يك رايانه با رنگ بندي هاي متفاوت كه به وسيله افراد مختلف استفاده مي شود واقعا سخت است.
استفاده از قالب هاي كد دلفي 3 يك خصوصيت جديد را راجع به ويرايش كد معرفي نمود. با استفاده از اين خاصيت لازم نيست شما تمامي حروف يك كلمه يا دستور را تايپ كنيد. فقط چند حرف اول آن را تايپ كنيد و كليد Ctrl+J را براي كلمات كليدي و Ctrl+Space را براي ساير كلمات و دستورات استفاده كنيد. در اين صورت مشاهده خواهيد كرد كه منويي ظاهر خواهد شد و دستوراتي را كه با حروف مورد نظر شما شروع مي شوند را به نمايش خواهند گذاشت.
كلمات كليدي، تمام لغاتي هستند كه بوسيله Object Pascal رزرو شده اند و در نقش هاي اساسي را در زبان بازي مي كنند. كلمات كليدي نمي توانند به عنوان نام متغييرها استفاده شوند. در جدول 2.1 ليستي از اين كلمات را مي بينيد. جدول 2.1 - كليدواژه ها و ساير كلمات كليدي در آبجكت پاسكال
عملگرها در پاسكال
اختتاميه اكنون كه ما شكل و شمايل كلي برنامه هاي پاسكال را مي دانيم ما مي توانيم فهميدن و درك كردن آن را آغاز كنيم. ما با آشنايي با نوع هاي پيش فرض و ساخت نوع هاي جديد كار خودمان را آغاز مي كنيم نوشته شده توسط هادی قنبری | لینک ثابت |
نكات ريز و درشت در دلفي موضوع: DELPHI جمعه یکم دی 1385 22:0 چگونه تمامي رويدادهاي يك شيء را در زمان اجرا به Nil تنظيم كنيم؟ در اين مقاله روشي را جهت اينكه تمامي رويدادهاي يك شيء تعريف شده در دلفي را در زمان اجرا به Nil تنظيم كنيد براي شما بازگو ميكنيم. شما ميتوانيد از RTTIها جهت رسيدن به اهداف خود استفاده كنيد اما فقط براي زمان طراحي و اجرا و اين امكان براي رويدادها وجود ندارد. استفاده از RTTI، تا حدودي پيچيده است بنابراين من رويهاي را براي نسبت دادن Nil به يك شيء موجود در زمان اجراي يك برنامه در دلفي آوردهام كه نحوه انجام اين كار را به شما نشان ميدهد. unit uNilEvent; چگونه رويداد مربوط به تمامي اجزاء درون برنامه خود را تغيير دهيم؟ گاهي لازم ميشود تا ما فراميني را براي يكي از رويدادهاي برنامه خود به تمامي اشياء استفاده شده در برنامه نسبت دهيم اينكار ميتواند با استفاده از RTTI دلفي صورت گيرد شما مثالي را ميبينيد كه اين كار را شبيهسازي كرده است. uses نوشته شده توسط هادی قنبری | لینک ثابت |
دلفی 7 موضوع: DELPHI جمعه یکم دی 1385 22:0 در ويرايش دلفي 7، شركت بورلند تغييراتي را در ساختار داخلي دلفي داده است كه مهمترين آن حمايت و توانايي برنامهنويسي بر اساس تكنولوژي .NET ميباشد. اين بدين معنااست كه برنامهنويسان دلفي ميتوانند از هم اكنون به محيط .Net framework سوئيچ كنند و از مزاياي برنامهنويسي در آن كه ميتوان به داشتن كلاسهاي برنامهنويسي فراوان، امنيت بالاي برنامهنويسي و وابسته نبودن به محيط برنامهنويسي و محيط اجراي برنامه را نام برد. ويرايش جديد دلفي 7 در دو CD ارائه شده است كه CD اول كامپايلر دلفي بوده و CD دوم شامل نسخه Preview از .Net framework جهت اجراي برنامههاي نوشته شده توسط دلفي 7 ميباشد. لازم به ذكر است كه كاربران بايد حتماً .Net را بر روي سيستم خود نصب كنند تا بتوانند در محيط دلفي 7 برنامهنويسي كنند. حداقل سيستمي كه جهت كار با دلفي 7 پيشنهاد ميشود بايد داراي مشخصات زير باشد: - Intel Pentium II/233MHz يا بالاتر - MS Windows 98, 2000, XP - RAM 64MB (البته 128MB پيشنهاد ميشود) - 520MB فضاي خالي روي ديسك سخت - درايو CD-ROM - كارت گرافيكي SVGA يا بالاتر امكانات جديد درون دلفي 7 شامل چندين بخش ميباشد : - افزودن ابزار Model Driven Architecture (MDA) به دلفي، اين يكي از محصولات معروف شركت نرم افزاري بورلند ميباشد كه امكان ميدهد تا شما بتوانيد بهتر و قويتر معماري برنامه خود را كنترل و پشتيباني كنيد اين محصول براساس UML بوده و مدلهاي Rose را نيز حمايت ميكند. - طراحي و مدلسازي برنامهها با UML : يكي از ويژگيهاي ويرايش 7 دلفي حركت به سمت برنامه نويسي و طراحي شيءگرا با ابزار UML ميباشد. محصول Mode Maker از معروفترين اين ابزارها ميباشد كه جهت طراحي پروژه با UML در محيط دلفي توسط شركتي به همين نام نوشته شده است. در اين محصول شما امكان طراحي كلاسها و دياگرامهاي UML را داريد كه سورس دلفي آنها نيز بطور خودكار براي شما نوشته ميشود. - ايجاد برنامههاي C-business : در ويرايش جديد شما ميتوانيد به راحتي به توليد برنامههاي مبتني بر Web اقدام كنيد Websnap و bizsnap در ويرايش جديد كامل شدهاند و تكنولوژي .Net را نيز همراه خود دارند، اين قابليت بزرگي ميباشد زيرا شما با كمترين زمان ممكن ميتوانيد به توليد محصولات تحت وب بپردازيد و فروشگاههاي تجاري خود را ايجاد كنيد. - ايجاد برنامههاي كاربردي با ويندوز XP : از ديگر قابليتهاي جديد دلفي 7 افزودن حالات و شكل و قيافه ويندوز XP با VCLهاي دلفي ميباشد. اين امكان به شما اجازه ميدهد تا برنامههاي قويتري را در محيط ويندوز پيادهسازي كنيد. - افزايش قدرت دلفي 7 در تهيه گزارشات و حمايت از محيطهاي كاري باعث شده است تا بتوان روي اين محصول بعنوان يكي از كامپايلرهاي قوي در محيط .Net سرمايه گذاري كرد، حمايت از Kylix3 در ويرايش جديد و توانايي برنامه نويسي تحت Linux از ديگر تواناييهاي دلفي ويرايش 7 ميباشد. - امكان ايجاد سيستمهاي چند لايه (3-tier) براساس ساختار DCOM، COM+ و CORBA بر پايه تكنولوژي Datasnap و حمايت از تمامي بانكهاي اطلاعاتي معروف دنيا از قبيل DBZ ،Oracle ،MySQL ،SQL Server و ... كه در ويرايش 6 دلفي نيز وجود داشت ولي در ويرايش جديد اين امكانات بهتر، سريعتر و قويتر شده است. نوشته شده توسط هادی قنبری | لینک ثابت |
مقدمه اي بر سي شارپ : قسمت بيستم موضوع: NET. جمعه یکم دی 1385 21:56 Delegates Delegates در سي شارپ روشي مطمئن و typesafe را براي بكار گيري مفهوم function pointer ارائه مي دهند. يكي از ابتدايي ترين استفاده هاي function pointers پياده سازي callback مي باشد. اما در ابتدا لازم است تا با اصول اوليه ي كاري آن آشنا شويم. مثال يك : يك delegate چگونه تعريف و استفاده مي شود؟ Delegate يك شيء است كه بيانگر يك تابع مي باشد بنابراين مي تواند بعنوان آرگومان ورودي يك تابع ديگر و يا عضوي از يك كلاس بكار رود. در زبان "function-pointer" ، Func1() اشاره گري به Func2() را بعنوان پارامتر دريافت كرده و نهايتا آنرا فراخواني مي كند. در زبان "delegate" ، Func1() يك شيء delegate از Func2() را دريافت كرده و سپس آنرا فراخواني مي كند. در مثال زير از دو تابع براي شرح اين مطلب سود جسته شده است: Func1() از delegate استفاده مي كند. Func2() يك delegate است. ( شماره گذاري خطوط ، در كد زير ، صرفا براي راحت تر شدن توضيحات در مورد آنها است و لزومي به تايپ آنها در برنامه ي اصلي نيست. ) 01 using System; LINE 02 02 delegate void Delg(string sTry); 03 public class Example1{ // function which uses the delegate object 04 private static void Func1(Delg d){ 05 d("Passed from Func1"); 06 } // function which is passed as an object 07 private static void Func2(string sToPrint){ 08 Console.WriteLine("{0}",sToPrint); 09 } // Main execution starts here 10 public static void Main(){ 11 Delg d = new Delg(Func2); 12 Func1(d); 13 } 14 } يك شيء delegate را براي Func2 تعريف مي كند. LINE 04-06 تابعي را تعريف كرده است كه آرگومان ورودي آن از نوع Delg است. LINE 07-09 تابعي را تعريف مي كند كه بايد به صورت delegate به تابع ديگر فرستاده شود. LINE 10-14 تابع Main اجراي برنامه را با ايجاد يك شيء delegate براي Func2 آغاز كرده و سپس تابع Func1 را فراخواني مي كند. مثال 2: چگونه مي توان از delegates در كارهاي عملي استفاده كرد؟ طرح يك مساله: شخصي تقاضاي ثبت نام در يك مؤسسه ي آموزشي و همچنين تقاضاي كاريابي در يك شركت را داده است. هر كدام از اين نهادها روشي خاص خود را براي ارزيابي شخص دارند. راه حل (با روشي شيء گرا): شخص مشخصاتي همچون سن / جنس / ميزان تحصيلات قبلي / تجربيات كاري و مدارك مرتبط دارد. مؤسسه ي آموزشي تعدادي از اين مشخصات را براي ارزيابي شخص استفاده مي كند و اين امر در مورد شركت ياد شده نيز صادق است. شيء شركت و شيء آموزشگاه هر كدام توابع ارزيابي خاص خودشان را پياده سازي مي كنند. شخص ، اينترفيسي واحدي را در اختيار شركت / آموزشگاه براي ارزيابي خود قرار مي دهد. پياده سازي (با استفاده از سي شارپ): ما delegateايي را تعريف مي كنيم كه بيانگر اينترفيسي است كه به شركت و آموزشگاه اجازه ي چك كردن شخص را مي دهد. سه كلاس school و company و person را تعريف مي نماييم. كلاس test را براي آزمودن اين موارد ايجاد مي كنيم. 01 using System; LINE 03 02 using System.Collections; 03 public delegate bool GetChecker(Person p); // Person has his information with him as he // applies for School and Company 04 public class Person 05 { 06 public string Name; 07 public int Age; 08 public bool Graduate; 09 public int YearsOfExp; 10 public bool Certified; 11 public Person(string name, int age, bool graduate, int yearsOfExp, bool certified) 12 { 13 Name=name; 14 Age=age; 15 Graduate=graduate; 16 YearsOfExp=yearsOfExp; 17 Certified=certified; 18 } 19 public bool CheckMe(GetChecker checker) 20 { 21 return(checker(this)); 22 } 23 } // A school, the person applied for higher studies 24 public class School 25 { 26 public static bool SchoolCheck(Person p) 27 { 28 return (p.Age>10 && p.Graduate); 29 } 30 } // A Company, the person wants to work for 31 public class Company 32 { 33 public static bool CompanyCheck(Person p) 34 { 35 return (p.YearsOfExp>5 && p.Certified); 36 } 37 } // A Test class, displays delegation in action 38 public class Test 39 { 40 public static void Main() 41 { 42 Person p1 = new Person("Jack",20,true,6,false); 43 Console.WriteLine("{0} School Check : {1}", p1.Name, p1.CheckMe(new GetChecker(School.SchoolCheck))); 44 Console.WriteLine("{0} Company Check : {1}", p1.Name, p1.CheckMe(new GetChecker(Company.CompanyCheck))); 45 } 46 } Delegate مورد نياز را تعريف مي كند. LINE 04-23 كلاس person را تعريف مي كند. اين كلاس تابعي پابليك را ارائه مي دهد كه آرگومان ورودي آن از نوع GetChecker مي باشد. LINE 24-30 كلاس school را تعريف مي كند و سپس تابعي را كه delegate است ارائه مي دهد. LINE 31-37 كلاس company را تعريف مي كند و سپس تابعي را كه delegate است ارائه مي دهد. LINE 38-36 كلاس test را پياده سازي مي نمايد. سپس يك شيء شخص ساخته مي شود. در ادامه new GetChecker(School.SchoolCheck) و new GetChecker(Company.CompanyCheck) شيء ايي را ايجاد مي كند از نوع delegate مورد نياز و آنرا به تابع CheckMe مي فرستد. خروجي نتيجه ي ارزيابي اين شخص مي باشد. اگر چك كردن اشخاص بيشتري نياز باشد به اين صورت عمل مي شود: Person p1 = new Person("Jack",20,true,6,false); مثال 3 : Person p2 = new Person("Daniel",25,true,10,true); GetChecker checker1= new GetChecker(School.SchoolCheck); GetChecker checker2= new GetChecker(School.CompanyCheck); Console.WriteLine("{0} School Check : {1}", p1.Name,p1.CheckMe(checker1)); Console.WriteLine("{0} Company Check : {1}", p1.Name,p1.CheckMe(checker2)); Console.WriteLine("{0} School Check : {1}", p2.Name,p2.CheckMe(checker1)); Console.WriteLine("{0} Company Check : {1}", p2.Name,p2.CheckMe(checker2)); Delegates در تعامل بين دات نت فريم ورك و سي شارپ چه نقشي دارد؟ طرح يك مساله: نمايش دادن ميزان پيشرفت خواندن يك فايل هنگامي كه حجم فايل بسيار زياد است. راه حل ( با استفاده از سي شارپ): در مثال زير از كلاس FileReader براي خواندن يك فايل حجيم استفاده شده است. هنگاميكه برنامه مشغول خواندن فايل است 'Still reading.. را نمايش مي دهد و در پايان 'Finished reading..'. را عرضه مي كند. براي اينكار از فضاي نام System.IO استفاده شده است. اين فضاي نام حاوي delegate ايي مهيا شده براي ما مي باشد. بدين ترتيب مي توانيم به دات نت فريم ورك بگوييم كه ما تابعي را تعريف كرده ايم كه او مي تواند آنرا فراخواني كند. سؤال: چه نيازي وجود دارد تا دات نت فريم ورك تابع ما را فراخواني و اجرا كند؟ با استفاده از تابع ما كه دات نت فريم آنرا صدا خواهد زد در طول خواندن فايل به ما گفته مي شود كه بله! من هنوز مشغول خواندن هستم! به اين عمليات Callback نيز گفته مي شود. به اينكار پردازش asynchronous نيز مي گويند! 01 using System; LINE 02 02 using System.IO; 03 public class FileReader{ 04 private Stream sInput; 05 private byte[] arrByte; 06 private AsyncCallback callbackOnFinish; 07 public FileReader(){ 08 arrByte=new byte[256]; 09 callbackOnFinish = new AsyncCallback(this.readFinished); 10 } 11 public void readFinished(IAsyncResult result){ 12 if(sInput.EndRead(result)>0){ 13 sInput.BeginRead(arrByte, 0, arrByte.Length, callbackOnFinish, null); 14 Console.WriteLine("Still reading.."); 15 } 16 else Console.WriteLine("Finished reading.."); 17 } 18 public void readFile(){ 19 sInput = File.OpenRead(@"C:\big.dat"); 20 sInput.BeginRead(arrByte, 0, arrByte.Length, callbackOnFinish, null); 21 for(long i=0;i<=1000000000;i++){ // just to introduce some delay 22 } 23 } 24 public static void Main(){ 25 FileReader asynctest=new FileReader(); 26 asynctest.readFile(); 27 } 28 } فضاي نام System.IO را به برنامه ملحق مي كند. اين فضاي نام به صورت خودكار حاوي تعريف delegate زير مي باشد: public delegate void AsyncCallback (IAsyncResult ar); LINE 03-10 تعريف كلاس LINE 06 شيء delegate را تعريف مي كند. LINE 07-10 سازنده ي كلاس را پياده سازي مي كنند. در اينجا ما تصميم گرفته ايم كه بافري حاوي 256 بايت را در هر لحظه بخوانيم. LINE 09 شيء delegate نمونه سازي شده است. LINE 18-23 readFile را پياده سازي مي كند. LINE 12-16 نحوه ي استفاده از شيء IAsyncResult را بيان مي كند. LINE 12 sInput.EndRead(result) تعداد بايتهاي خوانده شده را بر مي گرداند. اين خواندن تاجايي كه تعداد بايتهاي خوانده شده صفر است ادامه پيدا مي كند و در اينجا 'Finished reading..' اعلام مي گردد. نوشته شده توسط هادی قنبری | لینک ثابت |
مقدمه اي بر سي شارپ : قسمت نوزدهم موضوع: NET. جمعه یکم دی 1385 21:56 سربارگذاري عملگر ها (Operator OverLoading)
به تعريف مجدد راه و روش اجراي عملگر ها توسط ما ، سربارگذاري عملگرها گفته مي شود. فرض كنيد مي خواهيد عدد 2 را به يك مقدار datetime اضافه كنيد. خطاي زير حاصل خواهد شد: CS0019: Operator '+' cannot be applied to operands of type 'System.DateTime' and 'int' جالب بود اگر مي توانستيم عدد 2 را به datetime اضافه كنيم و نتيجه ي آن تعداد روزهاي مشخص بعلاوه ي دو مي بود. اينگونه توانايي ها را مي توان بوسيله ي operator overloading ايجاد كرد. تنها عملگر هاي زير را مي توان overload كرد: Unary Operators نحوه ي انجام اينكار نيز در حالت كلي به صورت زير است: + - ! ~ ++ -- true false Binary Operators + - * / % & | ^ << >> == != > < >= <= return_datatype operator operator_to_be_overloaded (agruments) { } به مثال زير توجه كنيد: using System; class MyDate { public DateTime tempDate; public MyDate(int year,int month,int day) { tempDate=new DateTime(year,month,day); } public static DateTime operator + (MyDate D,int noOfDays) { return D.tempDate.AddDays(noOfDays); } public static DateTime operator + (int noOfDays,MyDate D) { return D.tempDate.AddDays(noOfDays); } } class Test { static void Main() { MyDate MD=new MyDate(2001,7,16); Console.WriteLine(MD + 10 ); } } output: 2001-07-26 در مثال فوق عملگر + دوبار overload شده است. يكبار توسط آن مي توان يك عدد صحيح را به يك تاريخ اضافه كرد و بار ديگر يك يك تاريخ را مي توان به عدد صحيح افزود. موارد زير را هنگام سربارگذاري عملگرها به خاطر داشته باشيد: 1- تنها اپراتورهاي ذكر شده را مي توان overload كرد. اپراتورهايي مانند new,typeof, sizeof و غيره را نمي توان سربارگذاري نمود. 2- خروجي متدهاي بكار گرفته شده در سربارگذاري عملگر ها نمي تواند void باشد. 3- حداقل يكي از آرگومانهاي بكار گرفته شده در متدي كه براي overloading عملگرها بكار مي رود بايد از نوع كلاس حاوي متد باشد. 4- متدهاي مربوطه بايد به صورت public و static تعريف شوند. 5- هنگامي كه اپراتور < را سربارگذاري مي كنيد بايد جفت متناظر آن يعني > را هم سربارگذاري نماييد. 6- هنگاميكه براي مثال + را overload مي كنيد خودبخود =+ نيز overload شده است و نيازي به كدنويسي براي آن نيست. يكي از موارد جالب بكار گيري سربارگذاري عملگرها در برنامه نويسي سه بعدي و ساختن كلاسي براي انجام عمليات ماتريسي و برداري مي باشد نوشته شده توسط هادی قنبری | لینک ثابت |
مقدمه اي بر سي شارپ : قسمت هجدهم موضوع: NET. جمعه یکم دی 1385 21:55 مقابله با خطاها در سي شارپ (Exception Handling in C#) EXCEPTION يك خطاي زمان اجر است كه بدليل شرايطي غيرنرمال در برنامه ايجاد مي شود. در سي شارپ exeption كلاسي است در فضاي نام سيستم. شيء ايي از نوع exception بيانگر شرايطي است كه سبب رخ دادن خطا در كد شده است. سي شارپ از exception ها به صورتي بسيار شبيه به جاوا و سي پلاس پلاس استفاده مي نمايد. دلايلي كه بايد در برنامه exception handling حتما صورت گيرد به شرح زير است: - قابل صرفنظر كردن نيستند و اگر كدي اين موضوع را در نظر نگيرد با يك خطاي زمان اجرا خاتمه پيدا خواهد كرد. - سبب مشخص شدن خطا در يك نقطه از برنامه شده و ما را به اصلاح آن سوق مي دهد. بوسيله ي عبارات try...catch مي توان مديريت خطاها را انجام داد. كدي كه احتمال دارد خطايي در آن رخ دهد درون try قرار گرفته و سپس بوسيله ي يك يا چند قطعه ي catch مي توان آنرا مديريت كرد. و اگر از اين قطعات خطايابي استفاده نشود برنامه به صورتهاي زير متوقف خواهد شد : class A {static void Main() {catch {}}} بهتر است يك مثال ساده را در اين زمينه مرور كنيم: TEMP.cs(3,5): error CS1003: Syntax error, 'try' expected class A {static void Main() {finally {}}} TEMP.cs(3,5): error CS1003: Syntax error, 'try' expected class A {static void Main() {try {}}} TEMP.cs(6,3): error CS1524: Expected catch or finally int a, b = 0 ; برنامه شروع به اجرا مي كند. سپس وارد بلوك و يا قطعه ي try مي گردد. اگر هيچ خطايي هنگام اجراي دستورات داخل آن رخ ندهد ، برنامه به خط آخر جهش خواهد كرد و كاري به قطعات catch ندارد. Console.WriteLine( "My program starts " ) ; try { a = 10 / b; } catch ( Exception e ) { Console.WriteLine ( e ) ; } Console.WriteLine ( "Remaining program" ) ; The output of the program is: My program starts System.DivideByZeroException: Attempted to divide by zero. at ConsoleApplication4.Class1.Main(String[] args) in d:\dont delete\consoleapplication4\class1.cs:line 51 Remaining program اما در اينجا در اولين try عددي بر صفر تقسيم شده است بنابراين كنترل برنامه به بلوك catch منتقل مي شود و صرفا نوع خطاي رخ داده شده نوشته و نمايش داده مي شود. سپس برنامه به كار عادي خودش ادامه مي دهد. تعدادي از كلاس هاي exception در سي شارپ كه از كلاس System.Exception ارث برده اند به شرح زير هستند : • Exception Class - - Cause در كد فوق صرفا عمومي ترين نوع از اين كلاس ها كه شامل تمامي اين موارد مي شود مورد استفاده قرار گرفت يعني : • SystemException - A failed run-time check;used as a base class for other. • AccessException - Failure to access a type member, such as a method or field. • ArgumentException - An argument to a method was invalid. • ArgumentNullException - A null argument was passed to a method that doesn't accept it. • ArgumentOutOfRangeException - Argument value is out of range. • ArithmeticException - Arithmetic over - or underflow has occurred. • ArrayTypeMismatchException - Attempt to store the wrong type of object in an array. • BadImageFormatException - Image is in the wrong format. • CoreException - Base class for exceptions thrown by the runtime. • DivideByZeroException - An attempt was made to divide by zero. • FormatException - The format of an argument is wrong. • IndexOutOfRangeException - An array index is out of bounds. • InvalidCastExpression - An attempt was made to cast to an invalid class. • InvalidOperationException - A method was called at an invalid time. • MissingMemberException - An invalid version of a DLL was accessed. • NotFiniteNumberException - A number is not valid. • NotSupportedException - Indicates sthat a method is not implemented by a class. • NullReferenceException - Attempt to use an unassigned reference. • OutOfMemoryException - Not enough memory to continue execution. • StackOverflowException - A stack has overflown. catch ( Exception e ) اگر نيازي به خطايابي دقيقتر باشد مي توان از كلاس هاي فوق براي اهداف مورد نظر استفاده نمود. مثالي ديگر: ( در اين مثال خطايابي دقيق تر با استفاده از كلاس هاي فوق و همچنين مفهوم finally نيز گنجانده شده است ) int a, b = 0 ; قسمت موجود در قطعه ي فاينالي همواره صرفنظر از قسمت هاي ديگر اجرا مي شود. Console.WriteLine( "My program starts" ) ; try { a = 10 / b; } catch ( InvalidOperationException e ) { Console.WriteLine ( e ) ; } catch ( DivideByZeroException e) { Console.WriteLine ( e ) ; } finally { Console.WriteLine ( "finally" ) ; } Console.WriteLine ( "Remaining program" ) ; The output here is: My program starts System.DivideByZeroException: Attempted to divide by zero. at ConsoleApplication4.Class1.Main(String[] args) in d:\dont delete\consoleapplication4\class1.cs:line 51 finally Remaining program به مثال زير دقت كنيد : int a, b = 0 ; قسمت چاپ Remaining program اجرا نشده است. Console.WriteLine( "My program starts" ) try { a = 10 / b; } finally { Console.WriteLine ( "finally" ) ; } Console.WriteLine ( "Remaining program" ) ; Here the output is My program starts Exception occurred: System.DivideByZeroException: Attempted to divide by zero.at ConsoleApplication4.Class1. Main(String[] args) in d:\dont delete\consoleapplication4 \class1.cs:line 51 finally عبارت throw : اين عبارت سبب ايجاد يك خطا در برنامه مي شود. مثال : int a, b = 0 ; در اين حالت قسمت فاينالي اجرا شده و برنامه بلافاصله خاتمه پيدا مي كندConsole.WriteLine( "My program starts" ) ; try { a = 10 / b; } catch ( Exception e) { throw } finally { Console.WriteLine ( "finally" ) ; } نوشته شده توسط هادی قنبری | لینک ثابت |
مقدمه اي بر سي شارپ : قسمت هفدهم موضوع: NET. جمعه یکم دی 1385 21:55 در كلاس CCommObj كه با آن آشنا شديم ، آرايه اي Private از نوع ICommObjEvents به نام m_arSinkColl وجود دارد. اين آرايه تمام اينترفيس هاي sink شده را ذخيره مي كند. واژه ي sink در اينجا به كلاسي گفته مي شود كه دريافت كننده ي رخدادها است. متد Advise تنها sink وارده به آنرا در يك آرايه ذخيره مي كند و سپس انديس آرايه را كه در اينجا cookie ناميده شده است بر مي گرداند. اين كوكي توسط كلاينتي كه ديگر نمي خواهد از آن آيتم هيچونه رخدادي را دريافت كند به سرور فرستاده مي شود و سپس سرور اين آيتم را از ليست خودش حذف خواهد كرد. نحوه ي فراخواني متد advise توسط كلاينت نيز جالب است. public void Init(CCommObj theSource) در اينجا تنها يك this بعنوان آرگومان به متد advice فرستاده شده است در حاليكه انتظار مي رفت آرگوماني از نوع ICommObjEvents به تابع فرستاده شود. دليل صحت اين عمل بدين صورت است كه كلاس ClientApp_A از اينترفيس ICommObjEvents ارث برده است و آنرا پياده سازي نموده است. { m_Server = theSource; theSource.Advise (this); string strAdd = ("Hello"); m_Server.read (strAdd,10); } در ادامه ليست كامل برنامه ي نوشته شده را در حالت Console ملاحظه مي فرماييد. namespace CSharpCenter در متد Main برنامه ي فوق ، ما دو كلاينت تعريف كرده ايم و يك نمونه از CCommObj را. دو كلاينت instance هاي CCommObj را بعنوان آرگومان دريافت كرده اند. در هنگام فراخواني init توسط هر كلاينت متد advise فراخواني مي گردد. در خاتمه Read مربوط به كلاينت 1 فراخواني شده است كه سبب مي شود تا رخداد OnDataSend شيء CCommObj اجرا شود و به تمام كلاينت ها فرستاده شود. { using System; public interface ICommObjEvents { void OnDataSent(); void OnError(); } public class CCommObj { private int m_nIndex; public ICommObjEvents [] m_arSinkColl; public CCommObj() { m_arSinkColl = new ICommObjEvents[10]; m_nIndex = 0; } public void Advise(ICommObjEvents theSink) { m_arSinkColl[m_nIndex] = theSink; m_nIndex++; } public void SendData(string strData) { foreach ( ICommObjEvents theSink in m_arSinkColl) { if(theSink != null ) { theSink.OnDataSent (); } } } } class CClientApp_A:ICommObjEvents { public void OnDataSent() { Console.WriteLine("OnDataSent Client App A"); } public void OnError() { Console.WriteLine("OnError"); } public void Read() { string strAdd = ("Hello"); m_Server.SendData (strAdd); } private CCommObj m_Server; public void Init(CCommObj theSource) { m_Server = theSource; theSource.Advise (this); } } class CClientApp_B:ICommObjEvents { public void OnDataSent() { Console.WriteLine("OnDataSent Client App B"); } public void OnError() { Console.WriteLine("OnError"); } private CCommObj m_Server; public void Init(CCommObj theSource) { m_Server = theSource; theSource.Advise (this); } } class ConsoleApp { public static void Main() { CClientApp_A theClient = new CClientApp_A (); CClientApp_B theClient2 = new CClientApp_B (); CCommObj theComm = new CCommObj (); theClient.Init (theComm); theClient2.Init (theComm); theClient.Read(); } } } هدف از اين مثال ارائه ي بعضي از جنبه هاي اينترفيس ها و نحوه ي استفاده از آنها بود. دو مطلب ديگر در مورد اينترفيس ها باقي مانده اند تا به پايان بحث مربوط به آنها برسيم: چگونه مي توان متوجه شد كه يك شيء واقعا يك اينترفيس را پياده سازي كرده است؟ دو روش براي فهميدن اين موضوع وجود دارد: - استفاده از كلمه ي كليدي is - استفاده از كلمه ي كليدي as اولين مثال زير از كلمه ي كليدي is استفاده مي كند : CClientApp_C theClient3 = new CClientApp_C (); كلمه ي كليدي is مقدار true را بر مي گرداند اگر اپراتور سمت چپ ، اينترفيس سمت راست را پياده سازي كرده باشد. if(theClient3 is ICommObjEvents) Console.WriteLine ("theClient3 implements ICommObjEvents"); else Console.WriteLine ("theClient3 doesnot implement ICommObjEvents"); ICommObjEvents theClient5 = theClient3 as ICommObjEvents; در مثال فوق اپراتور as در حال casting شيء theClient5 به ICommObjEvents مي باشد. چون CClientApp_C اينترفيس را پياده سازي نمي كند حاصل خط اول نال خواهد بود. if(theClient5 != null ) Console.WriteLine ("Yes theClient implements interface"); else Console.WriteLine ("NO,Yes theClient doesn't implements interface"); به صورت خلاصه : يك اينترفيس قراردادي است كه به كلاينت گارانتي مي دهد يك كلاس خاص چگونه رفتار خواهد كرد. هنگاميكه كلاسي يك اينترفيس را پياده سازي مي كند به تمام كلاينت ها مي گويد كه : من تمام موارد ذكر شده در اينترفيس را ارائه و پياده سازي خواهم كرد. نمونه ي عملي استفاده از اينترفيس ها بحث dot net remoting است. نوشته شده توسط هادی قنبری | لینک ثابت |
مقدمه اي بر سي شارپ : قسمت شانزدهم موضوع: NET. جمعه یکم دی 1385 21:54 كلاس ها ي abstract كلاس ها را همچنين مي توان به صورت abstract تعريف كرد. از اين نوع كلاس ها نمي توان instance ايي را ايجاد نمود. در اين كلاس هاي پايه ، صرفا تعريف متدها و خواص هايي عنوان گرديده و در آينده در كلاس هاي فرزند توسعه داده خواهند شد. براي مثال : public abstract class Named والي كه شايد پيش بيايد اين است كه اگر interface ها صرفا تعريف توابع و خواص را مي توانند در خود جاي دهند پس چه دليلي براي بكار بردن آنها و طولاني كردن كار كد نويسي وجود دارد؟ { public abstract String Name {get; set;} // property public abstract void PrintName(); // method } public class B : Named { private String name = "empty"; public override String Name { get{return name;} set{name=value;} } public override void PrintName() { Console.WriteLine("Name is {0}", name); } } كاربردهاي زيادي را مي توان براي اينترفيس ها برشمرد. اينترفيس يك رفتار را تعريف مي كند. فرض كنيد در حال توسعه ي برنامه ايي هستيد كه بر روي دو كامپيوتر مختلف بايد با هم در ارتباط مستقيم بوده و برهم كنش داشته باشند و هر برنامه از ماژولي به نام CCommObj communication object استفاده مي نمايد. يكي از متدهاي اين شيء ، SendData() مي باشد كه رشته اي را دريافت كرده و به برنامه ي ديگر مي فرستد. اين فراخواني از نوع asynchronous است زيرا ما نمي خواهيم اگر خطايي در شبكه رخ داد، برنامه براي هميشه منتظر باقي بماند. اما چگونه برنامه ي A كه تابع ذكر شده را فراخواني كرده است مي تواند تشخيص دهد كه پيغام به مقصد رسيده است يا خير و يا آيا خطايي در شبكه مانع رسيدن پيغام گشته است يا خير؟ جواب بدين صورت است كه CCommObj هنگام دريافت پيغام ، رخدادي را سبب خواهد شد و اگر خطايي رخ داده باشد خير. در اين حالت نياز به يك ماژول logging نيز احساس مي گردد تا خطاهاي رخ داده را ثبت نمايد. يك روش انجام آن اين است كه CCommObj پياده سازي اين امكان را نيز بعهده گرفته و اگر فردا نيز خواستيم ماژول ديگري را به برنامه اضافه كنيم هر روز بايد CCommObj را تغيير دهيم. تمام اين كارها را به سادگي مي توان در يك اينترفيس مدل كرد. روش آن نيز در ادامه بيان مي گردد: در ابتدا يك اينترفيس ايجاد مي كنيم تا ليست تمام امكانات ممكن را "منتشر" كند: interface ICommObjEvents شي ء CCommObj ما از اين توابع كه بعدا توسعه داده خواهند شد براي با خبر سازي كلاينت ها استفاده مي نمايد. تمام متدها در يك اينترفيس ذاتا پابليك هستند بنابراين نيازي به ذكر صريح اين مطلب نمي باشد و اگر اينكار را انجام دهيد كامپايلر خطاي زير را گوشزد خواهد كرد : { void OnDataSent(); void OnError(); } The modifier 'public' is not valid for this item در ادامه كلاينت CClientApp_A را پياده سازي خواهيم كرد : class CClientApp_A:ICommObjEvents در كد فوق كلاس CClientApp_A از ICommObjEvents ارث برده و تمام متدهاي اين اينترفيس را پياده سازي نموده است. هنگامي كه CCommObj تابع OnDataSent را فراخواني مي كند اين كلاينت پيغام را دريافت خواهد كرد. لازم به ذكر است كه كلاس كلاينت ما چون از يك اينترفيس ارث بري مي نمايد پس بايد تمام توابع و خواص كلاس پايه را پياده سازي كند در غير اينصورت هر چند برنامه كامپايل خواهد شد اما هنگامي كه شيء CCommObj هر كدام از توابع اين كلاس را فراخواني كد ، خطاي زمان اجرا رخ خواهد داد. { public void OnDataSent() { Console.WriteLine("OnDataSent"); } public void OnError() { Console.WriteLine("OnError"); } private CCommObj m_Server; public void Init(CCommObj theSource) { m_Server = theSource; theSource.Advise (this); string strAdd = ("N450:1"); m_Server.read (strAdd,10); } } متد Init كلاس فوق آرگوماني را از نوع CCommObj دريافت نموده و در يك متغير private آنرا ذخيره مي نمايد. همچنين در اين متد ، متد Advise از كلاس CCommObj نيز فراخواني گشته است. public class CCommObj { private int m_nI | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||