PDA

View Full Version : عدم دسترسی به اجزای فرم دیگر



Hsimple11
پنج شنبه 21 شهریور 1387, 14:52 عصر
با سلام؛

فرم جستجویی دارم که با فشردن دکمه جستجو ShowModal می شود. میخواهم زمان بستن این فرم مثلا Text مربوط به Edit فرمی دیگر را تغییر دهم. اما نمیدونم چرا AV میگیرم. در واقع اصلا به فرم دیگر نمیتونم دسترسی پیدا کنم. لازم به ذکر است که فرمی که Edit در آن است هم ساخته و هم نمایش داده شده است. در دکمه بستن فرم جستجو هم می نویسم :


Search.ModalResult := mrCancel;
MyForm.Edit1.Text := 'salam';


اشکال از کجا میتواند باشد؟ هرچه فکر کردم به نتیجه نرسیدم.

Amir_Safideh
پنج شنبه 21 شهریور 1387, 16:33 عصر
اگر مقداری که به ادیت میدی ثابته بهتره از این روش استفاده کنید .

Search.ShowModal;
MyForm.Edit1.Text := 'Salam';

------------
موفق باشید .

Hsimple11
پنج شنبه 21 شهریور 1387, 23:35 عصر
اگر مقداری که به ادیت میدی ثابته بهتره از این روش استفاده کنید


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

vcldeveloper
جمعه 22 شهریور 1387, 01:28 صبح
نیاز به کد نمونه و توضیحات بیشتری هست. بطور کلی، وقتی به ModalResult مقدار میدید، فرم مربوطه بسته میشه. حالا اینکه در هنگام بسته شدن اون فرم، چه اتفاقی میافته، و چه کدی اجرا میشه، مشخص نیست.

Amir_Safideh
جمعه 22 شهریور 1387, 10:26 صبح
طبق توضیحات شما زمانی که فرمی که ShowModal شده بسته میشه میخواهید که متن یه ادیت رو عوض کنید . کدی که من نوشتم خیلی بی ربط نبود به توضیحی که شما داده بودید دوست عزیز .دستور تغییر متن ادیت دقیقا بعد از بسته شدن فرم ShowModal شده اتفاق میافته .
حالا یه سوال از شما میپرسم . FormStyle مربوط به فرمی که ادیت روی اون قرار داره MDIChild هستش یا فرم Normal ؟
اگر MDIChild دیگه نمیتونید به فرم از طریق اسم فرم دسترسی داشته باشید .
---------------
موفق باشید .

Hsimple11
جمعه 22 شهریور 1387, 14:16 عصر
ممنونم دوست گرامی ولی من در زمان بسته شدن AV میگیرم.

در مورد FormStyle هم با MDI کار نمیکنم.

Hsimple11
جمعه 22 شهریور 1387, 14:20 عصر
نیاز به کد نمونه و توضیحات بیشتری هست. بطور کلی، وقتی به ModalResult مقدار میدید، فرم مربوطه بسته میشه. حالا اینکه در هنگام بسته شدن اون فرم، چه اتفاقی میافته، و چه کدی اجرا میشه، مشخص نیست.

این نمای کلی فرمهایی است که گفتم. یک فرم که دکمه Search رویش قرار دارد و فرم جستجو با فشردن آن ShowModal می شود. و در رویداد دکمه Close فرم جستجو هم ModalResult و مقدار Edit فرمی دیگر را تغییر می دهم.

Mahmood_M
جمعه 22 شهریور 1387, 15:33 عصر
با توجه به توضیحاتی که شما نوشتید ، هیچ مشکلی نباید باشه ...
در حالت عادی مشکلی نیست ، یا فرم Free شده ، یا Edit روی فرم Free شده !! یا در کل کدی اجرا شده که دسترسی به Edit روی اون فرم رو غیر ممکن می کنه یا ... !
با توضیحاتی که شما دادید ، مشکلی وجود نخواهد داشت تا دوستان نظرشون رو در موردش بگن ، لطفا یک بار دیگه برنامتون رو چک کنید و دقیقا بگید که مثلا در رویداد OnClose مربوط به فرمی که ModalResult اون رو Set می کنید چه اتفاقی می افته ، فرمتون چطوری ساخته میشه ، خودتون Create می کنید یا AutoCreate هست یا اطلاعات دیگه ای که فکر می کنید مربوط باشه ...
به هر حال با توجه به توضیحاتی که شما دادید مشکلی نخواهد بود ، مشکل از جای دیگه ای هست ...

موفق باشید ...

Hsimple11
شنبه 23 شهریور 1387, 00:05 صبح
ممنونم. بله میدانم با این توضیحات مشکل مشخص نمی شود ولی متاسفانه برنامه حجم بالایی دارد و خودم راه حلی پیدا نکردم. میخواستم ببینم شاید دوستان نکته ای را ذکر کنند.

با تشکر....

vcldeveloper
شنبه 23 شهریور 1387, 04:51 صبح
بله میدانم با این توضیحات مشکل مشخص نمی شود ولی متاسفانه برنامه حجم بالایی دارد
در اینجور موارد Sampleایی درست کنید که همون رفتار خاص را شبیه سازی کنه. اینطوری هم خودتون متوجه میشید که آیا مشکل واقعا از همین قسمت از کد هست، یا مشکل جای دیگه ایی هست که اینجا خودش نشون میده، هم می تونید راحت آپلودش کنید تا دیگران هم بررسی کنند.

Hsimple11
شنبه 23 شهریور 1387, 14:46 عصر
در اینجور موارد Sampleایی درست کنید که همون رفتار خاص را شبیه سازی کنه. اینطوری هم خودتون متوجه میشید که آیا مشکل واقعا از همین قسمت از کد هست، یا مشکل جای دیگه ایی هست

بله ولی با یک Sample کوچک این مشکل رخ نمیدهد و مشکل از جای دیگری است که سعی میکنم پیدایش کنم.

Hsimple11
پنج شنبه 28 شهریور 1387, 16:46 عصر
با سلام؛

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

لطفا برنامه را ببینید و راهنمایی کنید (چرا پس از بستن فرم Search مقدار Edit در فرم 3 تغییری نمیکند.)

یک دنیا ممنون....

SYNDROME
پنج شنبه 28 شهریور 1387, 18:23 عصر
فرم 3 را به حالت Autocreate اضافه کنید و به جای دستورات زیر در فرم 1


Form1.SetActiveForm(TForm3);
Form2.Show;

دستورات زیر را بنویسید.


Form3.Show;
Form2.Show;

موفق باشید

Hsimple11
پنج شنبه 28 شهریور 1387, 19:54 عصر
ممنون ولی این فقط یک نمونه از برنامه ام بود و نمیتونم فرمها رو Auto-Create کنم. در واقع تمام برنامه از فرمهای شبیه 3 تشکیل می شود که همگی را باید در موقع نیاز بسازم.

vcldeveloper
جمعه 29 شهریور 1387, 02:25 صبح
علتش اینه که Form3 در زمان نمایش Form4 اصلا Assigned نشده. شما در منطق برنامه تون دچار مشکل شدید. برای اینکه متوجه مشکل بشید، کافیه مقدار


var
Form3: TForm3;

را از یونیت P_ حذف کنید و برنامه را کاپمایل کنید. در دو خط زیر در یونیت Pro خطا می گیرید:


procedure TForm4.Button1Click(Sender: TObject);
begin
ModalResult := mrCancel;
If Assigned(Form3) Then
Form3.Edit1.Text:='Salam!';
end;
خب، کامپایلر میگه این دو خط از متغیری به نام Form3 استفاده کردند که وجود نداره. درست هم میگه، ما تعریف Form3 را حذف کردیم. حالا برنامه را دوباره کامپایل کنید، برنامه بدون مشکل کامپایل میشه!! چرا کامپایل میشه و دیگه ایرادی نمیگیره؟! چون شما هیچ جای دیگه ایی از Form3 استفاده نکردید، یعنی به Form3 در هیچ جای برنامه مقداری ندادید! پس طبیعی هست که شرط Assigned(Form3) همیشه False باشه، و شرط اجرا نشه.
اما چرا اینطوری شد؟!
بخاطر متد SetActiveForm ایی که نوشتید. این متد اشاره گری از یک کلاس را میگیره و یک نمونه از اون کلاس میسازه. تا اینجاش مشکلی نیست، ولی چه متغیری به شی ساخته شده اختصاص داده میشه؟
FActiveForm! یعنی وقتی شما کد زیر را اجرا می کنید:

SetActiveForm(TForm3)
در واقع شی ساخته شده به FActiveForm اختصاص پیدا کرده، نه به Form3، از طرفی Form3 شما AutoCreate هم نیست، پس در طول اجرای برنامه مقدارش nil هست.

پس باید چگونگی نمایش فرمها در برنامه خودتان را تغییر بدید. اگر واقعا نمایش فرم ها و مدیریت فرم های باز در پروژه عمل پیچیده ایی هست، یک کلاس مجزا برای مدیریت فرم ها و نمایش آنها ایجاد کنید، و در طول اجرای برنامه یک نمونه از آن ایجاد کنید و تا پایان اجرای برنامه با همان نمونه فرم ها را مدیریت کنید (استفاده از Singlton Pattern)، همونطور که در دلفی شی Application از کلاس TApplication برای مدیریت برنامه شما فقط یک بار در طول اجرای برنامه ایجاد میشه، و کنترل برنامه را تا انتها در دست میگیره.

موفق باشید

SYNDROME
جمعه 29 شهریور 1387, 09:29 صبح
ممنون ولی این فقط یک نمونه از برنامه ام بود و نمیتونم فرمها رو Auto-Create کنم. در واقع تمام برنامه از فرمهای شبیه 3 تشکیل می شود که همگی را باید در موقع نیاز بسازم.
قبل از باز کردن فرم 3 آن را با کد نویسی ایجاد کنید تا مشکلتان حل شود(همانظور که آقای کشاورز گفت)


From3 := TForm3.Create(Owner);

موفق باشید

Hsimple11
جمعه 29 شهریور 1387, 13:41 عصر
واقعا ممنون آقای کشاورز. واقعا کامل بود؛ لطف کردید.

فکر میکنم اونقدر برنامم بزرگ نیست که نتونم خودم فرمهام رو در هر قسمت بسازم. فقط چطوری میتونم هر زمانی که یک فرم را میسازم چک کنم که فرمهای دیگر اگر ساخته شده بودند Free شوند. یا فرمهای دیگر را Close کنم و در OnClose اونا Free شون کنم؟

ولی با اینحال میشه در مورد Singlton Pattern سایت یا نمونه ای معرفی کنید. اینکه چطوری با یک Instance از کلاس فرمها تمام فرمهام رو مدیریت کنم؟ فقط یک سایت هم معرفی کنید کافیه.

باز هم واقعا ممنونم....

vcldeveloper
جمعه 29 شهریور 1387, 18:13 عصر
میشه در مورد Singleton Pattern سایت یا نمونه ای معرفی کنید. اینکه چطوری با یک Instance از کلاس فرمها تمام فرمهام رو مدیریت کنم؟ فقط یک سایت هم معرفی کنید کافیه.

توضیح درباره Singleton Pattern:
http://en.wikipedia.org/wiki/Singleton_pattern
فارسی:
http://ooa.blogfa.com/post-20.aspx

این نمونه ایی از پیاده سازی یک کلاس Singleton در دلفی هست، می تونید از همین قالب برای ایجاد کلاس های Singleton خودتون استفاده کنید و فقط بهش متدها، خصوصیات، و فیلدهای مورد نظرتان را اضافه کنید، یا ازش به عنوان یک کلاس پایه استفاده کنید و کلاس Singleton مورد نظرتان را از این کلاس پایه مشتق بگیرید:


{***********************************
Description:

Author: Ali Keshavarz
Date : 2008/09/19
***********************************}

unit MySingltonClass;

interface

uses
SysUtils, Windows;

type
TSingletonClass = class(TObject)
protected
constructor CreateInstance;
class function AccessInstance(Request: Integer): TSingletonClass;
public
constructor Create;
destructor Destroy; override;
class function Instance: TSingletonClass;
class procedure ReleaseInstance;
end;


implementation

{
******************************* TSingletonClass *******************************
}
constructor TSingletonClass.Create;
begin
inherited Create;
raise Exception.CreateFmt('Access class %s through Instance only',
[ClassName]);
end;

constructor TSingletonClass.CreateInstance;
begin
inherited Create;
end;

destructor TSingletonClass.Destroy;
begin
if AccessInstance(0) = Self then AccessInstance(2);
inherited Destroy;
end;

class function TSingletonClass.AccessInstance(Request: Integer): TSingletonClass;
const
{$WRITEABLECONST ON}
FInstance: TSingletonClass = nil;
{$WRITEABLECONST OFF}
begin
case Request of
0 : ;
1 : if not Assigned(FInstance) then
FInstance := CreateInstance;
2 : FInstance := nil;
else
raise Exception.CreateFmt('Illegal request %d in AccessInstance',
[Request]);
end;
Result := FInstance;
end;

class function TSingletonClass.Instance: TSingletonClass;
begin
Result := AccessInstance(1);
end;

class procedure TSingletonClass.ReleaseInstance;
begin
AccessInstance(0).Free;
end;

end.