PDA

View Full Version : سوال: ایجاد یک فرم به صورت دستی ، بدون استفاده از Uses کردن فرم



hadisalahi2
یک شنبه 08 تیر 1393, 12:04 عصر
سلام بر برو بچ برنامه نویس

من همینک روی پروژه هایی که مینویسم ، با استفاده از پروسیجر زیر ، فرمی رو که میخوام رو بدون اینکه اون رو uses کنم ، از فرم اصلیم بازش میکنم.



Function TCodeComp.FormNameReturn(FormTag: Smallint; ScreenTmp: TScreen):TForm;
var i:integer;
begin
try
for i:=1 to ScreenTmp.FormCount-1 do
if Screen.Forms[i].Tag=FormTag then FormNameReturn:=Screen.Forms[i];
except FormNameReturn:=Nil end;
end;




var FormName:Tform;
begin
FormName:=CodeComp1.FormNameReturn(DBObjectModule. PublicTag,Screen);
FormName.ShowModal;
end


با این کدها نیازی ندارم که از Uses کردن استفاده کنم.
اما این حالت رو در زمانی استفاده میکنم که همه فرم ها موقع اجرای application ساخته میشن:
مثلا اینطوری :



Application.CreateForm(TPassForm, PassForm);
Application.CreateForm(TCompanyForm, CompanyForm);


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

و حالا اگه حتما باید Use بشه همه فرم ها ، چطوری با یک مت این کار رو برای ایجاد و نمایش همه فرم هام انجام بدم؟

یوسف زالی
یک شنبه 08 تیر 1393, 12:23 عصر
یک مستر فرم می سازی، نمونه ای ازش نباید ساخته شده باشه،
در اون مستر فرم کد ساخت و اجرای فرم رو می ذاری.
همه فرم هات رو از اون می گیری، در جایی که می خوای بازش کنی به جای TForm از کلاس خودش بازش می کنی.
مثال ضمیمه شده رو ببینید.

hadisalahi2
یک شنبه 08 تیر 1393, 17:33 عصر
دستت طلا یوسف جان
اما اینجا دو تا مشکل هستش
که البته شاید مشکل هم نباشه و روش کار همین باشه

یکی اینکه باید همه فرم ها رو یوز کنی

uses SampleForm1, SampleForm2

یکی هم اینکه


procedure TMainFrm.Button1Click(Sender: TObject);
begin
TSampleFrm1.Execute
end;


procedure TMainFrm.Button2Click(Sender: TObject);
begin
TSampleFrm2.Execute
end;


چطوری اسم فرم رو با Sender بفرستم به پروسیجر که فقط یک پروسیجر برای ایجاد همه فرم ها داشته باشم؟

یوسف زالی
یک شنبه 08 تیر 1393, 18:43 عصر
مورد اول اجتناب ناپذیره. چون هنوز در حافظه موجود نیست.
مورد دوم، اسم فرم رو چرا بفرستی؟ باید کلاس فرم رو execute کنی. الان هم یک پروسیجر برای همه execute ها داری.
اما اگر منظورت درون Sender متد دکمه هست، موردی که نتونه جواب بده به ذهن ندارم. مثالش رو بزن

hadisalahi2
یک شنبه 08 تیر 1393, 19:29 عصر
مورد اول اجتناب ناپذیره. چون هنوز در حافظه موجود نیست.

این به نظرت باعث کند شدن برنامه ، و یا اشغال حافظه زیادی نمیشه
مثلا 50 فرم رو در داخل یک فرم uses کنیم؟



اما اگر منظورت درون Sender متد دکمه هست، موردی که نتونه جواب بده به ذهن ندارم. مثالش رو بزن

آره دقیقا منظورم همین Sender دکمه هستش
من میخوام یک پروسیجر داشته باشم که برای همه دکمه های فرم اجرا بشه
توی اون تیکه کد اولی که خودم گذاشتم ، میام و بر اساس تکی که به فرم و دکمه معادلش اختصاص دادم ، فرم رو پیدا میکنم و باز میکنم.
حالا اینجا هم یک همچین چیزی بشه پیاده کرد که احتیاجی نباشه برای باز کردن هر فرک یک متد رو فراخوانی کرد.

نمیدونم منظورم رو رسوندم یا نه؟

حالا بعد از اینکه فرم رو ایجاد کردم و نمایش دادم ، بعد از اینکه کاربر فرم رو بست ، به نظرت کجا فرم رو free کنم؟

یوسف زالی
یک شنبه 08 تیر 1393, 23:06 عصر
نه بابا 50 تا فرم یوز چیزی نمی شه. دلیلش هم اینه که به طور همزمان همشون ساخته نشدن هنوز. در پروژه های من حداکثر و در شرایط خاص 5 تا فرم همزمان بوجود میان. معمولش 3 تاست که یکیش مین فرمه، یکیش فرمی که یوزر داره باهاش کار می کنه و یکی هم فرم مخفی برای کارهای زیرسبیلی.
ببین، من در مستر فرم خودم یه همچین چیزی دارم:

کنترل فوکوس در فارسی انگلیسی خودکار
کنترل بارکد و هات کی وارده
کنترل کلید های اینتر و اسکیپ
کنترل ریسایز فرم
کنترل لود و ذخیره پروفایل کاربری برای فرم
کنترل لوگو، گلیف دکمه ها، کپشن های استاندارد دکمه ها، رویدادهای استاندارد دکمه ها و ...
کنترل موارد خاص مثل مودال شو، قبل از نمایش، خروج، ...

دیگه تو هیچ فرمی از این کارا نمی کنم، فقط کد کارکرد اون فرم.

حالا، اگه می خوای که تو دکمه هات کدی ننویسی و در فرم مستر اونها رو کنترل کنی، راه داره، یه چیزی شبیه به کد مثال ضمیمه می شه؛
نیازی نیست فرم رو فری کنید، خود رویدادی که براتون فرم می سازه، بعد از اتمام کارکرد و مودال، فرم رو از بین می بره. کدش رو ببینید.
در کد جدید مثلا فقط اسم دکمه رو BtnCancel بگذارید بدون این که هیچ کدی توش بنویسید با زدنش فرمتون بسته بشه.
یک آینده نگری هایی هم باید از الان به کار ببرید از جمله این که اگر دکمه ای اسمش BtnCancel بود و توش کد داشت، کاری به کارش نداشته باشید، که این مورد هم کنترل شده.

hadisalahi2
دوشنبه 09 تیر 1393, 09:59 صبح
یوسف جان منظور من رو اشتباه متوجه شدی
منظورم من اینی نبود که شرح دادی.

حالا این موضوع فعلا باشه تا اول خود پروسیجر Execute رو حل کنیم بعد بریم سراغ بعدی.

در این نمونه که فرستادی ، من Master Form رو به فرم اصلی اضافه میکنم
اما متد Execute در داخل فرم اولم قابل دسترسی نیست.

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

یوسف زالی
دوشنبه 09 تیر 1393, 10:35 صبح
TForm2 = class(TForm)

گفتم که باید از مستر بگیری نه از فرم

hadisalahi2
دوشنبه 09 تیر 1393, 17:24 عصر
داداش یوسف من یک چیزی رو این وسط نمی گیرم
الان شما اومدی از یک فرم واسط به نام Master Form اسفاده کردی

و ایجاد فرم رو توی اون انجام میدی
به نظرت ، وقتی دیگه یونیت فرم مقصد رو Uses میکنیم
چه نیازی به فرم واسط هستش؟

الان من این دو خط کد رو در فرم Splash خودم و در رویداد OnShow نوشتم


Application.CreateForm(TMainForm,MainForm);
MainForm.ShowModal;


نتیجه دقیقا همونه که تو با فرم واسط انجام دادی

همین جا رو نمیگرم واسه چیه؟
پلیز هلپ می :لبخند:

یوسف زالی
دوشنبه 09 تیر 1393, 20:41 عصر
ببین مساله فاکتور گیری از کدهای مشترک در تمام فرمهاست. سه چهار خطش هم مربوط می شه به ساخت فرم و فری کردنش.
اومدیم خواستی بعد از مدتی روی تک تک فرمهات یه دکمه کوچولو واسه هلپ بذاری، 60 تا فرم هم داری، 60 تا فرم رو اصلاح می کنی؟
در این روش فقط یک فرم رو اصلاح می کنی.
برای نمونه یک دکمه روی فرم مستر بگذار می بینی که اتومات هرکی ازش مشتق شده دکمه ها رو داره.

hadisalahi2
سه شنبه 10 تیر 1393, 10:12 صبح
پس باید حتما فرمی که میخوایم ازش Create کنیم رو Uses کنیم
یعنی میشه گفت یک جوری جواب سوال من نبود :لبخند:

واسه این چیزی که گفتی ، واقعا عالیه و به نظرم خیلی کار آدم رو راه میندازه
اما در بعضی موارد ایجاد اشکال میکنه
مثلا اگه من یک Status Bar بزارم روی مستر فرم

این توی همه فرم ها نمایش داده میشه
حالا اگه بخوام یکی از فرم هام یک StatusBar دیگه داشته باشه ، دو تا روی هم میندازه و یک کم ضایع میشه

حالا یک مسئله دیگه
اگه روی مستر فرم مثلا یک دکمه بزاریم برای help
وقتی کاربر روی اون دکمه مثلا توی فرم ششم کلیک کرد، چطوری باید بفهمیم توی کدوم فرم هستیم تا مثلا راهنمای معادل اون فرم رو به کاربر نشون بدیم؟

یوسف زالی
سه شنبه 10 تیر 1393, 10:29 صبح
مورد اول رو نمی ذارن رو مستر فرم، می تونی چندین نوع مستر فرم داشته باشی.
برای فهمیدن این که کدوم فرم دکمه رو کلیک کرده از Self استفاده کن. می فهمه.

hadisalahi2
سه شنبه 10 تیر 1393, 11:03 صبح
مورد اول رو نمی ذارن رو مستر فرم

من الان روی همه فرم هام StatusBar دارم که روش یک Progress Bar هستش
حالا اگه بخوام با مستر فرم ایجاد کنم ، قائدتا باید توی اون فرم باشه.
حالا ممکنه روی StatusBar بعضی از فرم ها چیزهایی دیگه هم باشه



می تونی چندین نوع مستر فرم داشته باشی
این راه حل مناسبیه



برای فهمیدن این که کدوم فرم دکمه رو کلیک کرده از Self استفاده کن. می فهمه.
این رو خدا رو شکر دلفی فهمید
اونقد هم که فکر میکردم خنگ نیست :لبخند:

حالا یک چیز دیگه رو نمیفهمه
چطوری حالیش کنم

ببین الان من یک دکمه گذاشتم روی مستر فرم
مثلا اینطوری :


ShowMessage(self.Caption);


توی اون فرم که بازه کپشن رو نشون میده.
حالا چطوری به متدها و کنترل های اون فرمی که الان بازه دسترسی پیدا کنم
باید Self رو با FindComponent ترکیب کنم؟

اگه آره ، چطوری؟
پلیز هلپ می :بوس:

hadisalahi2
سه شنبه 10 تیر 1393, 11:07 صبح
وگرفتم داش یوسف
اینطوریه دیگه درسته؟


ShowMessage((self.FindComponent('BtnHelp') as TButton).name);


البته اگه راههای بهتر یا دیگه ای داره
بازم پلیز هلپ می

یوسف زالی
سه شنبه 10 تیر 1393, 11:17 صبح
معمولا کارهای متفرقه و مختص خود فرم رو در خود فرم انجام می دن نه در مستر. اما اگر اصرار داری آره راهش همینه.

hadisalahi2
سه شنبه 10 تیر 1393, 11:32 صبح
اصرار که ندارم
ولی میخواستم راهش رو بدونم تا اگه لازم شد ، سریع بتونم اقدامات لازم رو انجام بدم :لبخند:

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

پیشنهاد میکنم ، همین رو به صورت یک نمونه ، کد یا یک مقاله ، یا هر چی که خودت صلاح میدونی بزاری تا همه ازش استفاده ببرند.
شاید جواب سوال من این موضوع نبود
اما من که خداییش خیلی حال کردم از این چیزی که یاد گرفتم

بی نهایت سپاسگذااااااااااااااااااا ااااااااااااااااااارم :بوس: