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;
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.