ورود

View Full Version : آموزش: یک نکته ظریف دلفی



MohsenB
سه شنبه 10 اردیبهشت 1392, 09:10 صبح
با سلام


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

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

================================
برای شروع یه نکته من شروع میکنم :

همه از بلوک try ... finally ... end استفاده کردیم . یه نکته خیلی جالب که این بلوک داره اینه که حتی اگر شما دستور خروج از روال رو در داخل بلوک بدید ، کد بعد از finally تا end حتما اجرا میشه .

برای مثال به کد زیر نگاه کنید :

function MyFunc:Integer;
begin
try
Result:= 1;
Exit;
finally
Result:= 2;
end;
Result:= 3;
end;

در نگاه اول شاید به این نتیجه برسید که برگشتی این تابع 1 باشه ولی خروجی میشه 2 .!

این نکته رو تو کدهایی که وقتی به نتیجه میرسه میخواد از تابع خارج بشه در نظر داشته باشید . مثلا اگر نیازه که یک شئی قبل از خروج از تابع آزاد بشه نیاز نداره که قبل از دستور Exit اون شئی رو آزاد کنید و آزاد سازی بین finally تا end برای اینکار کافیه .

موفق باشید

MohsenB
چهارشنبه 11 اردیبهشت 1392, 12:07 عصر
سلام

صحبت از try شد گفتم نکته بعدی رو هم در همین رابطه بگم .

این دفعه از برادر بلوک قبلی یعنی try ... except ... end .

هیچ فکر کردین تفاوت این دو در نحوه عملکردشون چطوره ؟
یه مثال میزنم :
فرض کنید تابعی میخواید بنویسید که توی اون یک سری کار ها انجام میشه ، که توی اون کارها ممکنه بعضیهاشون خطا ایجاد کنن ، ولی میخواید کدتون تا آخر اجرا بشه و تمام کارها انجام بشه .
برای نمومنه به کد زیر نگاه کنید :
function MyFunc:Integer;
var i :Integer;
begin
Result:= 1;
for i := 2 to 5 do begin
try
Result:= 9 div (i - 2);
finally end;
end;
Result:= Result + 1;
end;

توضیح این تابع اینه که یه حلقه داریم که یکی از ( اولین ) دستورات درون حلقه خطا تولید میکنه .
خوب برگشتی این تابع فکر میکنید چی میشه ؟ این تابع نتنها هیچ جوابی بر نمیگردونه بلکه روند اجرای روال صدا زننده این تابع رو هم مختل میکنه .

چاره کار استفاده از try ... except ... end هست .
ببینید :
function MyFunc:Integer;
var i :Integer;
begin
Result:= 1;
for i := 2 to 5 do begin
try
Result:= 9 div (i - 2);
except end;
end;
Result:= Result + 1;
end;

تو این تابع وقتی خطایی اتفاق میفته کدهای بین except end اجرا میشه ولی روند اجرا مخطل نمیشه . یعنی بعد از اتفاق افتادن خطا برنامه از خطی که توی اون خطا اتفاق افتاده به خط(های) بین except end میره و بعد از اجرای این خط(ـوط) ، خط بعد از بلوک try اجرا میشه . حالا دیگه خط آخر روال هم اجرا میشه . و تابع 4 رو بر میگردونه .

این نکته رو هم توجه داشته باشید که اگر در محیط کد نویسی برنامه رو اجرا کردین خطا رو دیباگر براتون نشون میده . اما وقتی برنامه بصورت مستقل اجرا میشه هیچ اتفاق نا خوشایندی اتفاق نخواهد افتاد .

موفق باشید

MohsenB
جمعه 13 اردیبهشت 1392, 17:03 عصر
سلام

مطمئنن یکی از مفیدترین ابزاری که در یک نرم افزار وجود دارد ، میانبرها هستند .
در زیر لیست کوچکی از میانبرهای دلفی رو براتون به همراه توضیح قرار میدم که مطمئنن با استفاده از اونا از دلفی خیلی بیشتر لذت خواهید برد و سرعت کارتون بیشتر خواهد شد .
چندتا مورد اول خیلی پرکاربردن ، که حتما اونا رو میدونید ولی حتما ادامه رو تا آخر بخونید و استفاده کنید .

Ctrl + Space

نمایش پنجره تکمیل کد
Ctrl + Shift + Space

نمایش پنجره پارامتر های کد
Ctrl + Y

حذف کامل خط جاری
Ctrl + Click = Alt + UpArrow

رفتن به محل تعریف
/ + Ctrl

افزودن دو اسلش به اول خط برای تبدیل به توضیح
Alt + SelectByClick

انتخاب کدها بصورت بلوکی با موس
Alt + Shift + Down,Left,Right,PageUp,PageDown

انتخاب کدها بصورت بلوکی با صفحه کلید
Ctrl + Del <> Ctrl + Backspace

حذف حروف کلمات جاری تا اول/آخر
Ctrl + Enter

بازکردن فایل جاری کد در پنجره مرور ویندوز
Ctrl + K + E,F

تبدیل حروف کلمه جاری به حروف کوچک/بزرگ
Ctrl + Tab <> Ctrl + Shift + Tab

جابجایی بین فایلهای باز شده
Alt + PageUp <> Alt + PageDown

جابجایی بین برگه های فایل باز شده

موارد بیشتر (http://docwiki.embarcadero.com/RADStudio/XE4/en/Default_Keyboard_Shortcuts)

موفق باشید

MohsenB
یک شنبه 22 اردیبهشت 1392, 00:13 صبح
با سلام

در این نکته میخوام در مورد برخی ظرافتهای ساختن اشیاء صبحت کنم .

مطمئنا تا بحال شیئی رو خودتون در حالت اجرا ساختین . تابحال به چیزی که بجای AOwner مینویسید دقت کردید ؟ چی باید نوشته بشه ؟ برای چی ؟ چه کاربردی داره ؟ چه کمکی میتونه بکنه ؟ ؟ ؟

MyComponent:= TMyComponent.Create(???);

چیزی که بجای علامت سوال بالا میتونه نوشته بشه بعبارتی همون مدیر موجودیت شیئ در حافظه هست . برای مثال و به زبان ساده وقتی Application رو برای اینکار انتخاب میکنید شما دیگه نباید غصه آزادسازی اون رو بخورید و این امر خطیر میفته به گردن Application ، و وقتی Application بخواد آزاد بشه اول نظیر این اشیاء رو آزاد میکنه .

و یا اگر درون فرم نوشتید Self لازم نیست اون رو آزاد کنید و خود فرم شیئتون رو آزاد میکنه .

خوب همونطوری که میشه حدس ضد نوشتن nil یعنی آزادسازی شیئ ساخته شده به گردن هیچ موجودیت دیگری نیست و خود برنامه نویس وظیفه آزادسازی رو داره .

برای مثال اول : وقتی یه فرم درست میکنید میتونید اینطور بنویسید و آزادسازی رو بندازید گردن برنامه :
var MyForm :TForm1;

procedure TForm1.FormCreate(Sender: TObject);
begin
MyForm:= TForm.Create(Application);
MyForm.Show;
...
end;

برای مثال دوم : وقتی یک کنترل روی یک فرم درست میکنید ... :
var MyBtn :TButton;

procedure TForm1.FormCreate(Sender: TObject);
begin
MyBtn:= TButton.Create(Self);
...
end;

و همینطور برای مثال سوم : وقتی به یک کامپوننت در یک بلوک بخصوص نیاز دارید و خارج از اون دیگه نیازی به اون نیست :
var MyImage :TImage;

procedure TForm1.FormCreate(Sender: TObject);
begin
MyImage:= TImage.Create(nil);
try
...
finally
MyImage.Free;
end;
end;
تو این کد مطمئنا یادتون به نکته اول خواهد افتاد که چقدر درون این کد کارگشاست .

برای واضحتر شدن قضیه یه مثال دیگه از نمونه آخر با روش دیگه :
var MyImage :TImage;

procedure TForm1.FormCreate(Sender: TObject);
begin
MyImage:= TImage.Create(nil);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
MyImage.Free;
end;
همینطور که میبینید در موقع ساخت فرم شیئ ساخته شده و در هنگام آزادسازی فرم هم شیئ ساخته شده با کدی که برنامه نویس نوشته ازاد میشه . در واقع این کد معادل کد مثال دوم هست ، منتها کد دوم مطمئنتر و فنی تر می باشد .

موفق باشید

alidehban
شنبه 16 فروردین 1393, 15:42 عصر
درود....
یک نکته در استفاده از بلوک try ... except ... end هست که گاهی اوقات قابل استفاده ست!
شما میتونید پیغام هارو از داخل فانکشن و یا پروسیجر فرزند به پدر پاس بدید و پدر بر اساس اون تصمیم بگیره کار خاصی رو انجام بده و یا همون پیام رو مستقیم نمایش بده...
به کد زیر توجه که کنید در فانکشن فرزند یک متغیر لیبل تعریف شده ولی Create نشده و مقداری به Caption اون اختصاص داده شده ، در نتیجه Exception میخوره و میاد بیرون اما
نکته اینجاست که اگر پدری باشه که مسیج رو دریافت کنه فانکشن فرزند میتونه Raise کنه و میشه در سمت پدر تصمیم گیری برای حرکت بعدی رو انجام داد،
به کد نگاهی بیاندازید :


function TForm1.child: string;
var lbl:TLabel;
begin

try
lbl.Caption:= 'aaaaaa';
except
raise Exception.Create('MY Error Message');
end;

end;

//=================================

procedure TForm1.btn1Click(Sender: TObject);
begin

try
child;
except on E:exception do
ShowMessage(E.Message);
end;

end;