PDA

View Full Version : دسترسي به Procedure بر اساس نام آن



shervin farzin
شنبه 12 مرداد 1387, 03:02 صبح
سلام
آقا ميخواستم بپرسم چطور ميشه به procedure ها بر اساس اسمشون دسترسي داشت .
مثلا دو تا procedure با نامهاي مشابه pro1 و pro2 داريم ، حالا مي خوام اگه مثلا كاربر مقدار 1 رو وارد كرد pro1 و اگه 2 وارد كرد pro2 اجراء بشه . ( در ضمن واضحه كه نمي خوام از if استفاده كنم . :کف: ) . دنبال يه متد شبيه FindComponenet مي گردم .
ممنون

SYNDROME
شنبه 12 مرداد 1387, 06:48 صبح
شما نمی توانید دو Procedure به نامهای مشابه در یک Unit داشته باشید مگر اینکه این توابع در تعداد و یا نوع پارامترها با هم فرق داشته باشند و بتوانید آنها را Overload کنید.
موفق باشید

shervin farzin
شنبه 12 مرداد 1387, 10:29 صبح
سلام
نه آقا منظورم اين نبود كه دو تا procedure با يك نام داشته باشم . اسمهاش همونطور كه نوشته بودم مثلا pro1 و pro2 باشه . يعني تفاوت نامشون در يك عدد آخر نام هست . دنبال يه كاري شبيه اينم :


متد نامعلوم ( inttostr(1) + 'Pro' )

vcldeveloper
شنبه 12 مرداد 1387, 11:41 صبح
ارزش این کار در چی هست؟! اگر قراره کاربر مقداری را وارد کنه و بر اساس آن یک Procedure اجرا بشه، و میشه با یک if ساده این کار را کرد، چه نیازی به این کار هست؟!


دنبال يه متد شبيه FindComponenet مي گردم .
FindComponent توی یک حلقه نام تمام کامپوننت هایی که متعلق به کامپوننت مورد نظر شما هستند را چک میکنه، اینطور نیست که تصور کنید در آن از حلقه یا if استفاده نشده!
در ضمن، وضعیت کلاس ها و اجزائشون در دلفی با functionها و procedureهای معمولی فرق میکنه، چون این کلاس ها می تونند اطلاعات RTTI با خودشون داشته باشند که از طریق آن میشه به برخی مشخصات و ویژگی های آنها دسترسی داشت.
در هر حال، من هیچ توجیهی برای کاری که شما می خواید انجام بدید، به ذهنم نمیرسه.

B-Vedadian
شنبه 12 مرداد 1387, 12:45 عصر
یه راه ساده برای این، داشتن یه آرایه از رویه‏هاست.


procs: array[0..1] of procedure(x: Integer);موقع استفاده


procs[idx](123);

shervin farzin
شنبه 12 مرداد 1387, 12:59 عصر
در ضمن، وضعیت کلاس ها و اجزائشون در دلفی با functionها و procedureهای معمولی فرق میکنه، چون این کلاس ها می تونند اطلاعات RTTI با خودشون داشته باشند که از طریق آن میشه به برخی مشخصات و ویژگی های آنها دسترسی داشت.

خوب علي آقا جان من هم براي استفاده كردن از همين RTTI هاست كه علاقه دارم يه همچين روالي رو پيدا كنم . در ضمن من به مشكلي بر نخوردم كه حتما با اين كار حل بشه ، به فرمايش خودتون ميشه خيلي راحت با يه IF سر و ته قضيه رو هم آورد ولي برام جالبه كه بدونم چطور ميشه Mehtod ها رو در دلفي با نامشون صدا كنيم .
از توجه شما ممنونم .

shervin farzin
شنبه 12 مرداد 1387, 13:03 عصر
آقاي B-Vedadian دوست خوبم ، راه حل شما بسيار عاليه ولي يه نكته كوچيك داره و اون اينه كه
من مجبورم داخل آرايه رو با Procedure هاي معمولي پر كنم در حالي كه شايد نياز داشته باشم به يه ليست از procedure هايي كه مثلا به صورت متد در بخش Public تعريف شده باشند دسترسي داشته باشم .
ممنون از توجهتون .

B-Vedadian
شنبه 12 مرداد 1387, 16:25 عصر
x:array[0..1] of procedure(Sender: TObject) of object;

vcldeveloper
شنبه 12 مرداد 1387, 16:32 عصر
من هم براي استفاده كردن از همين RTTI هاست كه علاقه دارم يه همچين روالي رو پيدا كنم . RTTI برای استفاده داخلی در دلفی طراحی شده، به همین دلیل هم Document شده نیست. شما نمی تونید درباره اش یک منبع رسمی پیدا کنید. از طرفی، چون Document شده نیست، هیچ تضمینی وجود نداره که توابع آن و ساختار داده های آن در همه نسخه های دلفی یکسان باشه! البته کاربردش هم برای برنامه نویسان بسیار محدود هست و به موارد خاصی مربوط میشه.
در هر حال، اگر دنبال Delphi RTTI بگردید، چند تا مقاله درباره اش پیدا می کنید. فکر کنم بهترینش همون مقاله Brain Long باشه.

shervin farzin
یک شنبه 13 مرداد 1387, 12:23 عصر
سلام مجدد .
اول از دوستانم كه به سوالم توجه كردن تشكر ميكنم . من يه راه حل خوب براي اين مشكل توي سايت Delphi.About پيدا كردم كه با يه كمي تغييرات هموني ميشه كه ميخوام .
كدش اين طوريه :

اول دوتا procedure در بخش published فرم اعلان ميكنيم ( توجه كنين كه اگه بخواين يه تابع رو به طور پويا در زمان اجراء بر اساس نامش صدا كنين حتما بايد در حوزه published باشه و فكر ميكنم چون دلفي براي اشياء اين حوزه RTTI مي سازه ) . خوب دو تا تابع مثلا با نامهاي Pro1 و Pro2 اعلان ميكنم . حالا يه تابع اساسي ديگه تعريف ميكنم به اين شكل :


procedure TForm1.execprocbyname(proc_name: string);
var
x:myproc;
z:string;
begin
tmethod(x).Data:=self;
tmethod(x).Code:=MethodAddress(proc_name);
if TMethod(x).Code<>nil then
begin
z:='Test';
x(z);
;end
end;

همون طور كه ازش پيداست يه رشته به عنوان نام procedure از من ميگيره و procedure با اون نام رو اجراء ميكنه . يه نكته ديگه هم اينه نوع MyProc بالاي implemantation فرم به اين شكل تعريف ميشه :


type
myproc = procedure (X:string) of object

در ضمن دوتا تابع Pro1 و pro2 هر دوشون در اين مثال يه پارامتر string به عنوان ورودي ميگيرن و مثلا همون رشته رو showmessage ميكنن .

طرز استفاده هم ميشه اين طوري باشه :


int1 : = 1;
execprocbyname('pro'+inttostr(int1);