موضوع :
بـرنـامـه نـويـسـي دلـفـي
درس مباحث ويژه
ارائه شده به :
مهندس طاهر زاده
توسط :
مجید حسینی
بهمن ماه سال 1386
تاریخچه زبان دلفی:
تاریخچه مختصری از زبان دلفی از زمان پیدایش تا دلفی 6 به تفکیک نسخههای مختلف آن.
دلفی در واقع یک کامپایلر پاسکال است. دلفی 6 نسل جدید کامپایلر های پاسکال است که شرکت Borland از زمان ایجاد اولین نسخه پاسکال توسط Andres Hejlsberg در 15 سال پیش به بازار عرضه کرد.
برنامه نویسی به زبان پاسکال در سالیان سال از استواری و ثبات، زیبایی و ظرافت و البته سرعت بالای کامپایل سود برده است. دلفی هم از این قاعده مستثنی نیست. کامپایلر دلفی ترکیبی از بیش از یک دهه تجربه طراحی کامپایلر پاسکال و معماری بهبود یافته کامپایلر های 32 بیتی است. اگرچه قابلیت های کامپایلرها با گذشت زمان پیشرفت قابل توجهی داشته است ولی سرعت آن چندان کاهش نیافته و همچنان از سرعت بالایی برخوردار است. به علاوه استحکام و قدرت کامپایلر دلفی معیاری برای سنجش دیگر کامپایلر هاست.
در اینجا به بررسی تفصیلی روند حرکتی دلفی در هر یک از نسخه های آن می پردازیم و مشخصات مهم آن را بررسی می کنیم.
سال 1995 - Delphi1
در زمان استفاده از سیستم عامل DOS برنامه نویسان مجبور بودند از بین زبان پر قدرت ولی کم سرعت Basic و زبان کارآمد ولی پیچیده و نامفهوم Assembly یکی را انتخاب کنند. پاسکال با ارائه یک زبان ساخت یافته و یک کامپایلر سریع و کم نقص این شکاف را پرکرد. برنامه نویسان Windows 3.1 هم با تصمیم گیری مشابهی رو برو شدند. یکی زبان قدرتمند و سنگین ++C و یکی زبان ساده و محدود کننده Visual Basic .
ارائه Delphi1 در این مورد هم راه حل خوبی برای برنامه نویسان بود. دلفی مجموعه متفاوتی برای برنامه نویسی بود . طراحی و توسعه برنامه های کاربردی، ایجاد DLL ها، پایگاههای داده و ... که یک محیط ویژوال وسیع را تشکیل می داد. Delphi1 اولین ابزار برنامه نویسی ویندوز بود که محیط طراحی ویژوال، کامپایلر بهینه کد برنامه و دسترسی قوی به پایگاههای داده را در یک جا جمع کرد که آن را به یکی از بهترین ابزارهای روش نوین توسعه سریع نرم افزار (Rapid Application Development) تبدیل کرد. این مجموعه قدرتمند باعث شد که در همان زمان بسیاری از برنامه نویسان زبانهای دیگر به Delphi روی بیاورند و این موفقیت بزرگی برای Borland به حساب می آمد. همچنین بسیاری از برنامه نویسان پاسکال دلفی را ابزاری یافتند که توسط آن هم از توانایی و تجربه خود در برنامه نویسی پاسکال استفاده می کردند و هم توانایی کار در ویندوز را به دست آوردند. همچنین زبانی که در آن زمان با نام پاسکال شیئی (ObjectPascal) در دانشگاهها ایجاد شده بود یک زبان بسیار خشک و محدود کننده بود که اصلاٌ حالت کاربردی پیدا نکرد.
ویژگیهای دلفی مثل طراحی ظاهری حساب شده و کاربر پسند آن باعث شد که زبان پاسکال شیئی عملاٌ از رده خارج شود. تیم طراحی VB در Microsoft قبل از حضور دلفی هیچ رقیب مهمی برای خود نمی دید. VisualBasic در آن زمان زبانی نا کارآ ، کم سرعت و کند ذهن بود. Visual Basic 3 در عمل اصلا توانایی رقابت با Delphi 1 را نداشت. در این سال شرکت Borland گرفتار یک سری مشکلات قضائی با شرکت Lotus بود که در نهایت هم متخلف شناخته شد. همچنین درگیری مشابهی هم با Microsoft بر سر تلاش در تغییر دادن فضای نرم افزار های Microsoft پیدا کرد. همچنین Borland مشغول طراحی و فروش طرح Quatro به شرکت Novell و طراحی پایگاه های داده dBase و Paradox بود که با استقبال قابل توجهی مواجه نشد.
در این زمان که Borland مشغول فعالیتهای قضایی و تجاری بود Microsft توانست گوی سبقت را از Borland برباید و قسمت اعظم بازار ابزار های برنامه نویسی تحت Windows را در اختیار بگیرد و سعی می کرد تا این طرز فکر را اشاعه دهد که چون Windows را طراحی کرده صلاحیت و توانایی تهیه بهترین ابزار های برنامه نویسی تحت آن را نیز در دست دارد. در این شرایط Borland با عرضه Delphi و نسخه جدید ++Borland C سعی کرد خدشه ای در فرمانروایی Microsoft وارد کند و سهمی در بازار بزرگ این محصولات داشته باشد.
سال 1996 - Delphi2
یک سال بعد Delphi2 تمام مزایای نسخه قبلی را تحت سیستم های جدید 32 بیتی (Windows 95,Windows NT) ارائه داد. همچنین Delphi2 با ارائه خصوصیات اضافه و کارکرد های قویتری نسبت به Delphi1 توانایی های خود را افزایش داد. (ازجمله ارائه کامپایلر 32 بیتی که سرعت بالایی به نرم افزار ها می بخشید، کتابخانه بزرگ و کاملی از اشیای مختلف، شیوه جدید و تکامل یافته ای برای اتصال به پایگاه های داده مختلف، ادیتور پیشرفته، پشتیبانی از OLE ، توانایی وراثت در فرمهای ویژوال و سازگاری با پروژه های 16 بیتی Delphi1 ). Delphi2 به معیاری برای سنجش و مقایسه همه ابزارهای توسعه نرم افزار در آن زمان تبدیل شد.
در آن زمان با ارائه سیستم 32 بیتی Windows95جهش بزرگی در سیستم عامل Windows رخ داد و Borland بسیار مشتاق بود که Delphi را به بهترین ابزار برنامه نویسی سیستم جدید تبدیل کند. نکته این که در آن زمان به منظور تاثیر در افکار عمومی و تاکید بر قدرت Delphi در سیستم عامل 32 بیتی قرار بود که نرم افزار با نام جدید Delphi32 به بازار عرضه شود ولی در آخرین مراحل به خاطر اینکه نشان دهند این زبان زبانی رشد یافته و تکامل یافته نسخه قبلی یعنی Delphi1 است نام Delphi2 را برای آن انتخاب کردند.
Microsoft تلاش کرد که با Visual Basic 4 با Delphi مقابله کند ولی از ابتدا کیفیت پایین آن و ضعف آن در انتقال برنامه های 16 بیتی به سیستم 32 بیتی و بروز اشکالات ساختاری در طراحی آن موجب شکست زودهنگام Visual Basic 4 شد. در این زمان هنوز تعداد زیادی از برنامه نویسان به Visual Basic وفادار بودند. Borland هنچنین روشها و ابزارهای قدرتمندی همچون PowerBuilder برای طراحی نرم افزار های Client/Server ارائه داد ولی Delphi هنوز آن قدر قدرتمند نشده بود که بتواند نرم افزارهایی که جایی در بین توسعه گران پیدا کرده اند را براندازد.
سال 1997 - Delphi3
از زمان تهیه و توسعه Delphi1 تیم توسعه Delphi در فکر گسترش و ایجاد یک زبان قدرتمند جهانی بود. برای Delphi2 این تیم تمام نیروی خود را صرف اعمال مربوط به انتقال تواناییها و کارکرد ها به سیستم 32 بیتی و همچنین اضافه کردن خصوصیات Client/Server و پایگاه داده کرد. در زمان تهیه Delphi3 تیم توسعه فرصت لازم برای گسترش مجموعه ابزار موجود را یافت و در این راستا کیفیت و کمیت ابزارهای Delphi بهبود یافت. به علاوه راه حل هایی برای مشکلات عمده و قدیمی برنامه نویسان تحت ویندوز ارائه شد. به ویژه استفاده از برخی فناوری های پیچیده و نا مفهوم (مثل COM و ActiveX وتوسعه نرم افزار های تحت Web وکنترل پایگاههای داده چند کاربره). روش نمایش کد برنامه همچنین توانایی کامل کردن خودکار کد (Code Completion) عملیات کد نویسی را راحت تر کرد. ضمن این که همچنان در بیشتر موارد اساس و متدولوژی برنامه نویسی مانند Delphi1 بود و بر پایبندی به قوانین اصولی Pascal تاکید می شد.
در این زمان رقابت شرکت های تولید کننده ابزار های برنامه نویسی بسیار تنگاتنگ شده بود. Microsoft با ارائه Visual Basic 5 به پیشرفت های خوبی دست یافت ازجمله پشتیبانی قوی از COM و ActiveX و ایجاد برخی خصوصیات و تغییرات کلیدی و اساسی در کامپایلر VB. ضمن این در همین سال Borland با پشتوانه قوی Delphi و با استفاده از ساختار موفق آن ابزارهای دیگری همچون Forte و BC++ Builder به بازار عرضه کرد.
تیم Delphi در زمان طراحی Delphi3 چند تن از اعضای کلیدی خود را از دست داد. Andres Hejlsberg معمار اصلی Delphi در اقدام غیر منتظره ای Borland را ترک کرد و تصمیم گرفت به رقیب دیرینه یعنی Microsoft بپیوندد. اما حرکت تیم Delphi متوقف نشد و معاون Hejlsberg که سالها تجربه همکاری با او را داشت توانست رهبری این تیم را به خوبی در دست بگیرد. همچنین مسئول فنی تیم (Paul Gross) هم در اقدام مشابهی به گروه Microsoft ملحق شد. این تغییرات بیشتر به خاطر اختلافات شخصی بین افراد تیم بود و نه به خاطر مسائل حرفه ای.
سال 1998 - Delphi4
Delphi4 بیشتر بر روی راحتتر کردن کار با دلفی متمرکز شد. مرورگر روال ها (Module Explorer) بهبود یافت و مرور و ویرایش Unit ها را راحت تر کرد. کنترل کد و کامل کردن خودکار کلاسها این فرصت را به کاربر داد که فکر و زمان خود را روی ساختار اصلی برنامه بگذارد و در وقت صرفه جویی کند. طراحی رابط کاربر هم کاملاٌ عوض شد و بهبود یافت و اشکال زدا (Debugger) نیز پیشرفت قابل توجهی داشت. Delphi4 قابلیتهای برنامه نویسان را در استفاده از تکنولوژیهای چند منظوره خارجی مثل MIDAS ، DCOM ، MIS و Corba افزایش داد.
در این سال Delphi جایگاه خود را در رقابت با دیگران مستحکم کرده بود و کم کم به سمت دست یابی به سودآوری مالی مورد نظر خود پیش می رفت. در واقع در این زمان بود که حاصل کار سنگین چند ساله تیم نمایان می شد. بعد از سالها آزمایش Delphi شهرت و محبوبیت خاصی پیدا کرد و دیگر برنامه نویسان Delphi توانایی جدا شدن از آن را نداشتند. در این زمان Borland به کار سوٌال برانگیزی دست زد و به منظور تبلیغ بیشتر و برتری در جنگ روانی با دیگر شرکتها نام Inprise را برای فعالیتهای تجاری خود برگزید.
ابزار های مربوط به فن آوری Corba را گسترش داد تا راه جدیدی برای سودآوری ایجاد کند. برای موفقیت در این زمینه Corba نیاز به رابط کاربر قدرتمندی داشت که در کنار توانایی های آن کار کردن با آن نیز راحت باشد. دقیقاٌ همان کاری که در سالهای قبل در مورد COM و برنامه نویسی تحت Web انجام شده بود و به موفقیت دست یافته بود. با این وجود بنا به دلایل مختلفی این گسترش و توسعه Corba هیچ وقت تکامل و موفقیتی که مورد نظر بود را به دست نیاورد و بر خلاف تبلیغات و سرمایه گذاری های انجام شده فن آوری Corba تنها توانست نقش کوچکی در روند رو به جلوی Delphi ایفا کند.
سال 1999 - Delphi5
Delphi5 در برخی زمینه ها پیشرفت های قبلی را ادامه داده است. اولاٌ مسیری را که Delphi4 با اضافه کردن ویژگیهای زیادی شروع کرده بود ادامه داد. Delphi4 باعث شد کارهایی که قبلاٌ به صرف وقت زیادی احتیاج داشت بسیار سریعتر انجام شود. Delphi به شکل امیدوار کننده ای به برنامه نویس این امکان را می دهد که بیشتر به برنامه ای که میخواهد بنویسد توجه کند و نه به قواعد برنامه نویسی و نوشتن کدهای تکراری و خسته کننده. این ویژگیهای سودمند شامل رابط کاربر بهبودیافته و سیستم اشکال زدایی(Debugger) توانمند ، امکانات برنامه نویسی تیمی و ابزار های ترجمه میشود.
ثانیا Delphi5 خصوصیات جدیدی را در بر می گیرد که توسعه برنامه های تحت وب را واقعاٌ راحت کرده است. این ویژگیها شامل طراح اشیای مربوط به ASP برای ساختن صفحات (Active Server Page)، اشیایی موسوم به Internet Express برای پشتیبانی از XML و خصوصیات جدید MIDAS که آن را به یک ابزار همه کاره در پایگاه های داده تحت Web تبدیل کرد. در نهایت با صرف وقت ، هزینه و صبر زیاد توانست Delphi5 قدرتمند را عرضه کند. این فعالیت مدتها به طول انجامید و قبل از عرضه عمومی، Delphi5 بارها در بازبینی ها و آزمایشهای داخلی قسمتهای مختلف آن تغییر کرد و بهبود یافت.
Delphi5 در نیمه دوم سال 1999 به بازار عرضه شد و به نفوذ و تسلط بر بازار ادامه داد. در این زمان Visual Basic که کم کم به عضوی تحقیر آمیز برای Microsoft تبدیل می شد هم با پیشرفتهایی توانست در رقابت دوام بیاورد و از صحنه خارج نشود. در اقدام درست و به جایی نام Inprise دوباره به Borland بازگشت. این اقدام از سوی طرفداران و مشتریان قدیمی Borland با استقبال خوبی مواجه شد.
سال 2001 – Delphi6
در هنگام تهیه Delphi6 ساختار Delphi در زمینه های مختلف شکل گرفته بود و به یک تکامل نسبی رسیده بود. این مسئله باعث شد که تیم طراحی بتواند وقت خود را بر روی طرحی که مدتها تنها در حد یک نظریه بود بگذارد و آن را بسیار زودتر از آن که انتظار می رفت عملی کند: گام نهادن به محیط های فراتر از Windows . بیشتر نیروی توسعه گران Delphi در این مدت صرف رهانیدن Delphi از بند Windows شد که این خود در درجه اول مبارزه ای آشکار با سلطه Microsoft بود و ثانیاٌ راه برنامه نویسان را به سوی فضا های دیگر برنامه نویسی باز کرد. در ابتدا این عمل ریسک بزرگی بود و بیم آن می رفت که جایگاه Delphi در Windows هم به خطر بیفتد ولی در نهایت به نقطه رشد و قوتی بدل شد که Delphi را به یکی از بهترین ابزار برنامه نویسی Multi Platform تبدیل کرد.تکنولوژی CLX روالهای مختلف Delphi را با Kylix (عضو جدید خانواده Borland که در فضای Linux کار می کند) به اشتراک گذاشت و استفاده از سیستم بایت Java باعث شد که Delphi حتی از قید سخت افزار هم رها شود.
به نظر می رسد که این فعالیتها باعث ثبات Delphi در دنیای برنامه نویسان شود و نگرانی های Borland و برنامه نویسان که همیشه می ترسیدند که مبادا با ضعیف شدن Windows جایگاه خود را از دست بدهند حال به افتخار و آرامش برای آنان و نگرانی برای طرفداران Microsoft تبدیل شده است.
منبع: Borland Delphi Developer's Guide, Essentials of Rapid Development Advanced Techniques
مدیریت حافظه در دلفی:
گاهی مواقع شاید شما احتیاج داشته باشید خودتان مستقیما به حافطه دسترسی داشته باشید و آنرا کنترل کنید. در این متن نگاهی به مدیریت حافظه در دلفی و همچنین حافظههای Heap و Stack خواهیم داشت.
تخصیص خودکار حافظه:
وقتی شما از نوعهای پایه (Integer ،real ،word و…) برای ایجاد متغییرهای خود استفاده می کنید، هیچ نگرانی درباره تخصیص حافظه آن وجود ندارد چون دلفی خودش آنرا تخصیص حافظه می کند و سپس آزاد میکند.
type
TDay = (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday);
var
Name : String; {256 Bytes}
X, Y : Integer; {4 + 4 = 8 Bytes}
List : array [0..10] of Double; {8 * 11 = 88 Bytes}
Today : TDay; {1 Byte}
دراین نمونه پس از پایان برنامه، تمام حافظه تخصیص داده شده فراخوانی و آزاد می شود.
تخصیص حافظه دینامیکی:
در این حالت برنامه نویس احتیاج دارد تا انباره حافظه را شخصا" تخصیص و آزاد کند.
نوع :Pointer
اشارهگرها در دلفی میتوانند شکلهای مختلفی را در برگیرد. نخست، نوع اشارهگری که یک آدرس حافظه را برای نوع ویژهای از داده، همانند صحیح، رشته و غیره نگه میدارد (Typed Pointer).
var
Number : ^Integer;
Name : ^String;
دوم، اشارهگرهای بدون نوع. اشارهگرهای بدون نوع (Untyped Pointers) خیلی به نوع معمولی خود شبیه هستند. اما محدودیتهایی مثل اینکه باید به نوع خاصی اشاره (Point) کند را ندارد.
var
Something : Pointer;
حال اشارهگر بدون نوع ما می تواند به هر نوعی از داده اشاره کند. برای تخصیص حافظه آن، از کمپلکس بیش از یک بیت استفاده میکنیم. برای مثال برنامه زیر کامپایل می شود ولی در زمان اجرا حافظهای تخصیص نمیشود.
begin
New(Something);
Dispose(Something);
end;
برای تخصیص حافظه کامپایلر باید بداند که نوع داده ما برای تخصیص حافظه چیست:
type
IntPtr = ^Integer;
var
Something : Pointer;
begin
Something := New(IntPtr);
Integer(Something^) := 10;
Dispose(Something);
end;
تخصیص بلاکی از حافظه:
ما میتوانیم از اشاره به بلاکهایی از تخصیص حافظه در سیستم استفاده کنیم. این کار را با رویههای GetMem و FreeMem برای تخصیص و آزاد سازی حافظه استفاده میکنیم.
var
Something : Pointer
begin
GetMem(Something, 100);
FreeMem(Something, 100);
end;
اشاره به حافظه از قبل تخصیص داده شده:
هر دو نوع اشارهگرها می توانند به هر جایی از حافظه اشاره بکنند. این بدان معناست که آنها میتوانند اشاره به فضای اشغال شده با دادههایی که در حال حاضر موجودند داشته باشند. این نمونه اشارهگر احتیاجی به تخصیص حافظه ندارد.
var
Something : Pointer;
MyString : PChar; // type PChar = ^Char;
begin
GetMem(Something, 100);
MyString := Something;
StrCopy(Something, 'Hello World');
FreeMem(Something, 100);
end;
حافظه :Heap
Heap شامل قسمتی از حافظه موجود در یک برنامه است که آنرا حافظه پویا می نامیم. Heap بخشی است که در آن تخصیص و تعریف حافظه به صورت تصادفی (Random) اتفاق میافتد. این به آن معناست که اگر شما سه بلاک از حافظه را به طور متوالی تخصیص دهید، می توانید بعد از هر دستور آنرا از بین ببرید. مدیر Heap جزئیات را برای شما نگهداری می کند. بنابراین شما به سادگی می توانید یک حافظه جدید را با GetMem و یا بوسیله صدا زدن constructor هنگام ساختن یک شی درخواست کنید و دلفی به شما یک بلاک جدید را برخواهد گرداند. Heap یکی از سه فضای موجود در برنامه کاربردی را استفاده کرده و دوتای دیگر به صورت فضای یکپارچه (Global) و پشته قرار می گیرند.
حافظه Stack:
Stack شامل قسمتی از یک بخش از حافظه موجود یک برنامه است که دینامیکی است اما برای تخصیص و آزادسازی فرامین مخصوص دارد. تخصیص Stack به صورت LIFO می باشد. این بدان معناست که آخرین حافظه شیء شما تخصیص داه خواهد شد و سپس حذف می شود. حافظه پشته در روتینهای نوعی استفاده میشود. وقتی شما یک روتین را صدا میزنید، پارامترهایش و روتین نوع آن در پشته ریخته می شود. همچنین پارامترهایی که در یک روتین تعریف میشوند، در پشته ذخیره میشوند و وقتی روتین خاتمه پیدا می کند تمام آنها به طور خودکار از بین می رود.
بررسی رکوردها در دلفی:
یک ساختار تعریف شده در پاسکال موضوعی تحت عنوان record میباشد. رکوردها را میتوان یک نوع داده که خود شامل چندین نوع داده دیگر است در نظر گرفت. برای تعریف رکوردها بصورت زیر عمل میکنیم:
type recordTypeName = record
fieldList1: type1;
...
fieldListn: typen;
end
پس از اینکه نوع رکورد ایجاد شد، باید متغییرهایی از نوع این رکورد تعریف واز آنها استفاده کرد. برای تعریف متغییر نوع رکورد به صورت زیر عمل میشود:
type
TDateRec = record
Year: Integer;
Month: (Jan, Feb, Mar, Apr, May, Jun,
Jul, Aug, Sep, Oct, Nov, Dec);
Day: 1..31;
end;
var
Record1, Record2: TDateRec;
هنگام کار با یک رکورد برای دستیابی به میدانهای آن، از نماد نقطه استفاده میکنیم:
Record1.Year := 1904;
Record1.Month := Jun;
Record1.Day := 16;
همچنین میتوان یک رکورد را در یک رکورد دیگر کپی کرد بدون اینکه با خطائی مواجه شویم. شما همچنین میتوانید متغییرهای از نوع رکوردهای خود را به صورت مستقیم تعریف کنید:
var S: record
Name: string;
Age: Integer;
end;
رکوردهای با طول متغییر:
نوع رکورد را میتوان طوری تعریف کرد که طول بخشی از آن ثابت و طول بخش دیگری بر اساس شرایط فیلدها متغییر باشد. در زیر یک مثال و در ادامه آن جدولی از حافظهای که اشغال میشود آورده شده است.
type
TPartType = (ptComputer, ptMonitor, ptComponent);
TPart = record
PartNumber : String[15];
Description : String[30];
Price : Double;
case PartType : TPartType of
ptComputer: (CPU : String[10]; Speed : String[10]; HardDrive : String[10]);
ptMonitor: (VideoType : String[10]; Size : String[5]; DotPitch : String[5]);
ptComponent: (Internal : Boolean; Specs : String[29]);
end;
این تعریف به کامپایلر می گویید که تنها یکی از متغییرهای مجموعه case را برای استفاده در هر رکوردی انتخاب کند. این یک راهکار بسیار خوب برای استفاده از حافظه می باشد؛ زیرا حافظه یکسانی برای هر مجموعهای از متغییرها در نظر گرفته میشود.
نام متغییر نام متغییر نام متغییر بایت
PartNumber 0
Description 15
Price 45
PartType 53
Internal VideoType CPU 54
Specs 55
Size Speed 64
DotPitch 69
HardDrive 74
دسترسی به یک بایت:
بعضی مواقع، هنگامیکه با یک API خارجی کار میکنید، احتیاج دارید که اطلاعاتی از نوع Word یا Longint را به نوعهای دلخواه ب######ید. به عنوان مثال TMSF را بصورت زیر در نظر بگیرید:
Least Significant Byte Most Significant Byte
Minute Seconds Frames Unused
ساختار TMSFRec رو بصورت زیر تعریف میکنیم:
type
TMSFRec = record
Minutes : Byte;
Seconds : Byte;
Frames : Byte;
Dummy : Byte;
end;
در این حالت ما میتوانیم به راحتی به هر یک از بایتهای نوع Longint دسترسی داشته باشیم:
begin
MinuteLbl.Caption := IntToStr(TMSFRec(Position).Minutes);
SecondLbl.Caption := IntToStr(TMSFRec(Position).Seconds);
FrameLbl.Caption := IntToStr(TMSFRec(Position).Frames);
end;
در مثال قبل، Position متغییری از نوع Longint میباشد.
آرایهها در دلفی:
دلفی به ما امکان می دهد آرایههایی از هر نوع متغییری را ایجاد کنیم. برای تعریف آرایه به صورت زیر عمل میکنیم:
var
array[indexType1, ..., indexTypen] of baseType;
در این تعریف برای نامگذاری آرایه، از قانون نامگذاری متغییرها استفاده میکنیم و مقدار اولیه را نیز درون یک جفت کروشه قرار می دهیم.
نکته: شما می توانید به جای استفاده از کروشه [] از ترکیب پرانتز نقطه استفاده کنید:
d(.i.):= 3 + i; // Equivalent d[i]:= 3 + i;
نکته: وقتی که شما یک آرایه را تعریف می کنید احتیاجی ندارید که به آن مقدار کمترین یا بیشترین بدهید:
var
A : array [Boolean] of integer;
begin
A[True] := 50;
A[False] := 100;
end;
نکته: توابع Low و High کرانهای پایین وبالای یک متغییر آرایهای یا نوعی یا ترتیبی را بر میگردانند:
for I := 0 to High(X) do S := S + X[I];
آرایههای ثابت:
آرایه های ثابت می توانند توسط ساختار ثابت نوع دلفی تعریف شود. نوع ثابت که همیشه با عبارت Const تعریف می شود، نه تنها مانع تغییر مقدار پارامتر می شود، بلکه کدهای بهینه بیشتری برای رشتهها و رکوردهای رد شده به توابع تولید می کند. ما هنگامی از این نوع استفاده می کنیم که نخواهیم مقدار رد شده به یک تابع تغییر کند.
type
TDay = (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday);
const
DayNames : array [TDay] of String[9] = ('Sunday', 'Monday', 'Tuesday',
'Wednesday', 'Thursday',
'Friday', 'Saturday');
var
Today : TDay;
begin
Today := TDay(DayOfWeek(Date) - 1);
ShowMessage('Today is ' + DayNames[Today] + '!');
end;
آرایههای دینامیکی:
آرایههای دینامیکی، آرایههای تحلیلی پویایی هستند که ابعاد آنها موقع کامپایل شدن شناخته شده نیست. برای اعلان آنها کافی است یک آرایه بدون بعد تعریف کنید:
var MyFlexibleArray: array of Real;
قبل از به کار گیری آرایههای دینامیکی، ابتدا باید از رویه SetLength برای تخصیص حافظه آرایه استفاده کرد:
SetLength (MyFlexibleArray, 2);
نکته: آرایههای دینامیکی همیشه مبتنی بر صفر می باشند.
نکته: شما میتوانید آرایههای دینامیکی را قبل از رسیدن به ترک قلمرو از حافظه خارج کنید:
MyFlexibleArray := nil;
نکته: مقدار حافظهای که در اختیار آرایه قرار میگیرد، به طول آرایه ونوع عناصر آن بستگی دارد. به عنوان مثال اگر آرایهای از نوع صحیح به طول 10 داشته باشیم 4*10 بایت حافظه به آن اختصاص مییابد.
فشردهسازی آرایهها:
در دلفی شما هنگامی که ساختار خود را تعیین کردید میتوانید با استفاده از کلمه کلیدی packed اطلاعات ذخیره شده خود را متراکم کنید:
type TNumbers = packed array[1..100] of Real;
نکته: استفاده از packed سرعت دسترسی به اطلاعات را کند میکند. در مورد آرایهای از کاراکترها این مورد سازگارتر میباشد.
آرایههای چند بعدی دینامیکی:
برای تعریف آرایههای چند بعدی دینامیکی، تنها کافی است ...array of را در ساختار خود تکرار کنید. به طور مثال:
type
TMessageGrid = array of array of string;
var
Msgs: TMessageGrid;
این تعریف یک آرایه دو بعدی از رشتهها می باشد. سپس باید به آرایه خود فضا نسبت داد:
SetLength(Msgs, I, J);
شما میتوانید آرایههای چند بعدی دینامیکی خود را به صورت غیر مستطیلی (Not Rectangular) ایجاد کنید. ابتدا رویه SetLength را صدا زده و پارامتر بعد اول را بدهید:
var
Ints: array of array of Integer;
SetLength(Ints, 10);
ما 10 سطر به آرایه خود اختصاص دادیم. از این پس، شما می توانید ستونهای خود را در هر زمان (با اندازههای مختلف) تخصیص دهید:
SetLength(Ints[2], 5);
تغییر Hint برای هر ستون از DBGrid در دلفی:
در DBGrid كار كردن بر روی هر سلول كاری مشكل و پردرد سر است چون انعطاف TGrid را ندارد. در این متن سعی کردهام شما را با راه حل این مشکل آشنا كنم.
ابتدا باید یک عنصر جدید مبتنی بر TDBGrid ایجاد کنید و رویداد OnMouseMove را فراخوانی کنید:
type
TMyDBGrid = class(TDBGrid)
published
property OnMouseMove;
end;
اگرچه شما در رویداد OnMouseMove مختصات X و Y را بدست خواهید آورد، اما شما باید ستون مورد نظر را پیدا کنید. برای ادامه کار لازم است که سطر زیر را در قسمت protected قرار دهید:
procedure WMMouseMove(var Message : TWMMouse); message WM_MOUSEMOVE;
همچنین متغیر های زیر را در قسمت public اضافه نمایید:
MouseRow : integer;
MouseCol : integer;
بنابراین متد WMMouseMove بصورت ریر خواهد بود:
procedure TMyDBGrid.WMMouseMove(var Message : TWMMouse);
var
t : TGridCoord;
begin
t := MouseCoord(Message.XPos, Message.YPos);
MouseCol := t.x;
MouseRow := t.y;
inherited;
end;
ما ابتدا فیلدهای XPost و YPos را از ساختار WMMouseMove تنظیم میکنیم:
procedure TForm2.MyDBGrid1MouseMove(Sender: TObject; Shift: TShiftState; X, Y:
Integer);
begin
if (((dgIndicator in MyDBGrid1.Options) and (MyDBGrid1.MouseCol > 0)) or
((not (dgIndicator in MyDBGrid1.Options)) and (MyDBGrid1.MouseCol <> -1)))
and (MyDBGrid1.MouseCol <> OldMouseCol) then begin
OldMouseCol := MyDBGrid1.MouseCol;
if dgIndicator in MyDBGrid1.Options then
MYDBGrid1.Hint := MyDBGrid1.Columns[MyDBGrid1.MouseCol - 1].FieldName
else
MYDBGrid1.Hint := MyDBGrid1.Columns[MyDBGrid1.MouseCol].FieldName;
end;
end;
حالا مجددا" تعریف زیر را در قسمت public قرار دهید:
HintMouseMessage(Control : TControl; var Message : TMessage)
در قسمت OnMouseMove از TDBGrid نیز فرامین زیر را اضافه نمایید:
var
r : TMessage;
begin
Application.HintMouseMessage(self, r);
TWMMouse(r).XPos := X;
TWMMouse(r).YPos := Y;
Application.HintMouseMessage(MyDBGrid1, r);
end;
همه کارها انجام شد. حالا شما میتوانید نتیجه را مشاهده کنید.
نكات مفید كار در محیط دلفی:
محیط دلفی برای برنامه نویسی یکی از بهترین محیطهای برنامه نویسی است گذشته از کارکرد داخلی و کمپایلر آن که بسیار قوی و سریع است، محیط آن یعنی IDE آنهم قدرت بسیار زیادی دارد که باعث شده یکی از بهترین ادیتورها باشد. در این مقاله من سعی بر این داشته ام تا با ارائه یک سری از نکات و کلیدهای میانبر که می توانند برای کار در دلفی بسیار مفید و کارا باشند، کمک کنم تا شما بتوانید با قدرت بیشتر به برنامه نویسی و کار در این محیط قدرتمند ادامه دهید.
در قسمت اول مقاله که در حال حاضر در مقابل شماست من یک سری از کلیدهای میانبر و ترکیبی مورد استفاده در IDE دلفی را بصورت لیست وار و همراه یک توضیح کوچک آورده ام. دوستان عزیز برنامه نویس ممکنه که شما مدتها با دلفی مشغول برنامه نویسی بوده باشید اما من یقین دارم که در این لیست نکات و روشهای جدیدی را خواهید آموخت.
جستجو در متن بصورت مستقیم:
برای اینکار کلیدهای 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 را بزنید. در اینحالت اگر روی کد تابع باشید به قسمت تعریف آن خواهید رفت.
دلفی و اسمبلی:
برنامه نويسان دوران DOS با tasm.exe و tlink.exe آشنايي دارند.ايندو از ديرباز رقيبان masm.exe و link.exe بوده و هستند.بله tasm و برادركوچكش tlink از اولين ابزارهاي برنامه نويسان حرفه اي هستند.اما بعد از ظهور Turbo Pascal ، Turbo C/C++ و متعاقبا كامپايلر هاي تحت ويندوز ، كم كم محبوبيت خود را از دست دادند.هم اكنون كمتر صحبتي در مورد اين افسانه هاي قديمي پردازنده هاي x86 ميشود.
آيا اين نشانه مرگ tasm است؟
آيا ميدانيد هر بار كه Delphi يا C++Builder را نصب ميكنيد ، نمونه 32 بيتي اين اسمبلر باوفا نيز ميهمان ديسك سخت شما ميشود؟
آيا ميدانيد مهمترين بخشهاي VCL توسط اسمبلي و tasm32.exe نوشته شده است؟
آيا مي خواهيد روش استفاده از tasm در Delphi را ياد بگيريد؟
اگر جواب شما به سوال آخر بله است ، با من همراه شويد تا يك برنامه كاملا ابتدايي و آموزشي با تركيب قدرت tasm و Delphi بسازيم.اگر جواب شما به سوال آخر خير است لطفا موس خود را به سمت گوشه بالا و راست اين پنجره برده و روي آن دكمه ضربدري شكل كليك كنيد!
چه كساني ميتوانند از اين مقاله استفاده كنند؟
قبل از هر چيز خواننده بايد با دستورات اسمبلي آشنا باشد.با يك جستجوي ساده در اينترنت ميتوانيد به مقالات آموزشي زيادي دسترسي پيدا كنيد.
آشنايي با نحوه پياده سازي ويندوز نيز كمك زيادي بشما خواهد كرد اما براي استفاده اين مقاله لازم نيست.در اين مورد، شايد مقاله ديگر من بنام "اسمبلي تحت ويندوز" بتواند بشما كمك كند.
برنامه اي كه خواهيم ساخت كار بسيار ساده اي انجام ميدهد.
اين برنامه يك Message box را نمايش داده كه داراي دو كليد OK و Cancel است.هر كدام از اين كليد ها كه click شوند توسط يك Message box ديگر به كاربر گزارش داده ميشود.
براي شروع يك فايل با پسوند dpr ساخته و كد زير را در آن كپي كنيد:
program DelphiAsm;
uses windows;
var
Title :PChar = 'Inline assembly with Reza'#0;//bar hasbeh adat!!
Mes1 : PChar = 'Please press one of the following buttons!!'#0;
Mes2 : PChar = 'You pressed OK button!!'#0;
Mes3 : PChar = 'You pressed Cancel button!!'#0;
label
PRINTPROC;
begin
asm
push 1
push Title
push Mes1
push 0
call MessageBoxA
cmp eax , IDOK
je PRINTPROC
push Mes3
pop Mes2
PRINTPROC:
push 0
push Title
push Mes2
push 0
call MessageBoxA
mov eax,0
call ExitProcess
end;
end.
نكته:در دلفي براي نوشتن دستورات اسمبلي از بلوك asm … end; استفاده ميشود.
قبل از هر چيز به نحوه تعريف يك ليبل توسط كلمه كليديمLabel توجه كنيد.چه در tasm و چه در masm احتياجي به اعلان كردن ليبل ها نداريد ولي از آنجايي كه Delphi يك كامپايلر است و قوانين خواص خود را دارد ، قبل از استفاده از هر ليبل بايد آنرا اعلان كنيد.
نكته: دوم مسئله calling convention است.بايد بدانيد كه Delphi از روش Fastcall براي فراخواني توابع خود استفاده ميكند ولي windows از روش stdcall بهره ميبرد.
Stdcall يعني آرگومانها را از چپ به راست در پشته قرار مي گيرند و callee )فراخوانده) مسئول pop كردن آرگومانها است.(براي اطلاعات بيشتر در مورد انواع calling convention ها به MSDN يا مقاله ديگر من بنام "اسمبلي تحت ويندوز" مراجعه كنيد.(
براي يافتن Prototype اولين تابع مورد استفاده نگاهي به MSDN بيندازيد و تابع MessageBox و نه MessageBoxA يا( MessageBoxW) را search كنيد :
int MessageBox(
HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption, // message box title
UINT uType // message box style
);
اكنون ميدانيد كه
1.Prototypeتابع MessageBox چيست.
2.calling conventionاستاندارد يا stdcall چگونه عمل ميكند.
پس دست بكار شده و آرگومانها را از چپ به راست در stack بچپانيد!! سپس تابع MessageBox را فراخواني كنيد.
همانطور كه در Prototype تابع MessageBox ميبينيد مقدار بازگشتي آن يك Integer است كه نشان دهده دكمه كليك شده در Message box است.
نكته مهم:
توابع stdcall مقدار بازگشتي خود را در eax قرار ميدهند.
آقا يادم رفت بگم ، اسامي چون IDOK, IDCANCEL, MessageBox و... در يونيت windows اعلان شده اند.
پس تا اينجا موفق شديم يك MessageBox با متن
Please press one of the following buttons!! نمايش دهيم .بر اساس مقدار بازگشتي اين تابع تشخيص ميدهيم كه كدام دكمه(button) كليك شده است و با يك جابجايي ساده و بدون توليد كد اضافي پيام مناسب را توسط يك Message box ديگر به كاربر نمايش ميدهيم.حتما ميدانيد كه متغييري از نوع رشته در ويندوز ، يك اشاره گر به اولين كاراكتر آن رشته است.(علت اين است كه windows بوسيله زبان C پياده سازي شده است).
در انتها نيز با فراخواني ExitProcess تمامي thread هاي فعال (كه در اين برنامه يكي بيشتر نيست!!) بسته ميشوند ، هر چند كه انجام اين كار ضروري نيست، دلفي كد لازم را توليد خواهد كرد.مي توانيد دو خط آخر را حذف كنيد و نتيجه كار را ببينيد.
در اين برنامه براي ساده كردن كار از VCL كه نقطه عطف Delphi است استفاده نكرديم اما شما ميتوانيد در برنامه هاي عادي خود VCL و اسمبلي را باهم بكار گرفته و برنامه هايي با بازدهي بسيار بالا بسازيد.از حالا به بعد اگر شنيديد كه :"آره بابا با دلفي نميشه فلان كارو انجام داد ، بايد با اسمبلي كد بنويسي" ميدانيد چه جوابي بدهيد.
کد گذاری اطلاعات متنی به روش encrypt در دلفی:
يكي از روشهاي جالب براي ساختن فايلهاي نوشتاري كه در كنار برنامه
قرار مي گيرند و در برنامه از آنها استفاده مي شود روش Encrypt مي باشد.
توسط اين روش ، شما نوشته هاي خود را به صورت كدگذاري شده در فايل ضبط مي كنيد تا ديگران نتوانند از نوشته هاي شما كه به صورت يك فايل آماده در كنار برنامه شما است استفاده كنند. اگر كاربري اين فايل را ببيند چيزي از آن متوجه نمي شود و از خير استفاده از آن مي گذرد.
شما مي توانيد با روش برعكس Decrypt آن نوشته هاي كد گذاري شده را به حالت اوليه خود يعني نوشته هاي معمولي بازگردانيد و در برنامه خود استفاده نماييد.
اين روش در بسياري از موارد ، مانند گرافيك ، بانكهاي داده اي و ... استفاده بسيار زيادي دارد. توسط اين روش ديگر نگران دزديده شدن اطلاعات خود نيستيد و با خيالي راحت فايلهاي خود را در كنار برنامه تان منتشر مي كنيد.
حال بياييد از نظر تئوري اين عمل را بررسي كنيم.
در رياضيات عملي به نام تبديل وجود دارد. به طور مثال فرض كنيد ما يك عدد داريم (5) حال مي خواهيم با استفاده از تبديلات آن را Encrypt كنيم.
اگر من اين عدد را با 2 جمع كنم ، سپس ضربدر 4 كنم ، بعد تقسيم بر 2
و سپس منهاي 1 كنم ، عدد 13 حاصل مي شود.
حال اگر عمل برعكس را انجام دهم ، يعني عددي كه در حال حاضر دارم
) كه عدد 13 مي باشد ( را به علاوه 1 ، سپس ضربدر 2 ، تقسيم بر 4 و
منهاي 2 كنم عدد اوليه من يعني 5 به دست خواهد آمد.
به اين روش تبديل و برعكس آن Encrypt و Decrypt مي گويند.
خوب شايد بگوييد چرا از ابتدا عدد 5 را به علاوه 8 نكردم تا عدد 13 به دست بيايد ؟ اين تنها يك مثال ساده بود تا شما متوجه بشيد كه چگونه رشته ها به صورت كدگذاري شده در مي آيند.
حال بياييد همين روش را با رشته ها تكرار كنيم.
به طور مثال من كلمه Test را دارم. حال كاراكتر اوليه آن را از نظر مقدار دهي كاراكترها 2 كاراكتر به جلو مي برم كه مي شود.
سپس كاراكتر بعدي يا e را به همين روش 3 كاراكتر به عقب مي برم كه
مي شود b. به همين روش باقي كاراكترها را تغيير مي دهم.
به طور مثال نتيجه حاصل شده به اين صورت است :
Test -> Venh
توجه كنيد كه رشته جديد بدست آمده هيچگونه ارتباطي با رشته اوليه آن
ندارد و هيچ كاربري نمي تواند بدون داشتن جزئيات تغييرات ، آن را به كاراكتر اوليه بازگرداند.
حال اگر محاسبات تغيير را بسيار پيچيده كنيم ، ديگر پيدا كردن رشته اوليه بسيار مشكل مي شود و هيچ كاربري نمي تواند آن را پيدا كند.
در برنامه به صورت برعكس عمل مي كنيم ، يعني كاراكتر اول را 2 عدد به
عقب بازمي گردانيم ، دومي را 3 كاراكتر به جلو مي بريم و ...
كه نتيجه مي شود :
Venh -> Test
اين از نظر تئوري ، اما بياييد در عمل كدنويسي دلفي آن را ببينيم :
function Encrypt(Text : string; Key1, Key2, Key3, Key4 : Integer) : string;
var
BufS, Hexa, Hexa1, Hexa2 : string;
BufI, BufI2, Sc, Sl, Num1, Num2, Num3, Num4, Res1, Res2, Res3, Res4 : Integer;
begin
Sl := Length(Text);
Sc := 0;
BufS := '';
if (Key1 in [1 .. 120]) and (Key2 in [1 .. 120]) and (Key3 in [1 .. 120]) and (Key4 in [1 .. 120]) then
begin
BufI := Key1 * Key4;
BufI2 := Key3 * Key2;
BufI := BufI - BufI2;
if BufI = 0 then
begin
Result := '';
Exit;
end;
end
else
begin
Result := '';
Exit;
end;
repeat
Inc(Sc);
if Sc > Sl then Num1 := 0 else Num1 := Ord(Text[Sc]);
Inc(Sc);
if Sc > Sl then Num2 := 0 else Num2 := Ord(Text[Sc]);
Inc(Sc);
if Sc > Sl then Num3 := 0 else Num3 := Ord(Text[Sc]);
Inc(sc);
if Sc > Sl then Num4 := 0 else Num4 := Ord(Text[Sc]);
Res1 := Num1 * Key1;
BufI := Num2 * Key3;
Res1 := Res1 + BufI;
Res2 := Num1 * Key2;
BufI := Num2 * Key4;
Res2 := Res2 + BufI;
Res3 := Num3 * Key1;
BufI := Num4 * Key3;
Res3 := Res3 + BufI;
Res4 := Num3 * Key2;
BufI := Num4 * Key4;
Res4 := Res4 + BufI;
for BufI := 1 to 4 do
begin
case BufI of
1 : Hexa := IntToHex(Res1, 4);
2 : Hexa := IntToHex(Res2, 4);
3 : Hexa := IntToHex(Res3, 4);
4 : Hexa := IntToHex(Res4, 4);
end;
Hexa1 := '$' + Hexa[1] + Hexa[2];
Hexa2 := '$' + Hexa[3] + Hexa[4];
if (Hexa1 = '$00') and (Hexa2 = '$00') then
begin
Hexa1 := '$FF';
Hexa2 := '$FF';
end;
if Hexa1 = '$00' then Hexa1 := '$FE';
if Hexa2 = '$00' then
begin
Hexa2 := Hexa1;
Hexa1 := '$FD';
end;
BufS := BufS + Chr(StrToInt(Hexa1)) + Chr(StrToInt(Hexa2));
end;
until Sc >= Sl;
Result := BufS;
end;
همان طور كه مشاهده مي فرماييد ما با استفاده از يك Function يك رشته را گرفته ، سپس متناسب با اعداد انتخابي داده شده ، كه همان عامل تغييرات مي باشند ، رشته جديد به صورت كدگذاري شده مي سازيم.
حال به اين كد نگاهي بياندازيد :
function Decrypt(Text : string; Key1, Key2, Key3, Key4 : Integer) : string;
var
BufS, Hexa1, Hexa2 : string;
BufI, BufI2, Divzr, Sc, Sl, Num1, Num2, Num3, Num4, Res1, Res2, Res3, Res4 : Integer;
begin
Sl := Length(Text);
Sc := 0;
BufS := '';
if (Key1 in [1 .. 120]) and (Key2 in [1 .. 120]) and (Key3 in [1 .. 120]) and (Key4 in [1 .. 120]) then
begin
Divzr := Key1 * Key4;
BufI2 := Key3 * Key2;
Divzr := Divzr - BufI2;
if Divzr = 0 then
begin
Result := '';
Exit;
end;
end
else
begin
Result := '';
Exit;
end;
repeat
for BufI := 1 to 4 do
begin
Inc(Sc);
Hexa1 := IntToHex(Ord(Text[Sc]), 2);
Inc(Sc);
Hexa2 := IntToHex(Ord(Text[Sc]), 2);
if Hexa1 = 'FF' then
begin
Hexa1 := '00';
Hexa2 := '00';
end;
if Hexa1 = 'FE' then Hexa1 := '00';
if Hexa1 = 'FD' then
begin
Hexa1 := Hexa2;
Hexa2 := '00';
end;
case BufI of
1 : Res1 := StrToInt('$' + Hexa1 + Hexa2);
2 : Res2 := StrToInt('$' + Hexa1 + Hexa2);
3 : Res3 := StrToInt('$' + Hexa1 + Hexa2);
4 : Res4 := StrToInt('$' + Hexa1 + Hexa2);
end;
end;
BufI := Res1 * Key4;
BufI2 := Res2 * Key3;
Num1 := BufI - BufI2;
Num1 := Num1 div Divzr;
BufI := Res2 * Key1;
BufI2 := Res1 * Key2;
Num2 := BufI - BufI2;
Num2 := Num2 div Divzr;
BufI := Res3 * Key4;
BufI2 := Res4 * Key3;
Num3 := BufI - BufI2;
Num3 := Num3 div Divzr;
BufI := Res4 * Key1;
BufI2 := Res3 * Key2;
Num4 := BufI - BufI2;
Num4 := Num4 div Divzr;
BufS := BufS + Chr(Num1) + Chr(Num2) + Chr(Num3) + Chr(Num4);
until Sc >= Sl;
Result := BufS;
end;
در اينجا هم عمل برعكس را انجام داده ايم ، يعني رشته كدشده را به حالت اوليه خود بازگردانديم.
توجه كنيد كه اعداد انتخابي براي كد گذاري ، كه همان Key1, Key2, Key3, Key4مي باشند ، كاملاْ به صورت انتخابي و مي بايست بين دو عدد 1 تا 120 انتخاب شوند ، در غير اين صورت نتيجه درست حاصل نمي شود.
با اين روش مي توانيد اطلاعات متني خود را ، به خصوص در بانكهاي داده اي به صورت كدگذاري شده تبديل نماييد. در اين صورت با خيالي آسوده مي توانيد بانك خود را بدون هيچگونه كلمه رمز در كنار برنامه خود منتشر كنيد.
نکات ریز و درشت در دلفی:
چگونه تمامي رويدادهاي يك شيء را در زمان اجرا به Nil تنظيم كنيم؟
در اين مقاله روشي را جهت اينكه تمامي رويدادهاي يك شيء تعريف شده در دلفي را در زمان اجرا به Nil تنظيم كنيد براي شما بازگو ميكنيم. شما ميتوانيد از RTTIها جهت رسيدن به اهداف خود استفاده كنيد اما فقط براي زمان طراحي و اجرا و اين امكان براي رويدادها وجود ندارد. استفاده از RTTI، تا حدودي پيچيده است بنابراين من رويهاي را براي نسبت دادن Nil به يك شيء موجود در زمان اجراي يك برنامه در دلفي آوردهام كه نحوه انجام اين كار را به شما نشان ميدهد.
unit uNilEvent;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{Private declarations}
public
{Public declarations}
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
uses
Typlnfo;
procedure NilEvents(lnstance: TObject);
var
Typelnfo: PTypelnfo;
I, Count: Integer;
PropList: PPropList;
Proplnfo: PProplnfo;
Method: TMethod;
begin
Typelnfo := Instance.Classlnfo;
Method.Code := nil;
Method.Data := nil;
Count := GetPropList(Typelnfo, [tkMethod], nil);
GetMem(PropList, Count * SizeOf(Pointer));
try
GetPropList(Typelnfo, [tkMethod], PropList);
for I := 0 to Count -1 do
begin
Proplnfo := PropList^[I];
SetMethodProp(lnstance, Proplnfo, Method);
end;
finally
FreeMem(PropList);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
const
sText = 'The 2nd time you click Button1 the event will not fire';
begin
NilEvents(Button1);
ShowMessage(sText);
end;
end.
چگونه رويداد مربوط به تمامي اجزاء درون برنامه خود را تغيير دهيم؟
گاهي لازم ميشود تا ما فراميني را براي يكي از رويدادهاي برنامه خود به تمامي اشياء استفاده شده در برنامه نسبت دهيم اينكار ميتواند با استفاده از RTTI دلفي صورت گيرد شما مثالي را ميبينيد كه اين كار را شبيهسازي كرده است.
uses
Typlnfo;
procedure TFrmRTTIOnChange.Button1Click(Sender: TObject);
var
proplnfo: PProplnfo;
thisEvent: TNotifyEvent;
begin
proplnfo := GetProplnfo(Memo1.Classlnfo, 'OnChange');
if proplnfo <> nil then
begin
thisEvent := Memo1AltChange;
SetOrdProp(Memo1, Proplnfo, integer(@thisEvent));
end;
end;
procedure TFrmRTTIOnChange.Memo1Change(Sender: TObject);
begin
Caption := 'Normal On Change';
end;
procedure TFrmRTTIOnChange.Memo1AltChange(Sender: TObject);
begin
Caption := 'Alternate On Change';
end;
دلفی و asp_net
پس از مطالعه اين متن خواهيد آموخت چگونه از دلفي براي توليد صفحات ديناميك وب مبتني بر تكنولوژي ASP.NET مايكروسافت استفاده كنيد .
مرحله اول : قبل از هركار بايد سيستم ASP.NET را از وجود دلفي به عنوان يكي از زبانهاي اسكريپت نگاري تحت NET. مطلع سازيد .
ASP.NET براي اجراي برنامه ها به دنبال فايلي با نام web.config خواهد گشت كه جزئيات زبانهاي مورد استفاده سيستم در آن ثبت شده است . اين فايل XML-Based بايد براي معرفي دلفي به سيستم تغيير كند .
كد زير نمونه خامي از اين نوع فايل را نمايش ميدهد :
كد:
<configuration>
<configSections>
<section name="appSettings"
type="System.Configuration.NameValueFileSectionHan dler,
System, Version=1.0.3300.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<section name="sessionState"
type="System.Web.SessionState.SessionStateSectionH andler,
System.Web, Version=1.0.3300.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
allowDefinition="MachineToApplication" />
</configSections>
<appSettings>
<add key="dsn" value="localhost;uid=MyUserName;pwd=;" />
<add key="msmqserver" value="server\myqueue" />
</appSettings>
<sessionState cookieless="true" timeout="10" />
</configuration>
فايل مورد نظر براي سازگاري با دلفي بايد به اين شكل باشد :
كد:
<configuration>
<system.web>
<compilation debug="true">
<assemblies>
<add assembly="DelphiProvider" />
</assemblies>
<compilers>
<compiler language="Delphi" extension=".pas"
type="Borland.Delphi.DelphiCodeProvider,DelphiProv ider" />
</compilers>
</compilation>
</system.web>
</configuration>
فايل مورد نظر بايد در دايركتوري مجازي معرفي شده براي وب سرور كه محل قرار گرفتن برنامه هاي ASP.NET ساخته شده با دلفي است قرار بگيرد . براي اين مقصود به وب سرور خود دايركتوري مجازي ديگري معرفي كرده و فايل فوق الذكر را آنجا قرار دهيد .
مرحله دوم : در محيط ويژوال استوديو ( .. والبته اگر تمايل داريد) Notepad !!!!! پروژه وب جديدي باز كنيد و يك تكست باكس - يك كليد - يك ليبل روي فرم خود قرار داده و تابع click را به رويداد OnClick كليد فشاري نسبت دهيد . نام تكست باكس را اديت وان و نام ليبل را مسج بگذاريد . فايل حاصل را بصورت زير ويرايش كنيد :
كد:
<html>
<script language="Delphi" runat="server">
procedure Click(Sender: System.Object; E: EventArgs);
begin
Message.Text := Edit1.Text;
end;
</script>
<body>
<form runat="server">
<asp:textbox id="Edit1" runat="server"/>
<asp:button text="Click Me!" OnClick="Click" runat="server"/>
</form>
<p><b><asp:label id="Message" runat="server"/></b></p>
</body>
</html>
فايل را با نام Test.AspX ذخيره كرده و اجرا كنيد . ( براي اجرا كرده برنامه هاي ASP.NET بايد IIS و NET. Run Times را قبلا نصب و تنظيم كرده باشيد !
...فقط اعضای سایت میتوانند لینک ها را ببینند ! برای ثبت نام کلیک کنید
)
مجموعه كامپايلر دلفي و ASP.NET كد زير را توليد و كامپايل (!) ميكنند :
كد:
unit ASP;
interface
uses System.Collections, System.Collections.Specialized, System.Configuration,
System.Text, System.Text.RegularExpressions, System.Web, System.Web.Caching,
System.Web.SessionState, System.Web.Security, System.Web.UI, System.Web.UI.WebControls,
System.Web.UI.HtmlControls, System.Globalization;
var
editdemo_aspx___autoHandlers: Integer;
editdemo_aspx___intialized: Boolean = False;
editdemo_aspx___fileDependencies: System.Collections.ArrayList;
type
editdemo_aspx = class(System.Web.UI.Page, System.Web.SessionState.IRequiresSessionState)
protected
Edit1: System.Web.UI.WebControls.TextBox;
__control3: System.Web.UI.WebControls.Button;
__control2: System.Web.UI.HtmlControls.HtmlForm;
Message: System.Web.UI.WebControls.Label;
procedure ButtonClick(Sender: System.Object; E: EventArgs);
public
constructor Create;
function get_AutoHandlers: Integer; override;
function get_ApplicationInstance: System.Web.HttpApplication; virtual;
function get_TemplateSourceDirectory: System.String; override;
procedure set_AutoHandlers(Value: Integer); override;
protected
property AutoHandlers: Integer read get_AutoHandlers write set_AutoHandlers;
property ApplicationInstance: System.Web.HttpApplication read get_ApplicationInstance;
public
property TemplateSourceDirectory: System.String read get_TemplateSourceDirectory;
private
function __BuildControlEdit1: System.Web.UI.Control;
function __BuildControl__control3: System.Web.UI.Control;
function __BuildControl__control2: System.Web.UI.Control;
function __BuildControlMessage: System.Web.UI.Control;
procedure __BuildControlTree(__ctrl: System.Web.UI.Control);
protected
procedure FrameworkInitialize; override;
public
function GetTypeHashCode: Integer; override;
end;
implementation
procedure editdemo_aspx.ButtonClick(Sender: System.Object; E: EventArgs);
begin
Message.Text := Edit1.Text;
end;
constructor editdemo_aspx.Create;
var
dependencies: System.Collections.ArrayList;
begin
inherited Create;
if (ASP.editdemo_aspx___intialized = False) then
begin
dependencies := System.Collections.ArrayList.Create;
dependencies.Add('d:\vslive\editdemo.aspx');
ASP.editdemo_aspx___fileDependencies := dependencies;
ASP.editdemo_aspx___intialized := True;
end;
Self.Server.ScriptTimeout := 30000000;
end;
function editdemo_aspx.get_AutoHandlers: Integer;
begin
Result := ASP.editdemo_aspx___autoHandlers;
end;
function editdemo_aspx.get_ApplicationInstance: System.Web.HttpApplication;
begin
Result := Self.Context.ApplicationInstance as System.Web.HttpApplication;
end;
function editdemo_aspx.get_TemplateSourceDirectory: System.String;
begin
Result := '/vslive';
end;
procedure editdemo_aspx.set_AutoHandlers(Value: Integer);
begin
ASP.editdemo_aspx___autoHandlers := Value;
end;
function editdemo_aspx.__BuildControlEdit1: System.Web.UI.Control;
var
__ctrl: System.Web.UI.WebControls.TextBox;
begin
__ctrl := System.Web.UI.WebControls.TextBox.Create;
Self.Edit1 := __ctrl;
__ctrl.ID := 'Edit1';
__ctrl.Width := System.Web.UI.WebControls.Unit.Parse('300px', System.Globalization.CultureInfo.InvariantCulture) ;
Result := __ctrl;
end;
function editdemo_aspx.__BuildControl__control3: System.Web.UI.Control;
var
__ctrl: System.Web.UI.WebControls.Button;
begin
__ctrl := System.Web.UI.WebControls.Button.Create;
Self.__control3 := __ctrl;
__ctrl.Text := 'Click Me!';
__ctrl.add_Click(Self.ButtonClick);
Result := __ctrl;
end;
function editdemo_aspx.__BuildControl__control2: System.Web.UI.Control;
var
__parser: System.Web.UI.IParserAccessor;
__ctrl: System.Web.UI.HtmlControls.HtmlForm;
begin
__ctrl := System.Web.UI.HtmlControls.HtmlForm.Create;
Self.__control2 := __ctrl;
__parser := __ctrl as System.Web.UI.IParserAccessor;
__parser.AddParsedSubObject(System.Web.UI.LiteralC ontrol.Create(''#13#10' '));
Self.__BuildControlEdit1;
__parser.AddParsedSubObject(Self.Edit1);
__parser.AddParsedSubObject(System.Web.UI.LiteralC ontrol.Create(''#13#10' '));
Self.__BuildControl__control3;
__parser.AddParsedSubObject(Self.__control3);
__parser.AddParsedSubObject(System.Web.UI.LiteralC ontrol.Create(''#13#10' '));
Result := __ctrl;
end;
function editdemo_aspx.__BuildControlMessage: System.Web.UI.Control;
var
__ctrl: System.Web.UI.WebControls.Label;
begin
__ctrl := System.Web.UI.WebControls.Label.Create;
Self.Message := __ctrl;
__ctrl.ID := 'Message';
Result := __ctrl;
end;
procedure editdemo_aspx.__BuildControlTree(__ctrl: System.Web.UI.Control);
var
__parser: System.Web.UI.IParserAccessor;
begin
__parser := __ctrl as System.Web.UI.IParserAccessor;
__parser.AddParsedSubObject(System.Web.UI.LiteralC ontrol.Create('<html>'#13#10' '));
__parser.AddParsedSubObject(System.Web.UI.LiteralC ontrol.Create(''#13#10' <body>'#13#10' '));
Self.__BuildControl__control2;
__parser.AddParsedSubObject(Self.__control2);
__parser.AddParsedSubObject(System.Web.UI.LiteralC ontrol.Create(''#13#10' <p><b>'));
Self.__BuildControlMessage;
__parser.AddParsedSubObject(Self.Message);
__parser.AddParsedSubObject(System.Web.UI.LiteralC ontrol.Create('</b></p>'#13#10' </body>'#13#10'</html>'#13#10));
end;
procedure editdemo_aspx.FrameworkInitialize;
begin
Self.__BuildControlTree(Self);
Self.FileDependencies := ASP.editdemo_aspx___fileDependencies;
Self.EnableViewStateMac := True;
end;
function editdemo_aspx.GetTypeHashCode: Integer;
begin
Result := -764444463;
end;
end.
كد فوق صرفا زماني قابل رويت است كه خطاي دستوري در برنامه دلفي خود داشته باشيد و وب سرور ضمن ارائه Error مربوط سورس كد را نير به شما نشان خواهد داد و در بقيه موارد راهي براي ديدن اين كد وجود ندارد و برنامه شما بصورت اسكريپت AspX كامپايل شده كه به زبان دلفي نوشته شده است قابل استفاده است .
هر چند هنوز محصول جامع و قابل اطمينان بورلند براي سازگاري محصولاتش با دات نت معرفي نشده است و احتمالا جزئيات موجود در .Net Preview نيز تغيير خواهند كرد اما اميد است توضيحات فوق تصوير نسبتا روشني از آنچه در آينده اي نزديك از تركيب تكنولوژي مايكروسافت و كامپايلر بورلند نصيبتان خواهد شد ايجاد كرده باشد .
به دو مثال زير نيز توجه كنيد :
الف(يكي از اشيا مفيد همراه ويژوال استوديو براي توسعه وب Calendar ميباشد . يك نمونه از آن را روي فرم وب خود گذاشته و پس از نسبت دادن مقادير مناسب به خواص پايه اي آن كد مناسب دلفي را براي توليد خروجي با عنوان تاريخ انتخاب شده توسط كاربر و حركت به سمت تاريخ مورد نظر كاربر را به شكل زير بنويسيد :
كد:
<script language="Delphi" runat="server">
procedure Calendar1Selected(Sender: System.Object; E: EventArgs);
begin
Label1.Text := 'Delphi for .NET says you picked ' + Calendar1.SelectedDate.ToString('D');
end;
procedure Button1Click(Sender: System.Object; E:EventArgs);
begin
Calendar1.VisibleDate := System.Convert.ToDateTime(Edit1.Text);
Label1.Text := 'Delphi for .NET says you set ' + Calendar1.VisibleDate.ToString('D');
end;
</script>
<body style="font:18pt Verdana">
<form runat="server">
<center>
<h1>Delphi for .NET running in ASP.NET</h1>
<p>Please pick a date</p>
<asp:Calendar id="Calendar1" runat="server" ForeColor="#0000FF" BackColor="#FFFFCC"
OnSelectionChanged="Calendar1Selected">
<TodayDayStyle Font-Bold="True"/>
<NextPrevStyle ForeColor="#FFFFCC"/>
<DayHeaderStyle BackColor="#FFCC66"/>
<SelectedDayStyle ForeColor="Black" BackColor="#CCCCFF"/>
<TitleStyle Font-Size="14pt" Font-Bold="True" ForeColor="#FFFFCC" BackColor="#990000"/>
<OtherMonthDayStyle ForeColor="#CC9966"/>
</asp:Calendar>
<p><asp:TextBox id="Edit1" width=200 runat="server"/>
<asp:Button text="Set date" id="Button1" OnClick="Button1Click" runat="server" />
</p>
<p><asp:Label id="Label1" runat="server"/></p>
</center>
</form>
</body>
خروجي برنامه ASP.NET اي خواهد بود كه در محيط ويژوال استوديو توليد شده و از كامپوننت تقويم طراحي شده با #C استفاده ميكند و پياده سازي آن توسط دلفي انجام شده است .
ب(اگر آشنائي مقدماتي با محيط ويژوال استوديو داشته باشيد ميدانيد كه اين محيط براي توليد سريع محتواي وب مبتني بر بانكهاي اطلاعاتي كامپوننتهاي خاصي جهت نمايش و ويرايش داده ها دارد .
يك نمونه از كامپوننت DataGrid را و يك نمونه TextBox را به فرم مثال قبلي ( تقويم ) اضافه كنيد . كد دلفي نوشته شده با بانك اطلاعاتي معروف Northwind موجود در سيستم ارتباط برقرار ميكند . ( بايد اسكوئل سرور 2000 نصب شده باشد (
حالا تقويم شما با بانك اطلاعاتي اتصال برقرار كرده و اطلاعات لازم استخراج ميگردد .
كد:
<%@Import Namespace="System.Data"%>
<%@Import Namespace="System.Data.SqlClient"%>
<script language="Delphi" runat="server">
const
ProdName = 'Delphi for .NET';
DispFields = 'OrderID, CustomerID, ShipName, ShipCity, ShipCountry';
procedure DateSelected(Sender: System.Object; E: EventArgs);
begin
Label1.Text := ProdName + ' says you picked ' + Calendar1.SelectedDate.ToString('D');
DataGrid1.DataSource := GetOrders(Calendar1.SelectedDate);
DataGrid1.DataBind;
end;
procedure Button1Click(Sender: System.Object; E:EventArgs);
begin
Calendar1.VisibleDate := System.Convert.ToDateTime(Edit1.Text);
Label1.Text := ProdName + ' says you set ' + Calendar1.VisibleDate.ToString('D');
end;
procedure Button2Click(Sender: System.Object; E:EventArgs);
begin
DisplayFields.Text := DispFields;
end;
function GetOrders(Date : DateTime) : DataSet;
var
Adapter : SqlDataAdapter;
begin
Adapter := SqlDataAdapter.Create(
'select ' + DisplayFields.Text + ' from Orders '+
'where OrderDate = ''' + date.ToString('d')+'''',
'Server=(local);Database=Northwind;Trusted_Connect ion=yes');
Result := DataSet.Create;
Adapter.Fill(Result);
end;
</script>
<body style="font:18pt Verdana">
<form runat="server">
<h1><%=ProdName %> with a Calendar, DataGrid, & SqlClient in ASP.NET</h1>
<table>
<tr valign="top"><td>
<p><b>Pick a date</b></p>
<asp:Calendar id="Calendar1" runat="server" ForeColor="#0000FF" BackColor="#FFFFCC"
OnSelectionChanged="DateSelected">
<TodayDayStyle Font-Bold="True"/>
<NextPrevStyle ForeColor="#FFFFCC"/>
<DayHeaderStyle BackColor="#FFCC66"/>
<SelectedDayStyle ForeColor="Black" BackColor="#CCCCFF"/>
<TitleStyle Font-Size="14pt" Font-Bold="True" ForeColor="#FFFFCC" BackColor="#990000"/>
<OtherMonthDayStyle ForeColor="#CC9966"/>
</asp:Calendar>
<p><asp:TextBox id="Edit1" width=150 runat="server"/>
<asp:Button text="Set date" id="Button1" OnClick="Button1Click" runat="server" />
</p>
</td><td valign="top">
<p><b>Display fields:</b> <asp:TextBox id="DisplayFields"
text="OrderID, CustomerID, ShipName, ShipCity, ShipCountry" width=500 runat="server"/>
<asp:Button text="Reset fields" id="Button2" OnClick="Button2Click" runat="server" /></p>
<asp:DataGrid id="DataGrid1" runat="server" BorderColor="#FFCC66" ForeColor="#0000FF">
<HeaderStyle ForeColor="#FFFFCC" BackColor="#990000"/>
</asp:DataGrid>
</td></tr></table>
<p><asp:Label id="Label1" runat="server"/></p>
</form>
</body>
بخاطر داشته باشيد كه خطوط :
كد:
<%@Import Namespace="System.Data"%>
<%@Import Namespace="System.Data.SqlClient"%>
درست مانند SqlConnection و ClientDataset محيط دلفي عمل كرده و ارتباط با بانك داده ها و ظرفي براي استخراج داده ها فراهم مي آورند .
اميد است توضيحات هر چند سطحي فوق ذهنيت مناسبي براي برنامه نويساني كه قصد دارند پاي به عرصه وب بگذارند ايجاد كرده باشد
استفاده از فلش در دلفی:
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 خطوط زير را در در سورس كد فرم اصلي خود قرار دهيد:
...
...
implementation
...
...
...
{$R *.dfm}
{$R SWFActivex.RES}
-5 حالا اين تابع را به كد خود اضافه كنيد:
function GetResourceFile(S : string; FilePath : string) : Boolean;
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;
-6 اين تابع را نيز اضافه كنيد:
function GetSystemDir : string;
var
SysPath : PChar;
begin
GetMem(SysPath, MAX_PATH + 1);
GetSystemDirectory(SysPath, MAX_PATH);
Result := StrPas(SysPath)+ '\';
FreeMem(SysPath, MAX_PATH + 1);
end;
-7 خوب! حالا بگذاريد به مهمترين قسمت قضيه يعني Register كردن OCX مربوطه بپردازيم. در ابتدا يونيت ActiveX را به ليست uses خود اضافه كنيد. سپس تابع زير را نيز به سورس خود اضافه نماييد.
function RegisterOCX( OCXFileName : string; Flag : Boolean) : Boolean;
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;
-8 اين سه متغيير را نيز به كد خود اضافه كنيد:
var
FilePath : string;
FlashOCX: TShockwaveFlash;
-9 تابع زير را نيز اضافه كنيد:
function CreateFlashOCX : Boolean;
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;
-10 كدهاي زير را به انتهاي فايل خود، قبل از .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.
-11 در اونت OnCreate فرم خودتون به راحتي از كمپوننت مربوطه استفاده كنيد:
FlashOCX.Parent := Form1;
FlashOCX.Movie := ExtractFilePath(Application.ExeName) + 'Main.swf';
FlashOCX.Play;
Resize شدن درست:
يكي از مشكلاتي كه ممكن است با اكتيو ايكس فلش پيدا كنيد مشكل 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
begin
PopupMenu1.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y);
Handled := True;
end;
ارتباط بين Flash و دلفى:
يكى از مسائل بسيار مهم و اساسى ديگر برقرارى ارتباط بين Flash و دلفي است. فرض كنيد در فايل SWF خود چند Button داشته باشيد و بخواهيد وقتى كاربر روى هر كدام از اين اونتها كليك كرد فرم خاصى باز شود. در اين صورت چه بايد بكنيد. پياده سازى اين كار بسيار ساده است. كافى است در Flash براى هر كدام از دكمههاى خود يك Action تعريف كنيد و از دستور FSCommand استفاده نماييد. از يك مقدار دلخواه مثل fMatn يا fSearch استفاده كنيد و در دلفى نيز از اونت OnFSCommand به صورت زير استفاده كنيد:
if command = 'fMain' then fMain.ShowModal;
if command = 'fSearch' then fSearch.ShowModal;
اجرا کردن فایل exe از درون دلفی:
يكي از مشكلاتي كه بسياري از تازه كاران در دلفي با آن مواجه مي شوند اجراي فايلهاي ديگر يا اجراي دستورات shell است.
در اين مقاله سعي ما بر اين است كه شما را با اجراي فايلهاي ديگر از درون دلفي و كنترل آنها آشنا كنيم. شما پس از خواندن اين مقاله خواهيد توانست به راحتي فايلهاي ديگر -و نه تنها exe- را از درون دلفي اجرا كنيد و حتي دستورات shell را نيز صادر كنيد. به عنوان مثال ممكن است بخواهيد يك فايل html را با Editor پيش فرض كاربر باز كنيد. يا يك فايل html را با Browser پيش فرض كاربر باز كنيد. يا شايد بخواهيد يك فايل BMP را با اديتور پيش فرض كاربر باز نماييد و يا اين كه يك فايل INF را نصب نماييد.
با خواندن اين مقاله شما مي توانيد به راحتي به تمامي اين اهداف برسيد.
تابع APIي وجود دارد به نام WinExec. شكل كلي اين تابع از اين قرار است:
WinExec(lpCmdLine: PAnsiChar; uCmdShow: Cardinal);
كه lpCmdLine خط دستور مورد نظر شما براي اجراي فايل و uCmdShow بايد يكي از مقادير زير را داشته باشد:
SW_HIDE SW_MAXIMIZE SW_MINIMIZE
SW_RESTORE SW_SHOW SW_SHOWDEFAULT
SW_SHOWMAXIMIZED SW_SHOWMINIMIZED SW_SHOWMINNOACTIVE
SW_SHOWNA SW_SHOWNOACTIVATE SW_SHOWNORMAL
براي توضيحات بيشتر راجع به هر كدام از اين ثابت ها به راهنماي Windows SDK دلفي يا MSDN مراجعه كنيد.
تابع WinExec تابع بسيار قديمي و محدودي است و ما قصد نداريم در اين مقاله بيشتر از اين راجع به اين تابع صحبت كنيم.
تابع ديگري وجود دارد به نام ShellExecute. اين تابع در يونيت ShellAPI تعريف شده است. بنابر اين لازم است يونيت ShellAPI را در ليست uses يونيت خود وارد كنيد. اين يكي از توابع بسيار قدرتمند براي اجراي فايل است.
نگاهي به شكل كلي اين تابع بياندازيد:
function ShellExecute(hWnd: HWND; Operation, FileName, Parameters, Directory: PChar; ShowCmd: Integer): HINST; stdcall;
hWnd Handle پنجره اي كه اين دستور را فراخوانده است.
Operation نوع دستوري مورد نظر جهت اجرا
FileName نام فايل يا شاخه
Parameters پارامترهاي مورد نظر در هنگام اجراي فايل exe
Directory شاخه پيش فرض در هنگام اجراي فايل
ShowCmd مشخص كننده چگوني نمايش فايل در هنگام اجرا
پارامتر اول يك متغيير از نوع HWND است.
لازم است براي كساني كه با مفهوم Handle در ويندوز آشنا نيستند توضيحاتي راجع به Handle بدهم. هر پنجره يا آبجكتي در ويندوز داراي يك Handle است كه براي دسترسي به آن پنجره يا آبجكت شما بايد از اين Handle استفاده كنيد. در واقع يك Handle يك عدد در مبناي 16 است. Handle يك عدد unique يا همتا است كه ويندوز آن را مقداردهي مي كند. اگر از يك پنجره دو Instance اجرا شده باشد (مثلا يك برنامه دو بار اجرا شده باشد) هر كدام از اين Instanceها يك Handle جداگانه دارند.
با اين تفاصيل پارامتر اول Handle پنجره اي است كه اين دستور را صادر كرده است. شما براي اين پارامتر مي توانيد از Application.Handle استفاده كنيد و يا آن را برابر 0 قرار دهيد. به علاوه مي توانيد Handle يك برنامه ديگر را بدهيد.
در صورتي كه شما مي خواهيد پيغام هاي اخطار آن فايل را دريافت كنيد يا آن را كنترل نماييد و يا تا اجراي كامل آن اجراي برنامه را متوقف كنيد با Handle برنامه خود را با استفاده از Application.Handle به اين پارامتر بدهيد.
پارامتر دوم مشخص كننده وظيفه اي است كه قرار است انجام شود. اين پارامتر مقادير پيش فرضي ندارد و بستگي به خصوصيات فايل اجرايي دارد. روي يك فايل از نوع Text كليد سمت راست ماوس را بزنيد. احتمالا موارد بالاي ليست "open"، "Edit with ..." , "print" است. هر كدام از اين رشته هاي مي توانند يك عمليات يا Operation باشند. به عنوان مثال شما مي خواهيد يك فايل Text را چاپ كنيد. در اين صورت كافي است از عبارت print به عنوان operation استفاده كنيد. يا مي خواهيد يك فايل rar را با استفاده از WinRar باز كنيد. در اين صورت مي توانيد از "Extract files" استفاده كنيد. حتما تا به حال متوجه شده ايد كه دستور ShellExecute چه مقدار انعطاف پذير است. با استفاده از اين فرمان مي توانيد هر گونه دستور Shell را اجرا نماييد.
پارامتر سوم مشخص كننده نام فايل يا شاخه اي است كه شما مي خواهيد عمليات بر روي آن انجام شود.
پارامتر چهارم ليست پارامترهايي است كه تمايل داريد فايل exe با اين پارامترها اجرا شود. پارامترها پنجم نيز نام شاخه پيش فرض در هنگام اجراي فايل مورد نظر شماست. اگر شما فايل exe اي را اجرا كنيد و اين فايل exe بخواهد از شاخه جاري فايلهاي اضافه اي را استفاده كند ويندوز شاخه جاري را به اون مطابق با اين شاخه اطلاع خواهد داد. و اما آخرين پارامتر مشخص كننده شكل اجراي فايل است. مقدار اين پارامتر مي تواند يكي از ثابت هايي ليستي باشد كه در ابتداي اين مقاله عنوان شد. به عنوان مثال شما مي توانيد از SW_HIDE استفاده كنيد كه در اين صورت فايل اجراي شما مخفي خواهد بود و يا از SW_SHOWMINIMIZE استفاده كنيد كه در اين صورت برنامه شما Minimizeشده اجرا مي شود.
و حالا به يك نكته خيلي مهم توجه كنيد:
1- رشته هاي اين تابع از نوع PChar هستند بنابراين شما بايد رشته هاي string را به صورت PChar به اين تابع بدهيد. شما مي توانيد به طور عادي رشته مورد نظر خود را به اين تابع بدهيد و يا در صورتي كه رشته مورد نظر شما string است بايد با استفاده با استفاده از دستور PChar آن را Typecast كنيد. به عنوان مثال:
ShellExecute(0, 'open', PChar(ExtractFilePath(Application.ExeName) + 'test.exe') , '', '', SW_SHOWNORMAL);
در اين مثال با استفاده از تابع ExtractFilePath و Application.ExeName كه حاوي آدرس كامل فايل Exe است شاخه اي كه فايل exe در آن قرار دارد را پيدا كرده ايم و سپس فايل test.exe را كه در كنار فايل اصلي اجرايي وجود دارد را به آن اضافه كرده ايم. كل اين عبارت TypeCast شده است به PChar.
جهت اطلاع كساني كه نمي دانند TypeCast چيست. TypeCast فرآيندي است كه شما متغيير يا Objectي را از يك نوع به نوع ديگري تبديل ميكنيد. كد زير را نگاه كنيد و با نوع پيشرفته تري از TypeCast آشنا شويد:
procedure TForm1.Button1Click(Sender: TObject); begin TButton(Sender).Caption := 'Test'; end;
در اين مثال Sender را از نوع TObject است TypeCast كرده ايم به TButton. و پراپرتي Caption آنرا تغيير داده ايم. براي اطلاعات بيشتر راجع به TypeCast به كتب دلفي مراجعه كنيد.
و اجازه دهيد به چند مثال جالب نيز نگاهي بياندازيم:
edit كردن يك فايل HTML با Editor پيش فرض HTML:
ShellExecute(Handle, 'edit', 'test.htm', '', '', SW_SHOW);
نصب يك فايل INF
ShellExecute(Handle, 'install', 'divx.inf', '', '', SW_SHOW);
فشرده ساختن يك فايل با استفاده از winrar و ارسال آن به ايميل:
ShellExecute(Handle, 'compress and mail...', 'test.file', '', '', SW_SHOW);
ارسال ايميل بهفقط اعضای سایت میتوانند لینک ها را ببینند ! برای ثبت نام کلیک کنید
و با موضوع "Great Article":
ShellExecute(0, 'open', 'فقط اعضای سایت میتوانند لینک ها را ببینند ! برای ثبت نام کلیک کنید
چگونه يك فايل exe را اجرا كنيم و تا اتمام آن برنامه را متوقف كنيم؟
uses ShellAPI;...function ExecAndWait(const ExecuteFile, ParamString : string): boolean;varSEInfo: TShellExecuteInfo;ExitCode: DWORD;beginFillChar(SEInfo, SizeOf(SEInfo), 0);SEInfo.cbSize := SizeOf(TShellExecuteInfo);with SEInfo dobeginfMask := SEE_MASK_NOCLOSEPROCESS;Wnd := Application.Handle;lpFile := PChar(ExecuteFile);lpParameters := PChar(ParamString);nShow := SW_HIDE;end;if ShellExecuteEx(@SEInfo) thenbeginrepeatApplication.ProcessMessages;GetExit CodeProcess(SEInfo.hProcess, ExitCode);until (ExitCode <> STILL_ACTIVE) or Application.Terminated;Result:=True;endelse Result:=False;end;
همان طور كه ملاحظه مي كنيد اين تابع به يونيت ShellAPI نياز دارد و بايد اين يونيت را در ليست uses يونيت خود اضافه كنيد.
در اين تابع از تابع ديگري به نام ShellExecuteEx استفاده شده است. اين تابع بر خلاف ShellExecute فقط يك پارامتر دارد كه بايد برابر متغييري از نوع TShellExecuteInfo قرار بدهيد. در ابتدا بايد با استفاده از تابع FillChar آنرا مقداردهي كنيد و وجود آنرا به ويندوز اطلاع دهيد. در واقع آن را Create كنيد:
FillChar(SEInfo, SizeOf(SEInfo), 0); SEInfo.cbSize := SizeOf(TShellExecuteInfo);
آبجكت ShellExecuteEx داراي پارامترهاي زير است:
cbSize: DWORD;fMask: ULONG;Wnd: HWND;lpVerb: PAnsiChar;lpFile: PAnsiChar;lpParameters: PAnsiChar;lpDirectory: PAnsiChar;nShow: Integer;hInstApp: HINST;
براي اطلاعات بيشتر راجع به اين پارامترها به راهنماي Windows SDK دلفي يا MSDN مراجعه كنيد. خروجي اين تابع از نوع boolean است و مشخص كننده اين
است كه آيا اين تابع با موفقيت اجرا شده است يا نه؟
تابع ExecAndWait پس از اين كه اطمينان پيدا كرد كه فايل با موفقيت اجرا شده است يك حلقه repeat..until تشكيل داده. در داخل repeat دستور Application.ProcessMessage صادر شده است تا برنامه بتواند messageها را دريافت كند. سپس با استفاده از GetExitCodeProcess مقدار خروجي پروسس اجرا شده دريافت مي گردد. در صورتي كه خروجي اين تابع مخالف STILL_ACTIVE بود (كه نشانگر اجراي پروسس است) حلقه با كار خود ادامه مي دهد.
خروجي اين تابع مشخص كننده اجرا يا عدم اجراي فايل اجرايي است.
و حالا به چند مثال جالب ديگر توجه كنيد:
-1 دسترسي به HotMail از درون دلفي:
program dummy;var ToAddress: string;EightSpaces: string;beginToAddress := 'john@pacbell.net';// Don't know why but this is required to get the// correct compose address...EightSpaces := ' ';ShellExecute(Handle, PChar('open'), PChar('rundll32.exe'), PChar('C:\PROGRA~1\INTERN~1\HMMAPI.DLL,MailToProto colHandler' + EightSpaces + ToAddress), nil, SW_NORMAL)end.
-2 نمايش ديالوگ مشخصات يك فايل:
procedure ShowPropertiesDialog(Filename: string);varSEI: TShellExecuteInfo;beginFillChar(SEI, SizeOf(SEI), 0);with SEI dobegincbSize := SizeOf(SEI);lpFile := PChar(Filename);lpVerb := 'properties';fMask := SEE_MASK_INVOKEIDLIST;end;ShellExecuteEx(@SEI);end ;
-3 اجراي ديالوگ Screen ويندوز: (Control Panel > Display)
ShellExecute(HInstance, nil, PCHAR('rundll32.exe'), PCHAR('shell32.dll, Control_RunDLL desk.cpl, , 3') { 3 is the tab index }, NIL, 1);
همان طور كه متوجه شديد 3 شماره Tabي است كه مورد نظر شماست.
-4 يك مثال كامل تر از فرستادن ايميل با استفاده از Outlook يا ارسال كننده پيش فرض :email
varmail: string;beginmail := 'فقط اعضای سایت میتوانند لینک ها را ببینند ! برای ثبت نام کلیک کنید
خروجي هاي تابع ShellExecute يا ShellExecuteEx
خروجي هاي اين دو تابع مي تواند يكي از مقادير زير باشد:
0 سيستم عامل داراي resourceهاي كافي يا حافظه كافي جهت اجرا نيست.
ERROR_FILE_NOT_FOUND فايل مورد نظر پيدا نشد.
ERROR_PATH_NOT_FOUND آدرس مشخص شده پيدا نشد.
ERROR_BAD_FORMAT فايل EXE نامعتبر است يا اين يك فايل EXE از نوع Win32 نيست.
SE_ERR_ACCESSDENIED سيستم عامل دسترسي به فايل مشخص شده ندارد.
SE_ERR_ASSOCINCOMPLETE association فايل مورد نظر شما ناقص يا نامعتبر است. مثلا مشخص نشده كه فايل bmp كه شما مي خواهيد آن را اجراه كنيد بايد با چه برنامه اي باز شود.
SE_ERR_DDEBUSY DDE transaction مربوطه كامل نشد زيرا DDE transactionهاي ديگري در حال اجرا بودند.
SE_ERR_DDEFAIL DDE transaction ناموفق بود.
SE_ERR_DDETIMEOUT DDE transaction نتوانست اجرا شود زيرا درخواست Time Out شد.
SE_ERR_DLLNOTFOUND فايل dynamic-link library يا dll مشخص شده پيدا نشد.
SE_ERR_FNF فايل مورد نظر پيدا نشد.
SE_ERR_NOASSOC هيچ برنامه اي با پسوند فعلي فايل منطبق نشده است. مثلا مشخص نشده كه فايل bmp كه شما مي خواهيد آن را اجراه كنيد بايد با چه برنامه اي باز شود.
SE_ERR_OOM حافظه كافي جهت اجراي عمليات وجود ندارد.
SE_ERR_PNF آدرس مشخص شده پيدا نشد.
SE_ERR_SHARE يك خطاي sharin violation پيش آمد. يعني فايل مورد نظر share شده بود.
خلاصه:
در اين متن با سه تابع API مهم به نام هاي WinExec و ShellExecute و ShellExecuteEx آشنا شديم و پارامترهاي آنها را بررسي كرديم. به علاوه مثالهاي متعددي راجع به استفاده از ShellExecute ارائه داديم. به علاوه ثابتهاي استفاده شده در اين تابع ها را ليست كرده و بعضا آنها را مورد بررسي قرار داديم. همچنين تابعي به نام ExecAndWait ارائه داديم كه كار آن اجراي يك فايل exe و متوقف كردن برنامه تا اتمام فايل exe آشنا شديم و ساختمان داخلي اين تابع را مورد بررسي قرار داديم.
پیشگفتار:
یكی از شیوه های متداول برنامه نویسی استفاده از برنامه نویسی شیﮔرا (object oriented)می باشد. برنامه نویسی شی ﮔرادر حققت برنامه نویسی ساختیافته توسعه داده شده می باشد.
این برنامه نویسی شیوه نوینی است كه در آن می توان قطعاتی را ایجاد كرد و در برنامه های مختلف مورد استفاده قرار داد.
قابلیت خوانایی برنامه هایی كه به این روش نوشته می شوند بالا بوده، تست ، عیب یابی و اصلاح آنها آسان است. از دیگر قابلیتهای آن كاهش مدت زمان طراحی و افزایش كارآیی برنامه می باشد.
دلفی تلفیقی از برنامه نویسی شی گرا و مجموعه ای از اجزای بصری است. وجود اشیاء آماده و خواص آنها برنامه نویسی را ساده كرده است.
دلفی به عنوان یك زبان برنامه سازی تحت سیستم ویندوز (كه امروزه محبوبترین سیستم عامل جهان محسوب می شود)، تحولی عظیم در برنامه نویسی ایجاد نموده است.
دلفی یك زبان برنامه نویسی سطح بالا با مقاصد عمومی است چرا كه از آن می توان برای انواع كاربردهای كامپیوتر چه علمی وچه تجاری استفاده كرد. زبان دلفی زبانی مناسب برای پردازش مستقیم است.
دلفی بسته نرم افزاری نسبتآ جدیدی می باشد كه به جهان كامپیوتر عرضه شده است و امكانات برنامه نویسی پیشرفته و قدرتمندی را برای استفاده كنندگان سیستم های كامپیوتری به ارمغان آورده و مترجم سریع و قوی دلفی امكان ترجمه سریع برنامه ها را فراهم نموده است. دلفی یكی از پركاربردترین زبانهای موجود در دنیای نرم افزار است كه امروزه در زمینه های مختلفی از جمله برنامه های گرافیكی، چند رسانه ای ، پایگاه داده هاو... به خوبی از آنها استفاده می شود.
سرعت برنامه نویسی در دلفی و قدرت فوق العاده بانك اطلاعاتی آن جذابیت خاصی در بین برنامه نویسان داشته است. امروزه زبان دلفی روی انواع گوناگونی از كامپیوترها و به ویژه اینكه به صورت زبان استانداردی برای ریز كامپیوترها قابل استفاده است .
زبان دلفی از زمان ایجاد تا به حال دچار تغییرات و اضافات متعددی شده و امروزه گونه استاندارد مناسبی از آن به وجود آمده است. زبان دلفی به صورت زبان همگانی برای فراگیری كامپیوتر در دانشگاه ها ، مؤسسه های آموزشی كامپیوتر و ... درآمده است.
بانك اطلاعاتی چیست؟
بانك اطلاعاتی مجموعه ای سازمان یافته از اطلاعات وداده های مرتبط به هم است .داده ها عبارتند از : حقایق وارقام یك موضوع خاص واطلاعات عبارتند از :نتایجی كه از تركیب داده ها حاصل می گردند . موسسات و سازمانها معمولا سیستمهای اطلاعاتی خود را به دو صورت تشكیل داده و از آنها استفاده می كنند.
استفاده از سیستمهای اطلاعاتی ساده:
در این روش ، داده ها در فایلهای جداگانه قرار می گیرند و برای استفاده از داده های موجود در آن فایلها ، سیستمهای جداگانه ای طراحی می شوند . به این نوع سیستمهای اطلاعاتی سیستم پردازش فایلها می گویند .
استفاده از بانكهای اطلاعاتی :
در این روش داده های موجود ، به صورت مجتمع یا بانك مورد استفاده قرار می گیرند . در چنین سیستمی كاربر می تواند بدون سر در گمی و با صرف وقت اندكی ، اطلاعات مورد نیازی خود را از داده های موجود در بانك اطلاعاتی اخذ كند . امروزه اكثر مؤسسات وسازمانها سعی می كنند از این سیستم اطلاعاتی استفاده كنند . برای پی بردن به تفاوت دو روش ذكر شده مؤسسه ای را در نظر بگیرید كه داده های مربوط به حقوق كارمندان ، بیمه ، تنبیه و تشویق را در چهار فایل جداگانه قرار داده برای اخذ خروجی های مورد نیاز ، سیستمهای جداگانه ای برای آنها نوشته است .
كار سیستم حقوق ، محاسبه دستمزد كاركنان با استفاده از داده های موجود در فایل حقوق ، كار سیستم بیمه ، پردازش داده های موجود در فایل بیمه و كار سیستمهای تنبیه و تشویق ، پردازش داده های موجود در فایلهای تنبیه و تشویق می باشد . هر یك از این سیستمها می توانند خروجی مناسبی را تولید كنند ، اما اگر بخواهیم اطلاعات جدیدی مانند آنچه در زیر آمده است اخذ كنیم ، با مشكل مواجه خواهیم شد:
1. كارمندانی كه دارای حقوق مشخصی بوده به تعداد دفعات مشخصی تنبیه یاتشویق شده اند .
2. كارمندانی كه در تاریخ معینی استخدام شده مبلغ خاصی برای آنها از طرف بیمه هزینه شده است .
3. كارمندانی كه تعداد دفعات تنبیه آنها بیشتر از تعداد دفعات تشویق باشد و برعكس.
در همه موارد بالا وموارد مشابه مجبوریم از داده های موجود در دو یا چند فایل استفاده كنیم كه كار ساده ای نیست. زیرا ممكن است داده های موجود در فایل ها دارای فرمت یكسانی نباشند . در حالی كه اگر مؤسسه سیستم اطلاعاتی خود را به صورت بانك اطلاعاتی تشكیل دهد با چنین مشكلی مواجه نخواهد شد.
در سیستم جدید ، تمامی داده های موجود در فایلهای طراحی شده در روش اول ، در یك فایل بزرگتر به نام بانك اطلاعاتی قرار می گیرد كه در نتیجه پردازش داده ها و اخذ گزارش های جدید آسان تر خواهد بود.
مزایای استفاده از بانك اطلاعاتی:
با یك نگاه ساده مشخص می شود كه داده های زیادی از قبیل نام كارمندان ، شماره كارمندی ، تاریخ استخدام در فایل های مختلف مشترك می باشد .این امر موجب استفاده بیهوده از حافظه می گردد. اگر در وضعیت كارمندان مؤسسه تغییراتی ایجاد شود،این تغییرات باید در تمام فایلها اعمال شود ، اگر این تغییرات در یك یا چند فایل اعمال نشود ، منجر به اخذ گزارشهای متناقضی می گردد ، اگر در این صورت به گزارشهای حاصل از سیستم اطمینانی نیست .
چون در روش پردازش داده ها به صورت بانك اطلاعاتی ، داده های مربوط به سیستم در یك فایل قراردارند ، در صورت نیاز فقط باید یك فایل را تغییر دهیم كه نه تنها وقت كمتری صرف می شود بلكه به گزارش های به دست آمده مطمین خواهیم بود .
در پردازش داده ها به صورت بانك اطلاعاتی ، داده ها از سیستمهای طراحی شده استقلال دارند ، در حالیكه در روش پردازش داده ها به صورت پردازش فایلها ، این گونه نیست. به عنوان مثال ، اگر ساختار بانك اطلاعاتی تغییر كند ، تغییری در سیستمهای كاربردی ایجاد نمی شود ، چرا كه سیستمهای كاربردی فقط از طریق سیستم پردازش بانكهای اطلاعاتی ، با داده ها مرتبط هستند.
در سیستم بانكهای اطلاعاتی می توان مسیولیت تصحیح وتفسیر داده ها را به عهده یك نفر یا یك واحد گذاشت ، كه در این صورت مدیریت داده ها به نحو بهتری انجام می گیرد.
مزایای استفاده از سیستم بانك اطلاعاتی به جای سیستم پردازش فایلها را می توان چنین برشمرد:
1. جلوگیری از اتلاف حافظه در ذخیره كردن داده ها .
2. ایجاد اطمینان نسبت به گزارش های به دست آمده.
3. اخذ گزارشهای جدید ساده است .
4. سرعت پردازش داده ها بالاست .
5. داده ها از سیستمهای كاربردی مستقل هستند .
6. تمركز در مدیریت داده ها به خوبی امكان پذیر است .
معایب استفاده از سیستم بانك اطلاعاتی:
بانك اطلاعاتی با همه مزایایش ، معایبی نیز دارد كه این معایب در مقابل مزایای فوق ناچیزند ، از جمله :
1. چون طراحی بانكهای اطلاعاتی ساده نیست ، جهت ایجاد آن به متخصصان ماهری نیاز است .
2. به دلیل متمركز بودن سیستم اطلاعاتی ، امكان آسیب پذیری سیستم زیاد است .یعنی ، اگر یك قسمت از سیستم از كار بیفتد ، ممكن است در كار بقیه قسمت ها خلل ایجاد شود .
اجزای تشكیل دهنده بانك اطلاعاتی:
1. كاربران
2. سیستم بانكهای اطلاعاتی
3. داده های موجود در بانكهای اطلاعاتی
كاربران كسانی هستند كه به نحوی با بانكهای اطلاعاتی سرو كار دارند . بر اساس نوع كاری كه كاربران با بانك اطلاعاتی دارند ، می توان آنها را به سه دسته تقسیم كرد :
1. مدیر یا مسیول بانك اطلاعاتی
2. برنامه نویسان كاربردی یا طراحان بانكهای اطلاعاتی
3. كاربران نهایی
كاربران نهایی كسانی هستند كه حق هیچگونه تغییر وتبدیل را در بانك اطلاعاتی ندارند، بلكه فقط از امكانات آن می توانند استفاده نمایند .طراحان بانكهای اطلاعاتی كسانی هستند كه بانك اطلاعاتی را ایجاد نموده اند .مسیول بانك اطلاعاتی كسی است كه حق هر گونه تبدیل وتغییر را در بانك اطلاعاتی دارد . به عنوان مثال اضافه كردن داده های جدید وحذف یا اصلاح داده ها به عهده مسیول بانك اطلاعاتی است .سیستم بانك اطلاعاتی مجموعه ای از برنامه هایی است كه نیازهای كاربران را برآورده می كند .
برای ایجاد بانك اطلاعاتی نیاز به جدولهایی داریم كه داده های ما درون این جدولها قرار می گیرد ، كه تعداد این جدولها باتوجه به نیازهای بانك اطلاعاتی ما متفاوت است .
ایجاد ساختار جدول:
برای ایجاد یك جدول ابتدا باید ساختار ركورد را مشخص كرد . برای این منظور باید نام ، نوع وطول هر فیلد از ركوردهای جدول را انتخاب نمود . برای تعریف ساختار جدول فرمان data base desktop را از منوی tools انتخاب نمایید :
1. پس از ظاهر شدن پنجره data base desktop گزینه file/ new/ table راانتخاب كنید تا كادر محاوره create table فعال شود . دراین كادر باید نوع جدول را وارد نمایید چون دلفی با پاراداكس راحت تر كار می كند پسparadox 7 را انتخاب كرده دكمه ok را كلیك كنید تا صفحه create paradox 7 table ظاهر شود ( البته اگر نوع جدول هم چیز دیگری غیر از پاراداكس باشد باز هم شامل قسمتهای زیر است ). بخشهای آن به صورت زیر است :
بخشname field : در این بخش می توان نام فیلدها را وارد كرد . نام فیلدها از قانون نام گذاری متغییر ها پیروی می كند . ( برای نامگذاری متغیر ها ، تركیبی از حروف A تا Z ، ارقام وخط رابط (-) استفاده می شود . دقت كنید كه در نامگذاری متغییر ها تفاوتی بین حروف كوچك وبزرگ نیست ) .
بخش type : در این بخش می توان نوع فیلد ها را وارد كرد كه در جدول زیر با چند نوع متداول آنها آشنا می شوید :
مفهوم نوع فیلد
مجموعه ای از كاراكترهای رشته ای را نگه داری می كند كه حداكثر می تواند 255 كاراكتر باشد. Alpha
برای نگه داری اعداد صحیح مثبت ومنفی بكار می رود .حد اكثر می تواند دارای 15 رقم باشد. Number
برای نگه داری اعداد صحیح مثبت با طول كوتاه بكار می رود . به دو بایت از حافظه نیاز دارد و بازه این نوع فیلدها بین32768- تا32767 می باشد. Short
برای نگه داری اعداد صحیح مثبت ومنفی بكار می رود وچهار بایت از حافظه را اشغال می كند . بازه این فیلدها بین 2147483648- تا 2147483647 است . Long integer
برای نگه داری داده های رشته ای كه طول آنها بیش از 255 كاراكتر باشد بكار می رود. Memo
برای نگه داری تصاویر بكار می رود .این نوع فیلد می تواند انواع تصاویر bmp ،pcx ، gip ،tif ،eps را نگه داری كند . Graphic
داده های نوع Boolean را نگه داری می كند . این فیلد فقط مقادیر true یا false را می پذیرد . Logical
بخش size : در این بخش می توان اندازه فیلد را بر حسب بایت تعیین كرد.
بخش key : این بخش برای معرفی فیلدهای كلید بكار می رود . فیلد كلید ، فیلدی است كه برای تمایز ركوردها بكار می رود . به عنوان مثال ، فایل اطلاعاتی پرسنلی را در نظر بگیرید . در این فایل می توان كد پرسنل را به عنوان فیلد كلید در نظر گرفت ، زیرا هیچ دو دو پرسنلی در یك مؤسسه وجود ندارند كه دارای كد پرسنلی یكسان باشد . پس كد پرسنلی بین ركوردهای فایل پرسنلی تمایز ایجاد می كند .یكی از شرایطی كه در پاراداكس باید در نظر گرفت این است كه تمام فیلدهای كلید باید در بالای ساختار قرار گیرند . در صورت تعریف فیلد كلید در پاراداكس ، موتور بانك اطلاعاتی تضمین می كند كه تمام فیلدهای كلید منحصربفرد باشند .( بررسی می كند كه هیچ دو ركورد با فیلد كلید تكراری وارد نشود.) اگر كاربر برای فیلد كلید ، داده تكراری وارد نماید ، در این صورت یك خطا رخ می دهد .
بخش minimum value : این بخش برای تعریف كمترین مقدار فیلد به كار می رود .
بخش maxcimum value : این بخش برای تعریف بیشترین مقدار فیلد استفاده می شود .
بخش defaul -value : این بخش برای تعیین مقدار پیش فرض فیلد ، در صورتیكه مقداری برای فیلد وارد نشود ، بكار می رود .
بخش table properties :در این بخش می توان خواص ساختار جدول را انتخاب كرد .به عنوان مثال ، برای اینكه بانك اطلاعاتی كمترین و بیشترین مقدار را چك كند در كادر خواص باید وضعیت validity checks را انتخاب نمایید .
2. نام فیلدها را همراه با نوع و اندازه آنها وارد كنید. در هنگام معرفی ساختار بانك اطلاعاتی می توان با كلیدهای جهت نما بین فیلدها حركت كرد . برای معرفی فیلد كلید می توان در بخشkey كلیدspace را فشار داد یا بخش key با ماوس دبل كلیك كرد. با كلید insert می توان فیلد جدیدی را به ساختار اضافه نمود و كلیدdelete برای حذف فیلدی از ساختار جدول به كار می رود.
3. پس از معرفی ساختار بانك اطلاعاتی ، دكمه save as را كلیك كنید تا اطلاعات ساختار بانك اطلاعاتی ذخیره شود.
4. با فشردن save as صفحه ای باز می شود كه از ما مسیری برای save جدول مربوطه می خواهد و هر مسیری را كه بخواهیم می توانیم انتخاب كنیم اما اگر مسیر های شناخته شده دلفی مانندDBDEMOS را انتخاب كنیم در جاهایی كه احتیاج دادن مسیر جدول داریم كافیست مقدار DBDEMOS را تایپ كنیم ونیاز به درج كامل مسیر نیست برای این منظور باید در قسمت aliese صفحه باز شده مقدار DBDEMOS را انتخاب و نام بانك اطلاعاتی را در كادر new وارد كرده ، اكنون دكمه save را كلیك كنید.
در اینجا لازم است با بعضی از عناصر و خواصی هم كه بعد از ایجاد جدول باید با آنها كار كنیم آشنا شویم:
صفحه BDE :
این صفحه شامل عناصری است كه از BDE (موتور بانك اطلاعاتی بورلند) استفاده می كنند. 1یك API ، بزرگ را برای كار كردن با داده های جدول Paradox و dbase را فراهم می كند. عناصر موجود در این صفحه غیر ویژوال می باشند.(در زمان اجرا قابل رؤیت نیستند) بعضی از این عناصر عبارتند از:
1. TTable:با این عنصر می توان بین جداول یك بانك اطلاعاتی و برنامه كاربردی ارتباط برقرار كرد . این عنصر در صفحه BDE قرار دارد واز عناصر غیر ویژوال است . برای هر فایلی كه در برنامه كاربردی باز می شود باید یك عنصر table به فرم اضافه شود. برخی از خواص table به صورت زیر است:
خاصیت active: :این خاصیت برای فعال كردن (باز كردن) جدول به كار می رود . اگر مقدار خاصیت True باشد ، داده های جدول در هنگام طراحی نمایش داده می شوند.درغیراین صورت داده های جدول را در هنگام طراحی نمایش نمی دهد.(مقدار پیش فرض false است)
خاصیت Index field name:می توان نام فیلد شاخص فعلی را برای جدول مشخص كرد.
خاصیتIndex name :با استفاده از این خاصیت می توان نام فایل شاخص ثانویه را تعیین كرد.
در یك زمان فقط به یكی از دو خاصیت Index name وIndex field name هر عنصر می توان مقدار داد.
خاصیتtable name :با استفاده از این عنصر می توان نام جدولی را مشخص كرد كه باید به این عنصر تخصیص یابد.(به عبارت دیگر نام جدول بانك اطلاعاتی كه ایجاد می كنیم در این خاصیت قرار می گیرد)
خاصیتDatabase name :با استفاده از این خاصیت می توان نام مستعار بانك اطلاعاتی را تعیین كرد.(به عبارت دیگر همان مسیرس كه جدول را در آن save می كنیم . اگر DBDMOS بود كافیست همین را بنویسیم ودر غیراین صورت باید مسیر كامل را بنویسیم.)
خاصیتtable type : از این خاصیت می توان نوع جدول (foxpro,access,paradox و...) را تعیین كرد.
خاصیت Master fields : این خاصیت برای ایجاد ارتباط بین دو جدول به كار می رود . در این خاصیت نام فیلدی قرار می گیرد كه براساس آن باید بین دو جدول ارتباط برقرار شود. (نام فیلد مشترك بین دو جدول در این خاصیت قرار می گیرد)
قابل ذكر است كه هر عنصری در محیط دلفی دارای تعدادی رویداد است كه در اینجا فقط به چند نمونه به عنوان مثال اشاره می كنیم:
رویدادAfter cancel : این رویداد پس از لغو كردن ویرایش یك ركورد اتفاق می افتد.
رویدادBefore open : این رویداد قبل از باز شدن یك جدول اتفاق می افتد. این رویداد در فاصله زمانی كه خاصیت Active ،True می شود (جدول با متد open باز می شود)تا باز شدن جدول اتفاق می افتد.
رویداد Before post : این رویداد قبل از ذخیره تغییرات یك ركورد اتفاق می افتد.
و...
عناصر صفحهData Controls :
عناصر این صفحه ، عنصر دستكاری داده ها نام دارند .با استفاده از این عناصر می توان داده ها را نمایش داده ، پیمایش و ویرایش كرد و سپس دوباره به بانك اطلاعاتی باز گرداند. بیشتر این عناصر همانند عناصر صفحه standard یا صفحه Additional عمل می كنند. عناصر صفحه Data Controls در زمان اجرا قابل رؤیت می باشند.(از عناصر ویژوال اند) كه بعضی از آنها عبارتند از :
عناصر TDdgrid: با استفاده از این عنصر می توان جدولی برای نمایش ، پیمایش و تغییر ركوردهای بانك اطلاعاتی ایجاد كرد. به طوریكه هر فیلد بانك اطلاعاتی در یك ستون جدول و هر ركورد بانك اطلاعاتی در یك سطر جدول قرار گیرد. بعضی از خواص عنصرDBgrid عبارتنداز:
خاصیت Columns : با استفاده از این خاصیت می توان مشخص كرد چه فیلدهایی در جدول نمایش داده شوند . برای باز شدن ویراستار این خاصیت می توان محتویات خاصیت را دوبار كلیك كنید تا ویراستار تغییرات خاصیت Colomns ظاهر گردد.حال با كلید Insertمیتوان یك عنصر از نوعTcolomns (یك فیلد)را اضافه نمود. در خاصیتField Name عنصرTcolomns می توان نام فیلد را وارد كرد و در خاصیت captionمربوط به خاصیتtitle آن می توان عنوان فیلد را وارد نمود.
عنصر TDb navigator : با استفاده از این عنصر ، می توان عناصر كنترلی را ایجاد كرد كه بتوان بانك اطلاعاتی را پیمایش و ویرایش كرد. از جمله عناصر كنترلی برای پیمایش می توان عقب و جلو بردن اشاره گر را نام برد و برای ویرایش می توان حذف ، اضافه و تغییر ركوردها را مثال زد.
از جمله خواص مورد نیاز و قابل استفاده این عنصر عبارتنداز :
خاصیت show hint :این خاصیت تعیین می كند ، در هنگام قرار گرفتن ماوس بر روی عناصر ، راهنمایی كوتاهی مربوط به آن عنصر نمایش داده شود یا خیر . اگر مقدار این خاصیت True باشد ، راهنمایی كوتاه عنصر را نمایش می دهد.
خاصیت hint:این خاصیت برای تغییر راهنمایی عنصر ، به كار می رود. برای تغییر راهنمایی عنصر ، بر روی خاصیت كلیك مضاعف كنید تا ویراستارhint ظاهر شود. حال می توان راهنمایی مربوط به هر عنصر كنترلی را تغییر داد. در این قسمت حتی می توان اطلاعات را به صورت فارسی تایپ كنید.
خاصیت visible buttons : با این خاصیت می توان كل راهنمایی كوتاهی را مشخص كرد كه برای عناصر كنترلی نمایش داده شود.
عنصرTDbtext : این عنصر، همانند عنصرlabel صفحه استاندارد است با این تفاوت كه برای فیلدهای جدول به كار می رود .
عنصرTDbedit : با استفاده از این عنصر ، می توان داده های ركورد فعلی را ویرایش كرد.با هر عنصر TDbedit می توان داده های یك فیلد را ویرایش كرد.
عنصر TDbmemo :با استفاده از این عنصر می توان فیلدهای memo ركورد فعلی را ویرایش نمود.
عنصر TDbimage : این عنصر برای نمایش نماد های گرافیكی وBitmap های ركورد جاری جدول به كار می رود.این عنصر همانند Timage صفحه استاندارد است با این تفاوت كه برای فیلدهای بانك اطلاعاتی به كار می رود.
و...
عناصر DBtext,DBedit,dbmemo و... همانند عناصر label,edit,memo و... می باشند. با این تفاوت كه عناصر DBtext و... بر روی فیلدهای بانك اطلاعاتی عمل می كنند. برای این عناصر فقط خاصیت Data Fields را بحث می كنیم.
خاصیت Data Fields :با استفاده از این خاصیت می توان نام فیلدی را برای نمایش ، ویرایش و... مشخص كرد. نام فیلدی كه باید نمایش داده شود یا ویرایش شود در این خاصیت قرار می گیرد.
عناصر صفحه DATA ACCESS :
با استفاده از عناصر این صفحه می توان به بانك اطلاعاتی دسترسی داشت. عناصر این صفحه مجموعه داده ها را فعال می كنند تا بتوانید با آنها كار كنید. عناصر این صفحه عبارتنداز:
Tsata access : با ستفاده از این عنصر می توان بین عناصر table یا query و عناصرData wore ارتباط برقرار كرد. از عناصر غیرویژوال است.
Tclient data set : یك مجموعه داده ها را پیاده سازی می كند كه داده هایش را در حافظه ذخیره می نماید
Tdata set provider: این عنصر،داده ها را در داخل بسته ها(packets) رمز گذاری كرده برای client می فرستد.
تغییر ساختار بانك اطلاعاتی:
بعد از ایجاد ساختار بانك اطلاعاتی باید بتوانید آن ساختار را تغییر دهید ، زیرا اگر دوباره آن ساختار را ایجاد نمایید تمام اطلاعات بانك اطلاعاتی از بین می رود . مراحل تغییر ساختار بانك اطلاعاتی موجود به صورت زیر است:
1. گزینه TOOLS/DATABASE DESKTOP را انتخاب كنید.
2. گزینه File/Open/Table را در صفحه creat paradox table انتخاب كنید.
3. نام بانك اطلاعاتی را كه باید ساختار آن تغییر یابد وارد كرده ، دكمه OK را كلیك كنید.
4. اگر گزینه Table/Restructure را انتخاب كنید ساختار جدول نمایش داده می شود كه می توانید آن را تغییر دهید و ذخیره كنید.
باز كردن جدول:
برای به كار گیری جدول باید آن را باز كرد وبرای باز كردن جدول از متد Open استفاده می شود كه كاربرد این متد به صورت زیر است :
OPEN . نام عنصر جدول
به عنوان مثال برای باز كردن جدول باید به صورت زیر عمل كرد :
Table1.database name :='DBDEMOS';
; "نام جدول " Table1.tablename:=
Table1.open;
بستن فایل:
برای جلوگیری از تخریب داده های جدول ، هنگامی كه كار با جدول پایان یافت باید آن را ببندیم . برای بستن جدول از متد close به صورت زیر استفاده می شود :
Close; . نام عنصر جدول
مراجعه به فیلد جدول :
به سادگی می توان به هر فیلد جدول مراجعه نمود كه از روشهای مختلف استفاده می شود . اما روش 1 كاربرد بیشتری دارد :
] ' نام فیلد [' نام عنصر جدول: روش 1
[' نام فیلد ']fieldvalues . نام عنصر جدول:روش 2
.valuse (شماره فیلد )fields .نام عنصر جدول: روش 3
. نوع فیلد as (' نام فیلد ') fieldByName . نام عنصر جدید:روش4
متدهای پیمایش و ویرایش ركورد های جدول :
متد next : این متد ،اشاره گر جدول را به ركورد بعدی منتقل می كند و به صورت زیر استفاده می شود :
.next نام عنصر
متد prior : با استفاده از این متد می توان اشاره گر جدول را به ركورد قبلی جدول انتقال داد.
. prior نام عنصر
متد first : این متد ، اشاره گر را به اولین ركورد جدول انتقال می دهد و به صورت زیر به كار می رود:
.first نام عنصر
متدlast : با استفاده از این متد می توان اشاره گر را به آخرین ركورد جدول انتقال داد و به صورت زیر استفاده می شود :
.last نام عنصر
متد delete : این متد ، برای حذف ركورد فعلی جدول به كلر می رود و به صورت زیر استفاده می شود :
.delete نام عنصر
متدinsert : با استفاده از این متد می توان یك ركورد خالی در محل فعلی اشاره گر درج كرد . كاربرد این متد به صورت زیر است :
.insert نام عنصر
متد edit : این متد برای ویرایش ركورد فعلی جدول به صورت زیر به كار می رود:
. edit نام عنصر
متد post : با استفاده از این متد می توان تغییرات انجام شده ركورد فعلی را ذخیره نمود و به صورت زیر استفاده می شود :
.post نام عنصر
متدcancel : این متد برای لغو تفییرات ركورد قعلی به كار می رود و كاربرد أن به صورت زیر است :
Cancel .نام عنصر
متد refresh: از این متد هنگامی كه چند برنامه كاربردی به یك ركورد دسترسی دارند وركورد را تغییر دادند، برای باز گرداندن مقدار ابتدایی ركورد استفاده می شود ، و به صورت زیر بكار می رود
refresh .نام عنصر
متدMoveBy : این متد اشاره گر را به اندازه n ركورد به سمت ابتدا یا انتهای جدول منتقل می كند . اگر nعدد مثبت باشد اشاره گر را به اندازه n ركورد به سمت انتهای فایل منتقل می كند ولی اگر n عددی منفی باشد ، اشاره گر را به اندازه n ركورد به بالای جدول انتقال می دهد و به صورت زیر بكار می رود :
MoveBy.نام عنصر
متدEof :با استفاده از این متد می توان تست كرد كه اشاره گر جدول به انتهای جدول رسیده است یا خیر .اگر اشاره یر جدول به انتهای جدول رسیده باشد ، این متد مقدار true ودر غیر این صورت مقدار false را بر می گرداند
Eof . نام عنصر
متد Bof : در صورتی كه اشاره گر جدول ، در انتهای آن باشد، این متد مقدار true ودر غیر این صورت مقدار false را بر می گرداند
Bof . نام عنصر
متدAppend record : این متد ركوردی را همراه با دادهای
مربوط به فیلدها،به انتهای حدول اضافه می كند و به صورت زیر بكارمیرود:
([مقدار فیلدها]). Appendrecord نام عنصر
اگر تعداد مقادیر بیش از یكی باشدبا كاما جدا می شود
متدEmpty table : این متد كلیه ركوردهای حدول را حذف می كند . جدولی كه كلیه ركوردهای آن توسط این متد حذف می شود باید باز (فعال)باشد ، یعنی خاصیت Active آن trueباشد .
Empty table . نام عنصر
متدDelete table : این متد برای حذف یك جدول به همراه ساختار آن بكار می رود،جدولی نه توسط Deletetable حذف می شود نباید باز باشد(خاصیت Active آنfalse باشد)
Deletetable. نام عنصر
With table 1 do
Begin Active :=false ; ' ; مسیر كامل داده شده'DBDEMOS DatabaseName:=
;' نام جدول' =:tabeName
; (به عنوان مثال ttparadox )' نوع جدول'=:tableType
Table.DeleteTable ; End;
متدset fields : این متد،مقادیر فیلدهای یك ركورد را تعیین می كند وبه صورت زیر بكار می رود:
([مقدار فیلد, n ... ,مقدار فیلد2 , مقدار فیلد1])set fildes.نام عنصر
به عنوان مثال برای فعال كردن جدولی به نام pay كه قبلا آنرا ایجاد كرده ایم واضافه كردن یك ركورد با مقادیر به صورت زیر عمل می كنیم:
Tabel 1.DatabaseName :='DBDEMOSE' ;
Table1.TableName:='pay.db' ;
Table.Open;
Table1.insert ;
Table.setfields(['123','Reza','Ahadi',100000,200000,'01']) ;
Table1.post ;
متدclear fields : این متد برای حذف محتویات تمام فیلدهای ركورد فعلی بكار می رود وبه صورت زیر استفاده می شود.
; clearfields. نام عنصر
به عنوان مثال دستور زیر،محتویات فیلدهای اولین ركورد را حذف می كند:
Table1.first ;
Table1.clearfields ; Table1.post ;
نتیجه:
توجه كنید كه برای تفییر در جدول ویا گرفتن اطلاعات از آن با متدها و عناصر گفته شده و روشهای مثال زده شده در بالا ابتدا باید جدول مورد نظر را باز كنید ، تغییرات مورد نظر را درآن داده،اطلاعات را saveكرده و سپس جدول را ببندید .
مفهوم DataModule :
همان گونه كه ملاحظه كردید ، ایجاد وكار با بانك اطلاعاتی در دلفی ساده است اما هنوز یك مشكل وجود دارد به عنوان مثال فرض كنید یكی از عناصر Tableیا Qurery را به فرم اضافه كرده باشید و نام جدول( در موردtables )ویا خاصیت SQL (در مورد Qurery) را تعیین كردید .سپس چند خاصیت و چند رویداد به بانك اطلاعاتی اضافه كرده در مرحله آخر باید DataSorce را به فرم اضافه كنید وارتباط آنرا با جدول یا Qurery بر قرار نمایید اگربخواهید همین جدول یا Qurery را در فرم دیگری استفاده نمایید همه این مراحل را باید برای فرم جدید نیز انجام دهید اما با استفاده از DataModule نیازی نیست .
برنامه داروهای مصرفی کلینیک :
این برنامه به منظور ذخیره اطلاعات مصرفی کلینیک شرکت دنا نوشته شده است کاربر با استفاده از این برنامه می تواند اطلاعات مصرفی داروهای روزانه ی کلینیک را در تاریخ مصرف آن داروها وارد بانک اطلاعاتی کند.
این برنامه دارای دو فرم اصلی است
1-فرم مصرفی داروهای کلینیک
2-فرم مصرفی پرسنل
با استفاده از فرم مصرفی داروهای کلینیک کاربر می تواند اطلاعات مصرفی داروها را در تاریخ مصرف آن داروها وارد کند و یا اطلاعاتی را که قبلا وارد کرده است را ویرایش و یا حذف کند.
با استفاده از فرم مصرفی پرسنل کاربر میتواند اطلاعات مصرفی پرسنل را در تاریخ مصرف آن همراه با مشخصات پرسنل وارد کند و یا اطلاعات آن را ویرایش ویا حذف کند.
لازم به ذکر است که با وارد کردن اطلاعات پرسنل مقدار داروی مصرف آن شخص به مصرفی آن داروها در آن روز به طور اتوماتیک اضافه می شود و کاربر لازم نیست با وارد کردن اطلاعات پرسنلی در یک روز خاص اطلاعات مصرفی کل در آن روز را نیز وارد کند.
با استفاده از این برنامه کاربر می تواند گزارش هایی از مصرف داروهای کل در یک روز ویا در یک محدوده زمانی تهییه کند
در صفحات بعد تصاویر مربوط به فرم های برنامه همراه با توضیحاتی درباره ی چگونگی کار کردن با این برنامه در فرم های مختلف آن آشنا می شوید.
شكل 1
فرم فوق فرم اطلاعات داروی مصرفی كلینیك می باشد
این فرم فرم اصلی برنامه بوده كه با اجرای برنامه و وارد كردن نام كاربری و كلمه عبور و كلیك كردن دكمه تایید ضاهر می شود. این فرم شامل سه منو به نامهای : پرونده & گزارشات & تنظیمات می باشد كه هر یك دارای زیر منوهایی است كه در پایین توضیح داده شده است
1- منوی پرونده : دارای زیرمنوهای زیر می باشد
وروداطلاعات مصرفی پرسنل:
با كلیك بروی این گزینه فرم مربوط به ورود اطلاعات پرسنلی نمایش داده می شود
(شكل 2 كه درصفحه بعد آورده شده است )
ویرایش اطلاعات موجودی:
با كلیك بر روی این گزینه فرم مربوط به ویرایش اطلاعات موجودی نمایش داده می شود.
(شكل 3 كه در صفحه بعد آورده شده است )
شكل 2
شكل 3
خروج:
با كلیك بر روی این دكمه می توان از برنامه خارج شد.
2- منوی گزارشات:
این منو شامل گزینه گزارش است كه دارای سه زیر منو به نامهای گزارش موجودی و گزارش مصرفی كل و گزارش مصرفی پرسنل می باشد
الف)زیر منوی گزارش موجودی :
این زیر منو خود دارای یك زیر منو به نام ’ گزارش از تاریخ ...’ می باشد كه با كلیك بر روی این گزینه فرمی ظاهر می شود(شكل 4 ) كه تاریخ ها را از ما می گیرد بعد از وارد كردن تاریخ ها با كلیك بر روی دكمه تایید فرم گزارش موجودی (شكل 5 ) نمایش داده
می شود.
شكل 4
شكل 5
ب)زیر منوی گزارش مصرفی كل :
این زیر منو خود دارای دو زیر منو می باشد كه در زیر توضیح داده شده است
1-گزارش روزانه:
با كلیك بر روی این گزینه فرمی (شكل 6 ) نمایش داده می شود كه با وارد كردن تاریخ و كلیك بر روی دكمه تایید فرم گزارش مصرفی كل در تاریخ وارد شده (شكل 7 ) نشان داده می شود.
2-گزارش از تاریخ …:
با كلیك بر روی این گزینه فرمی (شكل 4 در صفحه قبل) نمایش داده می شود كه با وارد كردن تاریخ ها و كلیك كردن بر روی دكمه تایید فرم گزارش مصرفی كل در محدوده ی تاریخ وارد شده نشان داده می شود(شكل 8 در صفحه بعد)
شكل 6
شكل 7
شكل 8
ج)زیر منوی گزارش مصرفی پرسنل :
این زیر منو خود دارای دو زیر منو می باشد كه در زیر توضیح داده شده است
1-گزارش روزانه:
با كلیك بر روی این گزینه فرمی (شكل 6 در صفحه قبل ) نمایش داده می شود كه با وارد كردن تاریخ و كلیك بر روی دكمه تایید فرم گزارش مصرفی پرسنل در تاریخ وارد شده (شكل 9 در صفحه بعد) نشان داده می شود.
2-گزارش از تاریخ …:
با كلیك بر روی این گزینه فرمی (شكل 4 درصفحات قبل) نمایش داده می شود كه با وارد كردن تاریخ ها و كلیك كردن بر روی دكمه تایید فرم گزارش مصرفی پرسنل در محدوده ی تاریخ وارد شده نشان داده می شود(شكل 10 در صفحه بعد).
شكل 9
شكل 10
3- منوی تنظیمات :
این منو دارای گزینه ای به نام ‘تغییر كلمه عبور’ می باشد كه با كلیك بر روی آن فرمی نشان داده می شود ( شكل 11 ) كه با وارد كردن نام كاربری و كلمه ورود فعلی و همچنین با وارد كردن نام كاربری وكلمه عبور جدید و كلیك كردن بر روی دكمه تایید میتوان نام كاربری وكلمه عبور را تغییر داد.
شكل 11
فرم اطلاعات داروی مصرفی كلینیك (شكل1) دارای 6 دكمه به نام های "اضافه كردن " و" حذف كردن " و" ویرایش كردن و" ركورد جدید " و" اعمال ویرایش " و" لغو ویرایش " می باشد كه در زیر توضیح داده شده است .
1- ركورد جدید:
با كلیك كردن این دكمه محتوای مقدار مصرفی را پاك كرده و برای وارد كردن مقدار جدید آماده می شود.
2- اضافه كردن:
از دكمه اضافه كردن برای ورود اطلاعات استفاده می شود برای این منظور باید ابتدا نام دارو را مشخص كرد سپس مقدار مصرفی و تاریخ روز مصرف دارو را تنظیم كرد و دكمه اضافه كردن را كلیك كرد.
3- ویرایش كردن:
از دكمه ویرایش كردن برای ویرایش اطلاعات استفاده می شود برای این منظور باید ابتدا تاریخ روزی كه اطلاعات مربوط به داروهای ان روز می خواهد ویرایش شود وارد شود سپس دكمه ویرایش را كلیك كرده با این كار اگر در روز مورد نظر دارویی مصرف شده باشد نام آن در combobox اضافه می شود.
4- اعمال ویرایش:
پس از ویرایش اطلاعات برای این كه تغییرات اعمال شده ذخیره شود باید دكمه اعمال ویرایش را كلیك می كنیم.
5-لغو ویرایش:
با استفاده از دكمه لغو ویرایش می توان از حالت ویرایش خارج شد.
6- حذف ركورد:
از این دكمه برای حذف اطلاعات مصرفی یك دارو در تاریخ مصرف ان دارو استفاده می شود برای این منظور می بایست ابتدا دكمه حذف ركورد را كلیك كنیم با این كار فرمی نشان داده می شود ( شكل 12) كه می توان با ورود اطلاعات یك دارو و تعیین تاریخ مصرف آن دارو وكلیك كردن دكمه حذف در این فرم اطلاعات مصرفی آن دارو را در تاریخ مربوطه حذف كرد.
شكل 12
فرم اطلاعات مصرفی پرسنل ( شكل 2) نیز دارای 6 دكمه است كه به طریق فوق عمل می كند.
فهرست منابع :
برنامه نویسی دلفی جعفرنژاد قمی ، رمضان عباس نژاد ، کاسترو ، الیزابت ، رضا ذوقی ، علی زارع پور


LinkBack URL
About LinkBacks




پاسخ با نقل قول


Bookmarks