PDA

View Full Version : سوال: یه مشکل عجیب در delphi berlin



Delphi Coder
سه شنبه 24 اسفند 1395, 00:52 صبح
این کدها وقتی با دلفی 7 کمپایل میشن کار میکنند اما با دلفی برلین exception میدن که مربول به GlobalSize هست. محیط تست من ویندوز 7 64 بیتی هست.

procedure TForm1.Button1Click(Sender: TObject);
var
b: integer;
Hnd: Cardinal;
begin
Hnd := Clipboard.GetAsHandle(ClipFormatInd);
b := GlobalSize(Hnd);
if b <> 0 then
Caption := 'Clipboard: '+ IntToStr(b) + ' bytes'
else Caption := 'Clipboard: <empty>';
end;

procedure TForm1.Button2Click(Sender: TObject);
var
b: integer;
begin
b := GlobalSize(0);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
ClipFormatInd := RegisterClipboardFormat('Test Proj Berlin');
end;
من هر چر هم کدهای اسمبلی رو trace کردم چیز خاصی ندیدم یعنی چیز خاصی نبود که ببینم یه application خالی و یه فراخوانی API از کرنل 32 هست که هر دو انجام میدن اونیکی همه چی درست کار میکنه اینیکی error میده. ظاهرا زمانی که کلیپ بورد خالی هست globalsize کار نمیکنه!!!؟؟؟
با این اوصاف حالا اگر بخوایم سایز clipboard رو در دلفی برلین بدست بیاریم چیکار باید بکنیم.

Mahmood_M
جمعه 27 اسفند 1395, 11:50 صبح
پیغامی که نمایش داده میشه یک First Chance Exception هستش
این نوع خطا معمولا به معنی مشکل درون کد نیست، اگر برنامه رو خارج از محیط دلفی اجرا کنید احتمالا خطایی ظاهر نمیشه
اگر خطا از کد نوشته شده بود برنامه روی همون خط متوقف میشد اما تابع مقدارش رو برگشت میده و برنامه هم به کارش ادامه میده
حتی اگر کد رو درون Try ... Except هم بنویسید، بعد از اجرای تابع برنامه به قسمت Except نمیره
این نوع خطا یک جور اعلان هستش به برنامه نویس که بدونه یک خطای داخلی رخ داده و Handle شده
وقتی درون برنامه یک تابع یا متد خارجی رو Call می کنید، مثل توابع API ، درون اون توابع ممکنه خطایی رخ بده که از دسترس شما خارج هستش، First Chance Exception امکانی هست که در Debugger گذاشته شده تا برنامه نویس بدونه که خطایی رخ داده اما توسط همون متد خارجی Handle شده
مشکلی که این خطا رو هم درون تابع API بالا به وجود آورده نبود Data در ClipBoard و درواقع نامعتبر بودن مقدار متغیر Hnd به عنوان Handle هستش
مثلا اگر به جای Format ایجاد شده از فرمت CF_TEXT استفاده کنید و یک متن رو کپی کنید، می بینید که همون خطا هم ظاهر نمیشه
به هر حال، اون خطا به معنی وجود مشکل نیست و می تونید اون رو نادیده بگیرید

Delphi Coder
جمعه 27 اسفند 1395, 14:52 عصر
تجربه به من نشون داده که خطای access violation رو اصلا نباید سرسری گرفت ولی به نظر فرمایش شما صحیح هست چون داخل except نمیره و ظاهرا با نادیده گرفتنش برنامه در اصل درست کار میکنه و مشکل هم فقط زمان debug خودشو نشون میده. اما هنوز این نکته که چرا تو دلفی 7 این اتفاق نمی افته سوال برانگیز هست.

Mahmood_M
جمعه 27 اسفند 1395, 17:38 عصر
اما هنوز این نکته که چرا تو دلفی 7 این اتفاق نمی افته سوال برانگیز هست
نحوه برخورد با First Chance Exception توسط Debugger مشخص میشه و یکی از امکانات Debugger هستش
می تونید تنظیمات Debugger رو تغییر بدید که این پیام رو نمایش نده
در حال حاضر دلفی 7 ندارم اما ممکنه این امکان در Debugger دلفی 7 به صورت پیشفرض غیر فعال باشه که پیغام نمایش داده نمیشه

تجربه به من نشون داده که خطای access violation رو اصلا نباید سرسری گرفت
پیغام AV اگر به خاطر کد برنامه شما نمایش داده شده باشه، باید حتما دلیلش رو پیدا کنید و مشکل رو رفع کنید اما همونطور که گفتم این پیغام از کد برنامه شما نیست و به صورت داخلی در تایع GlobalSize اتفاق می افته و البته Handle شده
برای درک بهتر کد زیر رو درنظر بگیرید :

function ConvertStrToInt(S : String) : Integer;
var
I : Integer;
begin
try
I := StrToInt(S);
except
I := 0;
end;

Result := I;
end;
این تابع یک رشته رو می گیره و سعی می کنه که اون رو به عدد تبدیل کنه، اگر خطایی رخ بده، مقدار برگشتی رو صفر می کنه
وقتی برنامه اجرا بشه و به ورودی تابع یک متن غیر عددی بدید، خطا اتفاق می افته و Debugger هم اون خطا رو نمایش میده اما خطا توسط تابع Handle شده و مشکلی در عمل وجود نداره و شاید نیازی به نمایشش هم وجود نداشته باشه
در تابع GlobalSize هم می تونید فرض کنید که اون Handle به این صورت چک میشه و اگر خطایی رخ داد خروجی صفر میشه و باز در عمل مشکلی وجود نداره، اما Debugger باز بهتون اطلاع میده که خطایی رخ داده برای اینکه بتونید بهتر عمل Debug رو انجام بدید و اتفاقاتی که افتاده رو بررسی کنید
در نهایت با خیال راحت می تونید خطا رو نادیده بگیرید