ورود

View Full Version : ارسال مقدار به یک فرم



Delphi7_love
دوشنبه 03 آبان 1389, 17:28 عصر
میخوام زمان بازکردن فرم ، مثل تابع ، یک مقدار به فرم ارسال کنم چگونه امکان پذیر است؟
مثلا :


procedure tmain.chek(s:string);

که یک تابع هست به یک مقدار دریافت میکند
من میخوام به همین شکل زمان بازکردن فرم بهش یک مقدار ارسال کنم
با تشکر از دوستان

Felony
دوشنبه 03 آبان 1389, 18:27 عصر
دو راه دارید یا باید یک متغییر Public تعریف کنید و در فرم دیگه برنامتون بهش مقدار بدید که راه چندان فنی نیست یا اینکه Constructor فرم رو بازنویسی کنید ، مثلا :

کد زیر رو در قسمت Public فرم دوم قرار بدید :

Constructor Show(Str: String);

و به صورت زیر Constructor رو بازنویسی کنید :

constructor TForm2.Show(Str: String);
begin
inherited Show;
ShowMessage(Str);
end;

حالا از این پس برای فراخوانی فرم دوم باید بهش یک پارامتر رشته ای ارسال کنید ، مثلا :

Form2.Show('www.barnamenevis.org');

Delphi7_love
دوشنبه 03 آبان 1389, 20:04 عصر
با تشکر
اگه ممکنه در رابطه با constructor یه توضیح بدبد .
و اینکه اگه بخوام از showmodal استفاده کنم چطوریه؟

Felony
دوشنبه 03 آبان 1389, 21:12 عصر
با تشکر
اگه ممکنه در رابطه با constructor یه توضیح بدبد .
و اینکه اگه بخوام از showmodal استفاده کنم چطوریه؟

برای توضیح به این (http://www.delphibasics.co.uk/RTL.asp?Name=Constructor) لینک مراجعه کنید .

برای بازنویسی Constructor متد ShowModal هم به صورت زیر عمل کنید :

تعریف :
Constructor ShowModal(Str: String);

بازنویسی :

constructor TForm2.ShowModal(Str: String);
begin
ShowMessage(Str);
inherited ShowModal;
end;

vcldeveloper
سه شنبه 04 آبان 1389, 02:14 صبح
دو راه دارید یا باید یک متغییر Public تعریف کنید و در فرم دیگه برنامتون بهش مقدار بدید که راه چندان فنی نیستچرا فنی نیست؟!


و به صورت زیر Constructor رو بازنویسی کنید :


(http://www.barnamenevis.org/forum/showthread.php?t=255612#about)


constructor TForm2.Show(Str: String);
begin
inherited Show;
ShowMessage(Str);
end;این کد قراره چیکار کنه؟! یک constructor تعریف کردید هم نام یکی از متدهای کلاس TForm؛ اون وقت این consturctor تون متد Show کلاس والد خودش رو فراخوانی میکنه؟!!! مگه وقتی کد constructor در حال اجرا هست، هنوز شی مربوطه ساخته شده که شما متد Show اش را فراخوانی کردید؟! الان اگر کسی بخواد با همچین constructor ایی شی ایی از کلاس TForm2 بسازه، و کدی مثل این بنویسه:

MyForm := TForm2.Show('Test');انتظار دارید غیر از Access Violation چه نتیجه ایی بگیره؟!




من میخوام به همین شکل زمان بازکردن فرم بهش یک مقدار ارسال کنمشما باید اول مشخص کنید که منظورتون از باز کردن فرم چی هست؟ منظورتون صرفا نمایش دادن فرم هست؟ یا ایجاد آن؟ اگر منظور نمایش دادن فرم هست (مثلا همون کاری که متدهایی مثل Show یا ShowModal انجام میدند)، با توجه به اینکه قبل از نمایش فرم، فرم ایجاد شده، شما می تونید برای فرم یک property تعریف کنید، و قبل از نمایش فرم، به آن property مقدار بدید، مثلا:


type
TForm2 = class(TForm)
private
FMyProp : Integer;
public
property MyProp : Integer read FMyProp write FMyProp;
end;

Form2.MyProp := 2;
Form2.Show;اگر میخواید مقدار به صورت پارامتر به تابع ارسال بشه، می تونید یک متد برای کلاس فرم مورد نظرتون تعریف کنید، که پارامتر مربوطه رو میگیره، و سپس فرم را نمایش میده:


type
TForm2 = class(TForm)
private
FMyProp : Integer;
public
procedure ShowMyForm(MyProp: Integer);
end;

var
Form2: TForm2;

implementation

{$R *.dfm}

{ TForm2 }

procedure TForm2.ShowMyForm(MyProp: Integer);
begin
FMyProp := MyProp;
Show;
end;

Form2.ShowMyForm(2);اگر میخواید پارامتر مربوطه در هنگام ایجاد فرم (نه نمایش آن) دریافت بشه، اون وقت می تونید یک constructor برای اون فرم بنویسید، و از اون برای ایجاد فرم استفاده کنید:


TForm2 = class(TForm)
private
FMyProp : Integer;
public
constructor CreateWithParam(AOwner: TComponent; MyProp: Integer);
end;

var
Form2: TForm2;

implementation

{$R *.dfm}

{ TForm2 }

constructor TForm2.CreateWithParam(AOwner: TComponent; MyProp: Integer);
begin
inherited Create(AOwner);
FMyProp := MyProp;
end;
Form2 := TForm2.CreateWithParam(nil, 2);

Felony
سه شنبه 04 آبان 1389, 04:26 صبح
چرا فنی نیست؟!
با توجه به این گفتم که دسترسی به اون متغییر از همه جا امکان پذیره .


این کد قراره چیکار کنه؟! یک constructor تعریف کردید هم نام یکی از متدهای کلاس TForm؛ اون وقت این consturctor تون متد Show کلاس والد خودش رو فراخوانی میکنه؟!!! مگه وقتی کد constructor در حال اجرا هست، هنوز شی مربوطه ساخته شده که شما متد Show اش را فراخوانی کردید؟! الان اگر کسی بخواد با همچین constructor ایی شی ایی از کلاس TForm2 بسازه، و کدی مثل این بنویسه:
کد:

MyForm := TForm2.Show('Test');
انتظار دارید غیر از Access Violation چه نتیجه ایی بگیره؟!
والا علی اقا من اولش داشتم همون راه آخر شما رو پیشنهاد میدادم ، یعنی همون نوشتن Constructor برای ایجاد فرم ، بعد پیش خودم گفتم حتما فرم تو برنامه ایشون هست و فقط میخوان بهش پارامتر ارسال کنن که گفتن در زمان باز شدن فرم ... وگرنه معلومه که در شرایطی که شما گفتی Access Violation میگیره .

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

متشکر .

vcldeveloper
سه شنبه 04 آبان 1389, 11:37 صبح
با توجه به این گفتم که دسترسی به اون متغییر از همه جا امکان پذیره .
property یک متغیر یا یک فیلد نیست؛ پیاده سازی آن از دید دیگران مخفی هست، و اگر هم نیازی به اعمال مدیریت داشته باشه، از طریق getter و setter اش این کار صورت میگیره.
در مورد سوال ایشون هم، اگر قرار باشه از property استفاده بشه، باید دسترسی بهش وجود داشته باشه، چون ایشون میخواد یک مقدار به کلاس مربوطه ارسال کنه، پس property باید قابل دسترس باشه که مقدار رو دریافت کنه. الان اگر شما برای یک متد پارامتر هم تعریف کنید، باز مقدار اون پارامتر توسط کد فراخوان متد تعیین میشه، یعنی همچنان امکان تغییر اون مقدار برای هر کدی که اون متد رو فراخوانی میکنه، وجود داره.




در آخر من خودم تا به حال از این راه استفاده نکرده بودم و دیروز به عنوان تست این کا رو انجام دادم ، در کل آیا نوشتن Constructor به اون شکل به جز ایرادی که گفتید ممکنه مشکل دیگه ای پیش بیاره ؟ چرا ؟ اگر صرفا نیاز به نمایش فرم همراه با یه پارامتر باشه آیا اون کد مشکلی داره ؟
مشکل اون کد در constructor بودنش هست. constructor همانطور که از اسمش پیدا ست، برای ساخت اشیاء از یک کلاس استفاده میشه، و یک متد ویژه هست. اون constructor شما اصلا متد Create کلاس والد رو فراخوانی نمیکنه، یعنی اصلا شی ایی نمی سازه. در واقع شما از یک consturctor به عنوان یک متد معمولی استفاده کردید.

Felony
سه شنبه 04 آبان 1389, 11:48 صبح
مشکل اون کد در constructor بودنش هست. constructor همانطور که از اسمش پیدا ست، برای ساخت اشیاء از یک کلاس استفاده میشه، و یک متد ویژه هست. اون constructor شما اصلا متد Create کلاس والد رو فراخوانی نمیکنه، یعنی اصلا شی ایی نمی سازه. در واقع شما از یک consturctor به عنوان یک متد معمولی استفاده کردید.

درسته منم از همین تعجب کردم ، گفتم که تا به حال Constructor رو اینجوری ننوشته بودم ، از دیروز هم ذهن منو مشغول کرده ، الان اون کد درست کار میکنه ولی از لحاظ فنی با توجه به دانسته های خودم و چیزایی که شما گفتید مشکل داره ، حالا اگر بخوایم همون متد Show رو تغییر بدیم تا برای صدا زدنش نیاز به ارسال پارامتر باشه چی کار باید کرد ؟

Delphi7_love
سه شنبه 04 آبان 1389, 12:16 عصر
شما باید اول مشخص کنید که منظورتون از باز کردن فرم چی هست؟ منظورتون صرفا نمایش دادن فرم هست؟ یا ایجاد آن؟
فرم قبلا ایجاد شده است
من از این روش برای مدیریت فرم میخوام استفاده کنم
زمانی که فرم رو بازم میکنم مثلا اگر مقدار 1 فرستاده شد یعنی فرم رو برای ثبت اطلاعات جدید باز کردیم ، اگر 2 فرستاده شد میخوایم اطلاعات رو ویرایش کنیم ، اگر 3 بود ....

البته اگر روش بهتری هست ممنون میشم راهنمایی نمایید.

vcldeveloper
سه شنبه 04 آبان 1389, 13:05 عصر
حالا اگر بخوایم همون متد Show رو تغییر بدیم تا برای صدا زدنش نیاز به ارسال پارامتر باشه چی کار باید کرد ؟ شما متد Show رو تغییر نمیدید، چون این متد در داخل TForm تعریف شده، و Virtual هم نیست. شما باید یک متد جدید در کلاس تون تعریف کنید که در داخل خودش اون متد Show رو فراخوانی کنه. این میشه همون کاری که متد ShowMyForm در کد پست شماره 5 انجام میده. اگر اصرار دارید که حتما اسمش Show باشه، باید به همون روش ShowMyForm عمل کنید، فقط اسمش را بزارید Show و البته متدش را به صورت overload تعریف کنید، وگرنه متد Show اصلی رو hide میکنه!


من از این روش برای مدیریت فرم میخوام استفاده کنم
زمانی که فرم رو بازم میکنم مثلا اگر مقدار 1 فرستاده شد یعنی فرم رو برای ثبت اطلاعات جدید باز کردیم ، اگر 2 فرستاده شد میخوایم اطلاعات رو ویرایش کنیم ، اگر 3 بود ....پارامترتون رو به صورت enum تعریف کنید، تا مفهوم هر کدوم از اون مقادیر مشخص باشه. اون وقت هر دو حالت استفاده از property و استفاده از متد براش تعریف کنید:

type
TMyFormType = (mftEdit, mftInsert);

TForm2 = class(TForm)
private
FFormType : TMyFormType;
procedure SetFormType(Value: TMyFormType);
public
constructor Create(AOwner: TComponent); override;
procedure Show(AFormType: TMyFormType); overload;
property FormType: TMyFormType read FFormType write SetFormType;
end;

var
Form2: TForm2;

implementation

{$R *.dfm}

constructor TForm2.Create(AOwner: TComponent);
begin
inherited;
/// Set default form type
FFormType := mftEdit;
end;

procedure TForm2.SetFormType(Value: TMyFormType);
begin
if Value = FFormType then
Exit;

FFormType := Value;
case FFormType of
mftEdit:
begin
{ TODO : Add code to prepare form for editing.}
end;

mftInsert:
begin
{ TODO : Add code to prepare form for inserting.}
end;
end;
end;

procedure TForm2.Show(AFormType: TMyFormType);
begin
FormType := AFormType;
Show;
end;


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

Form2.Show(mftEdit);

Felony
سه شنبه 04 آبان 1389, 14:20 عصر
شما متد Show رو تغییر نمیدید، چون این متد در داخل TForm تعریف شده، و Virtual هم نیست. شما باید یک متد جدید در کلاس تون تعریف کنید که در داخل خودش اون متد Show رو فراخوانی کنه. این میشه همون کاری که متد ShowMyForm در کد پست شماره 5 انجام میده. اگر اصرار دارید که حتما اسمش Show باشه، باید به همون روش ShowMyForm عمل کنید، فقط اسمش را بزارید Show و البته متدش را به صورت overload تعریف کنید، وگرنه متد Show اصلی رو hide میکنه!
:لبخند: عجب اشتباه مزحکی بود ، ممنون علی جان الان که بهش فکر کردم فهمیدم قضیه از چه قرار بوده .