PDA

View Full Version : دسترسی به اعضای فرم پدر از طیق فرم فرزند!



Hadizadeh
سه شنبه 30 مرداد 1386, 16:09 عصر
من یک ActiveX Form دارم که روش یک کلید هستش. وقتی این کلید رو می زنم یک TForm دیگه رو می سازم و نشونش می دم:


unit main;
uses form1;
.....
procedure TActiveForm1.Button1click(sender:TOBject);
begin
Form1:=TForm1.Create(self);
Form1.Show;
end;

حالا می خوام از توی این فرم دومی به آبجکت های فرم اصلی یعنی TActiveForm دسترسی داشته باشم. برای این کار می نویسم:


unit submain;
uses main;
.....
var ActiveForm1:TActiveForm1;
begin
ActiveForm1.Button1.Visible:=False;
end;

ولی این جواب نمی ده. خوب مشکل چیه؟ توجه کنید که نباید از ActiveForm1:=TActiveForm1.Create(self) استفاده کنم چون در اینصورت یک آبجکت جدید ساخته میشه در حالیکه من می خوام به همون نمونه اصلی TActiveForm1 دسترسی داشته باشم. کسی راه حلی داره؟

Hadizadeh
سه شنبه 30 مرداد 1386, 16:24 عصر
دوستان برای فهمیدن سوال من لطفا این برنامه کوچولو رو نگاه کنید. Form1 رو باز کنید و از داخل کلید تعبیه شده روی اون به فرم اصلی دسترسی پیدا کنید و بگین که چه جوری این کارو می کنید؟ ممنون

absent
سه شنبه 30 مرداد 1386, 17:27 عصر
دوست عزیز من برنامت رو داونلود کردم ولی با D2007 باز نمی شه

Hadizadeh
سه شنبه 30 مرداد 1386, 17:29 عصر
والله من با دلفی 7 نوشتم. چه پیغامی می ده؟

absent
سه شنبه 30 مرداد 1386, 17:31 عصر
بی خیال باز شد. منظورت اینه که وقتی فرم رو دینامیک می سازی دیگه بهش دسترسی نداری؟ خودت اینو چجوری تست می کنی؟

absent
سه شنبه 30 مرداد 1386, 17:32 عصر
absent_khafan@yahoo.com
من آنلاینم

Hadizadeh
سه شنبه 30 مرداد 1386, 17:41 عصر
دوستان پروژه رو که بازکردید ، Shift+F12 بزنید و فرم 1 رو باز کنید و کامنت داخل Button1 روی اون رو ببینید. اسم فرم اصلی ActiveFormX هست. حالا از داخل این روتین سعی کنید به آبجکت های ActiveFormX دسترسی داشته باشید. منتظرم تا برنامه نویس های حرفه ای رو دوباره شناسایی کنم! توجه کنید که این برنامه یک پروژه ActiveX یا Library هست و با F9 اجرا نمیشه و شما به اجرای اونهم نیاز ندارین.

Hamid.Kad
سه شنبه 30 مرداد 1386, 17:47 عصر
جناب هادیزاده دلیل خاصی داره که مستقیم به خود متغیر فرم دسترسی پیدا نمیکنید ؟
لزومی به تعریف متغیر نیست.
متاسفانه D6 دارم.باز نشد.

Hadizadeh
سه شنبه 30 مرداد 1386, 17:54 عصر
آره ، تا پروژه رو بازنکنید نمی فهمید من چی میگم! چرا با D6 باز نکرد؟ کجا گیر می ده؟

Batman
سه شنبه 30 مرداد 1386, 17:58 عصر
با سلام
جناب هادیزاده من هم با دلفی 7 نتوستم بازش کنم از کامپوننت خاصی استفاده کردید

Hadizadeh
سه شنبه 30 مرداد 1386, 17:59 عصر
نه نه! هیچی توش نیست غیر از دو تا کلید! ببینم مگه چه جوری بازش می کنید؟ و دلفی چی میگه؟

Hamid.Kad
سه شنبه 30 مرداد 1386, 18:07 عصر
باز شد.
توی یونیت ActiveFormImpl1 قبل از implementation بنویس :var A:TActiveFormFactory;

حالا بخش Initialization همین یونیت رو اصلاح کن :
A := TActiveFormFactory.Create(
ComServer,
TActiveFormControl,
TActiveFormX,
Class_ActiveFormX,
1,
'',
OLEMISC_SIMPLEFRAME or OLEMISC_ACTSLIKELABEL,
tmApartment);


حالا توی رویداد کلیک button فرم Form1 بنویس : A.Button1.Width := 300

Batman
سه شنبه 30 مرداد 1386, 18:09 عصر
هیچی بابا دلفی 7 مثل بقیه هم بازش میکنم

Hadizadeh
سه شنبه 30 مرداد 1386, 18:14 عصر
باز شد.
توی یونیت ActiveFormImpl1 قبل از implementation بنویس :var A:TActiveFormFactory;

حالا بخش Initialization همین یونیت رو اصلاح کن :
A := TActiveFormFactory.Create(
ComServer,
TActiveFormControl,
TActiveFormX,
Class_ActiveFormX,
1,
'',
OLEMISC_SIMPLEFRAME or OLEMISC_ACTSLIKELABEL,
tmApartment);


حالا توی رویداد کلیک button فرم Form1 بنویس : A.Button1.Width := 300
میشه توضیح بدی چی کار کردی؟! Factory چیه؟

Hamid.Kad
سه شنبه 30 مرداد 1386, 18:18 عصر
TActiveFormFactory همون کلاسی هست که می خواهید ازش فرم بسازید دیگه
در حقیقت متغیر A یک نگهدارنده برای کلاس TActiveFormFactory محسوب میشه
حالا آخرش درست شد یا نه ؟

Hadizadeh
سه شنبه 30 مرداد 1386, 18:19 عصر
دارم میرم که تستش کنم! خبر می دم!

Hadizadeh
سه شنبه 30 مرداد 1386, 18:22 عصر
var A:TActiveFormX;
implementation

uses unit1;

initialization
A := TActiveFormX.Create(
ComServer,
TActiveFormControl,
TActiveFormX,
Class_ActiveFormX,
1,
'',
OLEMISC_SIMPLEFRAME or OLEMISC_ACTSLIKELABEL,
tmApartment);

Comserver رو نمی شناسه! بعد می گه Too many parameters!

Hamid.Kad
سه شنبه 30 مرداد 1386, 18:26 عصر
بابا چرا کدت رو دست میزنی ؟
من اینجوری نوشتم
var A:TActiveFormFactory
تو اینجوری
var A:TActiveFormX
من اینجوری نوشتم
A := TActiveFormFactory.Create
تو اینجوری
A := TActiveFormX.Create(

Hamid.Kad
سه شنبه 30 مرداد 1386, 18:27 عصر
همون کد خودته فقط قبلش یه ...=:A اضافه شده دیگه

Hadizadeh
سه شنبه 30 مرداد 1386, 18:33 عصر
var A:TActiveFormX;
implementation
....
initialization
A:=TActiveFormX.Create(
ComServer,
TActiveFormControl,
TActiveFormX,
Class_ActiveFormX,
1,
'',
OLEMISC_SIMPLEFRAME or OLEMISC_ACTSLIKELABEL,
tmApartment);

میگه Incomplete Types: TComponent and TComServer;

Hadizadeh
سه شنبه 30 مرداد 1386, 18:36 عصر
آقا اینجا داره کم کم صبح میشه! منم دیگه چشمام داره سیاهی تاریکی می ره! فردا صبح جوابش رو بهتون میگم. مرسی

Hamid.Kad
سه شنبه 30 مرداد 1386, 18:37 عصر
گرفتی ما رو !
بابا بجای اون TActiveFormX بنویس :TActiveFormFactory

Hadizadeh
سه شنبه 30 مرداد 1386, 18:40 عصر
آره درست شد ولی حالا توی فرم 1 می زنم:
A.Button1 پیدا نمی کنه باتون 1 رو که؟!!

ghabil
سه شنبه 30 مرداد 1386, 20:56 عصر
نمیدونم چرا اینقدر پیچیدش کردین ؟ وقتی که ActiveX رو ساختی ، اولا رجیسترش کن ، بعد هم راحت TypeLibraryش رو Use کن بعد هم راحت مثل کلاسهای دیگه یک Instance ازش بساز باهاش هرجا میخوای کار کن مثلا :


Uses ActiveFormProj1_TLB;
[code]
with TActiveFormX.Create(Self) do
begin
Parent := Application.MainForm;
Button1.Visible:= True;
Show;
end;


میتونستی هم بجای with یک متغییر از نوع TActiveFormX تعریف کنی، فقط یادت باشه اینستنس رو بسازی.

Hadizadeh
سه شنبه 30 مرداد 1386, 21:03 عصر
نه آقای قابیل، ببینید مسئله اینه که تو خود ActiveX دو تا فرم داریم که می خواهیم از فرم دوم اون به توابع فرم 1 دسترسی داشته باشیم ولی مشکل اینه که وقتی یک Instance از یک activex گرفته میشه ، متغیری برای فرم 2 ساخته نمیشه که از تو فرم دوم بتونیم توسط این متغیر به آبجکت های فرم اول دسترسی داشته باشیم. مشکل اینه. یعنی تو خود activeX داریم صحبت می کنیم.

ghabil
چهارشنبه 31 مرداد 1386, 10:49 صبح
ببین نکته اینه که کام آبجکت چون Applciation نیست برای همین فرمها در اون AutoCreate نیستند و برای همین هم اون متغیر گلوبالی که توی برنامه های معمولی هست براش ساخته نمیشه ، که اگر هم خودت ازش میسازی دیگه اونوقت کام آبجکتت ThreadSafe نیست و یا باید Serializeش بکنی که کار پردردسریه یا بجای اینکه گلوبال بگیریش هرجا لازمش داری بسازیش و باهاش کار بکنی.
اگر مشکلت غیر از اینه ببخشید من درست متوجه نمیشم . اگه دقیقا بگی که از نظر سناریویی میخوای چی کار کنی شاید بهتر بتونم کمک کنم.

Hadizadeh
چهارشنبه 31 مرداد 1386, 11:01 صبح
دقیقا زدی تو خال آقای قابیل. همونطور که گفتم این پروژه Library هست و لذا فرم هاش AutoCreate نیستند. خوب حالا بذارین مسئله رو با یه مثال توضیح بدم. ببینید من در ران تایم یک نمونه از این ActiveX Form می سازمو بعد فرم اصلی برنامه رو پرنت اون قرار می دم. با این کار حالا این اکتیوفرم من توی برنامه اصلی دیده میشه. از طرفی این اکتیو فرم یک فرم دیالوگ دیگه هم داره که با فراخوانی یک متد از اکتیو فرم ، این دیالوگ نشون داده میشه. حالا من می خوام از توی این دیالوگ به آبجکت های اکتیو فرمی که در حال حاضر نمونه گیری شده و داریم می بینیمش ، دسترسی داشته باشیم. اما چه طوری؟ ببنید اگه اون فایل ضمیمه اولی رو که گفتم ، باز کنید به راحتی می فهمید که من چی میگم. حالا متوجه شدید؟

Hadizadeh
چهارشنبه 31 مرداد 1386, 11:17 صبح
آقای Hamid.kad یه جورایی به جواب نزدیک شدن ولی خوب باید مرحله آخر رو هم بگن. من با توجه به کدی که گفتین ، حالا یک متغیر گلوبال A دارم. ولی مشکل اینه که var A:TActiveFormFactory یعنی A از جنس TActiveFormFactory هست نه TActiveFormX و لذا نه تنها از داخل دیالوگ دوم بلکه از هر جای دیگه هم نمی تونم به آبجکت های داخل ActiveFormX دسترسی داشته باشم. اما استپ آخر؟

ghabil
چهارشنبه 31 مرداد 1386, 12:52 عصر
خب همراه دیالوگت Pointer اینستنس این فرم رو بفرست ، نه اینکه یک فرم جدید بسازی!!!

مثلا اینطوری :



تو دیالوگ

procedure ShowDlg(const AnActvForm: TAactiveFormX);
begin
Show;
AnActiveForm.Button1.visible := False;
end;

تو فرم اول
TdlgForm.Create(Self).ShowDlg(Self)



ببین بازم تاکید میکنم تو باید همین Instance رو پاس کنی ، نه اینکه یک فرم جدید بسازی

Hadizadeh
چهارشنبه 31 مرداد 1386, 12:58 عصر
بله! ممنونم آقای کوشا. کارت حرف نداشت. جالبه که به ذهن خودم نرسیده بود. به هر حال از همه ممنونم.

Hadizadeh
چهارشنبه 31 مرداد 1386, 12:59 عصر
ولی متد آقای Hamid.Kad هم خوب بود فقط من نفهمیدم با اون A چه باید کرد؟ اونم بدونیم بد نیست. چیزی یاد می گیریم!