View Full Version : ارسال يك خط دستور به يك پروسيجر
SayeyeZohor
دوشنبه 10 بهمن 1390, 04:35 صبح
اين فانكشني هستش كه ازش استفاده مي كنم
هدف : بدست آوردن يك نوع كامپوننت در تمام فرم هاي برنامه در لحظه است
مثال : تمام ديبيگريد هاي برنامه در فرم هاي مختلف كه كار اين فانكشن همينه فقط من اومدم اون ها رو در يك TStringList ذخيره مي كنم بعد تو يك حلقه for دستور هام رو روشون اجرا مي كنم
مثلا در اينجا مي خوام ParentColor تمام Panel هام True بشند
FUNCTION TForm1.NewFindComponent(NForm: TCustomForm; CompType: TComponentClass) : TStringList;
var
I, J : Integer;
FormName, FormComp : TComponent;
Ts : TStringList;
BEGIN
Ts := TStringList.Create;
For I := 0 to Application.ComponentCount - 1 Do
For J := 0 to Application.Components[I].ComponentCount - 1 Do
begin
FormName := Application.Components[I]; //نام فرم هاي موجود در پروژه ...
FormComp := Application.Components[I].Components[J]; //نام كامپوننت هاي موجود در فرم ها ...
If {(FormName = NForm) AND} (FormComp is CompType) Then
Ts.Add(FormName.Name+'~'+TComponent(FormComp).Name );
End;
ListBox1.Clear;
ListBox1.Items.Text := Ts.Text;
Result := Ts;
END;
با اين دستور اين كار رو انجام مي دم
procedure TForm1.Button1Click(Sender: TObject);
var
NameForm, NameComp: string;
Ts1: TStringList;
I: Integer;
begin
Ts1 := TStringList.Create;
Ts1.Text := NewFindComponent(Form1, TCustomPanel).Text;
For I := 0 to Ts1.Count - 1 Do
Begin
NameForm := Trim(Copy(Ts1[I], 1, Pos('~', Ts1[I])-1));
NameComp := Trim(Copy(Ts1[I], Pos('~', Ts1[I])+1, length(Ts1[I])));
TPanel(FindComponentEx(NameForm+'.'+NameComp)).Par entColor := True;
End;
Ts1.Free;
End;
:متفکر:
حالا مي خوام پروسيجر دوم رو يك خطي كنم و دستور اين TPanel(FindComponentEx(NameForm+'.'+NameComp)).Par entColor := True; هستش رو به صورت يك متغير به فانكشنم پاس بدم و خودش ديگه دستور رو روي تمام كامپوننت هام اجرا كنه
شايد مسخره به نظر بياد
:گریه::گریه:
لطفاً زود كمكم كنيد
SAASTN
دوشنبه 10 بهمن 1390, 18:58 عصر
در ابتدا یه سری پیشنهاد می کنم در مورد کدتون:
اولا برای قرار دادن کد توی فروم از تگ PAS استفاده کنید تا کدها قابل خوندن باشه.
شما از یه TStringList استفاده کردید و نام کامپوننت ها و فرم ها رو در اون ذخیره کردید و بعد با پردازش رشته روی اون متن ها دو باره کامپوننت و فرم مربوطه رو بدست آوردید، در صورتی که نیاز به این کار نیست، بهتره از یه TList استفاده کنید و خود شیئ کامپوننت رو درش اضافه کنید تا دیگه نیازی به اون پردازش رشته نباشه.
از طرفی شما NewFindComponent رو بصورت تابع تعریف کردید که اون TstringList (یا TList) رو داخل خودش ایجاد می کنه و در خروجی قرار میده، توجه داشته باشید که این خروجی هیچ جا Free نمی شه و برنامه شما نشت حافظه داره. باید حتما خروجی تابع رو در محل فراخونی، در یک متغیر بریزید و بعد اون متغیر رو آزاد کنید. البته بهتر هست که ایجاد و آزادسازی اشیائ در یه محل انجام بشه، پس بهتره که تابع NewFindComponent به یه روال تبدیل بشه و اون TList رو به عنوان یه پارامتر دریافت کنه و فقط لیست رو پر کنه. ایجاد و آزادسازی اون لیست هم بر عهده فراخواننده NewFindComponent خواهد بود.
و نکته آخر این که کد نویسی شما خیلی خوانا نیست، برای برنامه نویسی یه سری اصول نگارشی رو باید رعایت کنید که قبلا چند موردش رو اینجا (http://barnamenevis.org/showthread.php?315033-%D9%85%D8%B4%DA%A9%D9%84-%D8%AF%D8%B1-%D8%B3%D8%A7%D8%AE%D8%AA-%D8%B2%DB%8C%D8%B1-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87&p=1383553) ذکر کرده بودم.
حالا بریم سراغ موردی که پرسیده بودید، این امکان وجود داره که شما یه متد رو از طریق پارامتر های یه متد دیگه ارسال کنید، برای اینکار باید یه نوع جدید از اون متد تعریف کنید و نوع پارامتر رو برابر این نوع جدید قرار بدید، نمونه این کار به همراه اصلاحاتی که در بالا گفتم رو توی کد خوتون انجام دادم:
// Type of Method!!
TModifyComponentMethod = procedure (aComponent: TComponent) of object;
TForm1 = class(TForm)
Button1: TButton;
Panel1: TPanel;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
procedure SetPanelsParentColor(aComponent: TComponent);
procedure SetButtonsFont(aComponent: TComponent);
procedure NewFindComponent(NForm: TCustomForm;
CompType: TComponentClass; List: TList);
procedure ModifyComponents(NForm: TCustomForm; CompType: TComponentClass;
Method: TModifyComponentMethod);
{ Private declarations }
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button2Click(Sender: TObject);
begin
ModifyComponents(Self, TPanel, SetPanelsParentColor);
ModifyComponents(Self, TButton, SetButtonsFont);
end;
procedure TForm1.ModifyComponents(NForm: TCustomForm; CompType: TComponentClass;
Method: TModifyComponentMethod);
var
List: TList;
I: Integer;
begin
List := TList.Create;
NewFindComponent(NForm, CompType, List);
for I := 0 to List.Count - 1 do
Method(TComponent(List[I]));
List.Free;
end;
procedure TForm1.NewFindComponent(NForm: TCustomForm; CompType: TComponentClass;
List: TList);
var
I, J: Integer;
FormName, FormComp: TComponent;
begin
List.Clear;
for I := 0 to Application.ComponentCount - 1 do
for J := 0 to Application.Components[I].ComponentCount - 1 do
begin
FormName := Application.Components[I]; // نام فرم هاي موجود در پروژه ...
FormComp := Application.Components[I].Components[J];
// نام كامپوننت هاي موجود در فرم ها ...
If { (FormName = NForm) AND } (FormComp is CompType) then
List.Add(FormComp);
end;
end;
procedure TForm1.SetButtonsFont(aComponent: TComponent);
begin
with TButton(aComponent).Font do
begin
Name := 'Arial';
Size := 12;
end;
end;
procedure TForm1.SetPanelsParentColor(aComponent: TComponent);
begin
TPanel(aComponent).ParentColor := True;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
// NameForm, NameComp: string;
ComsList: TList;
I: Integer;
begin
ComsList := TList.Create;
NewFindComponent(Form1, TCustomPanel, ComsList);
for I := 0 to ComsList.Count - 1 do
begin
// NameComp := TPanel(ComsList[I]).Name;
// NameForm := TForm(TPanel(ComsList[I]).Owner).Name;
TPanel(ComsList[I]).ParentColor := True;
end;
ComsList.Free;
end;
نوع TModifyComponentMethod همون نوع از متدی هست که گفتم باید تعریف بشه، از این نوع در متد ModifyComponents استفاده شده و نمونه های اون هم SetPanelsParentColor و SetButtonsFont هستند، برای فراخونی هم به Button2Click توجه کنید.
امیدوارم تونسته باشم مطلب رو برسونم
SayeyeZohor
سه شنبه 11 بهمن 1390, 01:42 صبح
آقا دمت گرم
ميشه يك كم بيشتر راجع به روشي كه گفتيد توضيح بديد؟
من با متد ها زياد كار نكردم
در كل بگم مبتديم
:خجالت::خجالت:
SAASTN
سه شنبه 11 بهمن 1390, 17:13 عصر
برای انجام این کار اولین کاری که باید انجام بشه تعریف یه نوع جدید از متده. پارامترهای این متد باید فرم عمومی اون کاری رو که می خوایم انجام بدیم داشته باشه، در مورد مسئله حاظر کاری که می خوایم انجام بدیم اینه که مشخصات یه کامپوننت رو تغییر بدیم، پس متد ما باید یه پارامتر از نوع TComponent داشته باشه، که از طریق اون کامپوننت مورد نظر رو براش ارسال کنیم. پس نوع از متد رو به شکل زیر تعریف می کنیم:
type
TModifyComponentMethod = procedure (aComponent: TComponent) of object;
در مرحله بعد نمونه هایی از این متد رو تو کلاسمون ایجاد می کنیم، مثلا می خوایم ParentColor یه Panel رو تغییر بدیم، پس یه متد به این صورت تو کلاس فرم تعریف می کنیم:
procedure SetPanelsParentColor(aComponent: TComponent);
//...
implementation
//...
procedure TForm1.SetPanelsParentColor(aComponent: TComponent);
begin
TPanel(aComponent).ParentColor := True;
end;
یا مثلا می خوایم فونت Button ها رو تغییر بدیم:
procedure SetButtonsFont(aComponent: TComponent);
//...
implementation
//...
procedure TForm1.SetButtonsFont(aComponent: TComponent);
begin
with TButton(aComponent).Font do
begin
Name := 'Arial';
Size := 12;
end;
end;
توجه داشته باشید که ترتیب پارامترهای این دو روال دقیقا شبیه به همون نوع TModifyComponentMethod هست که قبلا تعریف کردیم.
حالا می خوایم روالی تعریف کنیم که یکی از پارامترهای اون از نوع متد هست، تعریف این نوع پارامتر هیچ تفاوتی با تعریف پارامتر از نوع Integer یا String نداره، فقط نوع پارامتر رو برابر TModifyComponentMethod قرار می دیم:
procedure ModifyComponents(NForm: TCustomForm; CompType: TComponentClass;
Method: TModifyComponentMethod);
در بدنه این روال پارامتر Method از جنس متد هست، یعنی با ذکر نام این پارامتر دقیقا داریم یه روال رو اجرا می کنیم و باید پارامترها مورد نیاز اون رو براش ارسال کنیم، از طرفی می دونیم این روال از نوع TModifyComponentMethod هست، پس یه پارامتر از نوع TComponent نیاز داره، پس پیاده سازی ما به این شکل در میاد:
procedure TForm1.ModifyComponents(NForm: TCustomForm; CompType: TComponentClass;
Method: TModifyComponentMethod);
var
List: TList;
I: Integer;
begin
List := TList.Create;
NewFindComponent(NForm, CompType, List);
for I := 0 to List.Count - 1 do
Method(TComponent(List[I]));
List.Free;
end;
حالا برای فراخونی روال ModifyComponents باید پارامتری از نوع روال ارسال کنیم، برای این منظور فقط روال هایی رو می تونیم ارسال کنیم که ترتیب و نوع پارامترهاشون دقیقا شبیه به TModifyComponentMethod باشه. خوب ما قبلا روالهای SetPanelsParentColor و SetButtonsFont دقیقا به همین ترتیب تعریف کردیم، پس می تونیم اونها رو به روال ModifyComponents ارسال کنیم، برای این منظور همونطوری که مثلا 1 یا 'Ali' رو برای یه روال ارسال می کنیم، تنها کافیه نام متد مورد نظرمون رو به عنوان پارامتر ارسال کنیم:
procedure TForm1.Button2Click(Sender: TObject);
begin
ModifyComponents(Self, TPanel, SetPanelsParentColor);
ModifyComponents(Self, TButton, SetButtonsFont);
end;
امیدوارم این دفعه دیگه رسونده باشم، اگه باز مشکلی بود راجع به بخشی که متوجه نشدید بپرسید تا مجبور نشم دوباره از اول بگم:کف:
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.