ورود

View Full Version : یک باگ عجیب در نمایش فرمها برایم پیش آمده کمکم کنید



NIUSHA_KH
شنبه 16 شهریور 1387, 12:10 عصر
سلام دوستان
من به یک مشکل عجیب برخوردم
پروژه من حدود 20 فرم داره که تا 10 روز پیش به خوبی پیش میرفت اما یک دفعه با مشکل عجیبی روبرو شدم.
از فرم 15 به بعد هر فرم جدیدی را که Show یا ShowModal میکنم با خطای زیر روبرو میشم


Project project1.exe raised exception class EAccess Violation with message 'Access Violation at address 0053AC8F in module 'project.exe'. read of address00000000 Process stopped. Use Step or Run to continue

حتی اگر فرمی را New کنم , باز هم این مشکل رو داره . اصلا ربطی هم به onshow eventفرم نداره چون بدون هیچ Eventی هم برای فرم امتحان کردم و عجیب تر آنکه در بعضی اجرا ها بدون اینکه هیچ تغییری بدم مشکلی نداره و باز میشه و یک دفعه در اجرای بعد به مشکل بر میخوره ، کسی میدونه چرا اینطور میشه ؟ آیا دلفی رو از اول نصب کنم درست میشه ؟

zman123456
شنبه 16 شهریور 1387, 12:38 عصر
پیغامهای Access Violation بخشیش مربوط به Ram دستگاه هست.ببین Ram سیستم عیبی پیدا نکرده.
پروژه رو ReBuild کن.

Hsimple11
شنبه 16 شهریور 1387, 17:02 عصر
پیغامهای Access Violation بخشیش مربوط به Ram دستگاه هست.ببین Ram سیستم عیبی پیدا نکرده.

AV علل بسیار زیادی دارد. Access Violation را در سایت جستجو کنید.

vcldeveloper
شنبه 16 شهریور 1387, 17:23 عصر
بررسی کنید که آیا فرم های شما بصورت Auto Create ساخته میشند، یعنی در فایل DPR پروژه برای هر یک از آنها عبارت:

َApplication.CreateForm(FormClass,FormName);
وجود داره؟
اگر فرم ها بصورت Auto Create ساخته نمیشند، باید قبل از نمایش آنها، آنها را Create کنید. آیا فرم ها را Create کردید؟ برای اینکه بررسی کنید آیا فرم مربوطه قبل از نمایش Create شده، می تونید از تابع Assigned استفاده کنید:

if Assigned(MyForm) then
MyForm.Show;
کد بالا فقط زمانی که فرم Create شده باشه، فرم را نمایش میده.

Mask
شنبه 16 شهریور 1387, 18:55 عصر
سلام
با اجازه اساتید
من چند بار تاحالا این مشکل برام پیش اومده بود که با بررسی های زیاد متوجه شدم از نوع برنامه دلفی که استفاده می کنمه.
آیا دلفی شما ریجیستر شده است؟؟؟

NIUSHA_KH
یک شنبه 17 شهریور 1387, 08:52 صبح
جطور باید ریجیستر کنم؟.آیا باید نسخه خاصی از دلفی رو بخرم؟

NIUSHA_KH
یک شنبه 17 شهریور 1387, 09:04 صبح
با تشکر از جواب شما
من نتوانستم( َApplication.CreateForm(FormClass,FormName) را پیدا کنم ولی با دستوری که داده بودید if Assigned(MyForm) thenچک کردم مشکلی نبود و مشخص شد که Auto Create میشه ولی مشکل اینجاست که این خطا در بعضی اجرا ها پیش میآید و در بعضی اجرا ها پیش نمیآد برای بار دوم که اجرا کردم شرط بالا برقرار نشد. چرا در بعضی از اجرا ها Auto Create میشه ولی بدون هیچ تغییری در کد در بعضی از اجراها نمیشه
کجا باید این دستور
َApplication.CreateForm(FormClass,FormName); را بنویسم ؟ آیا قبلش باید چیز خاصی را تعریف کنم؟
البته من توی منوی project->view sourceرفتم دیدم همه فرم ها حتی اون چند تا فرم مشکل دار Create میشه یعنی قبل از Application.Run; همه فرم ها Create میشه.

Cave_Man
یک شنبه 17 شهریور 1387, 11:03 صبح
ممکنه از کامپوننت هایی که در اون فرم ها استتفاده میکنید هم باشه
اگه کامپوننت های قفل شکسته استفاده میکنید احتمالا از اونها هست

Hsimple11
یک شنبه 17 شهریور 1387, 11:16 صبح
کجا باید این دستور
َApplication.CreateForm(FormClass,FormName); را بنویسم ؟ آیا قبلش باید چیز خاصی را تعریف کنم؟

اگر فرمهای شما Auto-Create می شوند خود دلفی این خط را برای ساخت فرم شما در پروژه شما اضافه میکنه. برای دیدن آن هم میتوانید با انتخاب منوی View|Units و یا کلیدهای Ctrl+F12 یونیت مربوط به پروژه خود را انتخاب و ببینید. اگر فرمی را بخواهید AutoCreate نشود باید این خط را بردارید که خودبخود موقع کامپایل ساخته نشود.

با توضیحات شما، AV به ساخت فرمها مربوط نمیشه و علت دیگری دارد. اگر مشکل ادامه داشت سورس برنامه تان را اینجا آپلود کنید.

Mask
یک شنبه 17 شهریور 1387, 16:18 عصر
جطور باید ریجیستر کنم؟.آیا باید نسخه خاصی از دلفی رو بخرم؟

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

vcldeveloper
یک شنبه 17 شهریور 1387, 17:38 عصر
ولی مشکل اینجاست که این خطا در بعضی اجرا ها پیش میآید و در بعضی اجرا ها پیش نمیآد برای بار دوم که اجرا کردم شرط بالا برقرار نشد. چرا در بعضی از اجرا ها Auto Create میشه ولی بدون هیچ تغییری در کد در بعضی از اجراها نمیشهاین یعنی، فرم شما در جایی از برنامه Free میشه. یا شما خودتون جایی در کدتان آن را Free می کنید، یا عملی انجام میدید که منجر به Free شدن آن میشه. سعی کنید وضعیت آن فرم را مرتبا در طول پروژه بررسی کنید و ببینید چه هنگامی Free میشه، مثلا یک کدی مثل این بنویسید:


procedure CheckMyFormState(MyForm: TForm);
begin
if (not Assigned(MyForm)) or (MyForm.Height < 0) then
raise Exception.Create('Your form is not assigned');
end;
و در انتهای متدهای مختلف برنامه تان، آن را فراخوانی کنید، مثلا هر رویدادی که اجرا میشه، یا هر دکمه ایی که زده میشه، در انتهای کد آن این کد را فراخوانی کنید:

CheckMyFormState(MyForm);به این ترتیب می تونید مکان احتمالی کدی که فرم در آن Free میشه را پیدا کنید. دقت کنید که در کد بالا، بررسی Height فرم فقط بخاطر اینه که مطمئن بشیم فرم Free شده، چون وقتی مثلا Form1.Free را اجرا می کنید، شی مربوط به Form1 آزاد میشه، ولی خود متغیر Form1 هنوز به یک خانه ایی در حافظه اشاره میکنه، پس در این شرایط، تابع Assigned متوجه Free شدن فرم نمیشه و مقدار True برمیگردونه، ولی اگر شی مورد نظر آزاد شده باشه، و مقدار موجود در Form1 غیر معتبر باشه، نمی تونید به خصوصیت Height دسترسی پیدا کنید، اگر این کار را بکنید، پیام خطای Access Violation نمایش داده میشه، دقیقا مثل اون اتفاقی که زمان فراخوانی متد Show پیش میاد. پس اون MyForm.Height <0 فقط برای اینه که به یکی از داده های فرم دسترسی پیدا کنیم و مطمئن بشیم که مقدار موجود در MyForm معتبر هست.

دوستان، لطفا بحث های غیرفنی و خارج از موضوع، مثل رجیستر نبودن دلفی یا کامپوننت نکنید. من در تمام این سال هایی که از دلفی استفاده کردم، نسخه دلفی و نسخه کامپوننت هایی که استفاده کردم، همه کرک شده بودند، ولی تا بحال یادم نمیاد که پیغام Access Violation ایی بخاطر رجیستر و قانونی نبودن نسخه دلفی یا کامپوننت هایی که استفاده کردم، گرفته باشم.
از نظر فنی شایع ترین علت Access Violation استفاده از شی ایی هست که وجود نداره. دوست خوبمان، آقای خورسندی (m-khorsandi) هم در توضیح Access Violation یک مقاله خوب در سایت گذاشتند که می تونید با جستجوی عبارت Access Violation آن را پیدا و سپس مطالعه کنید، پس با این اظهار نظرها کاربر بنده خدا را بیشتر سردرگم نکنید.

با تشکر

s.mostafa.rahmani
یک شنبه 28 مهر 1387, 14:02 عصر
سلام دوباره
اين كد رو

if (not Assigned(MyForm)) or (MyForm.Height < 0) then
به اين شكل تغيير دادم تا اگه فرم Assign شده باشد، دستوري اجرا شود:

if (Assigned(MyForm)) and (MyForm.Height >0) then

اما مشكل بنده:
با اين كه در OnClose فرم دوم دستور Action := caFree رو هم گذاشتم، اما باز هم در شرط فوق هم MyForm داراي مقدار است و هم Height بالاتر از صفر (587) است.
در نتيجه با اين كه فرم بسته و Free شده، شرط فوق برقراره و در ادامه برنامه دچار مشكل مي‌شوم.

؟؟؟
.

s.mostafa.rahmani
یک شنبه 28 مهر 1387, 14:15 عصر
مشكلم با اين كد حل شد:

if (Assigned(MyForm)) and (MyForm.Height > 0) and (MyForm.Showing) then

vcldeveloper
یک شنبه 28 مهر 1387, 14:56 عصر
Free کردن یک فرم باعث نمیشه که Assign مقدار False برگردونه. بلکه باید فرم علاوه بر Free شدن، Nil هم بشه، تا Assign درست عمل کنه.