PDA

View Full Version : دسترسی به آبجکت های یک فرم از یونیت



zahra_no
سه شنبه 08 اسفند 1391, 13:04 عصر
با سلام
همون طور که از عنوان هم پیداست آیا میشه به آبجکت های یک فرم از طریق یونیت ها دستکاری کند و خصوصیات اونارو تغییر داد؟؟

یوسف زالی
سه شنبه 08 اسفند 1391, 14:02 عصر
سلام.
فکر نمی کنم بشه با استفاده از نام یونیت به فرم(های)ی که (احتمالا) داخلش تعریف شده دسترسی داشت.
اما اگر منظورتون اینه که با داشتن نام فرم به اجزاش دسترسی داشت، FormName.Components و FormName.Controls گزینه های مناسبی هستند.

zahra_no
سه شنبه 08 اسفند 1391, 14:41 عصر
منظور من به این حالت است

این یونیت
unit Unit2;

interface

procedure setName();

implementation

procedure setName();
begin
label1.caption:='hello'
end;
end.


این هم فرم اصلی

unit Unit1;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs,unit2, Vcl.StdCtrls,unit2;

type
TForm1 = class(TForm)
Label1: TLabel;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
setName();
end;

end.

یوسف زالی
سه شنبه 08 اسفند 1391, 17:02 عصر
وقتی این رو دارید:


var
Form1: TForm1;

به راحتی بنویسید:
Form1.lable1.caption

اما راه حل درست برای این کار اینه:


type
TForm1 = class(TForm)
Label1: TLabel;
procedure FormCreate(Sender: TObject);
private
procedure setName();
public
{ Public declarations }
end;

حالا روی setName ایستاده و کلیدهای Ctrl+Shift+C رو بزنید. دلفی براتون یک متد می سازه در حوزه ی شی فرمتون. یعنی اینکه Lable1 براش شناخته شده هست.

سعی کردم ساده بگم.
اگر لازمه فلسفه ش رو بدونید کمی در مورد متدها و OOP تحقیق کنید.
موفق باشید.

zahra_no
سه شنبه 08 اسفند 1391, 17:18 عصر
ممنون از جوابتون دوست عزیز

ولی وقتی من


حالا روی setName ایستاده و کلیدهای Ctrl+Shift+C رو بزنید. دلفی براتون یک متد می سازه در حوزه ی شی فرمتون

متد ساخته شده در اون فرم که به درد من نمیخوره، چون من اون متد را در یونیت نوشته ام و میخوام از اون استفاده کنه وگرنه در فرم اصلی که این کار مشکلی نداره.

در مورد

به راحتی بنویسید:
Form1.lable1.caption

این کار را انجام دادم باز هم label1 را نمیشناسد حتی در uses ، unit1 را در نوشتم باز نشناخت.

به نظر شما اصلا این کار شدنیه یا نه؟

MohsenB
سه شنبه 08 اسفند 1391, 20:12 عصر
با سلام


..
اما راه حل درست برای این کار اینه:


type
TForm1 = class(TForm)
Label1: TLabel;
procedure FormCreate(Sender: TObject);
private
procedure setName();
public
{ Public declarations }
end;
..

اگر قصد دسترسی از خارج از فرم 1 به این متد را دارید این متد را در قسمت Public تعریف کنید .


ممنون از جوابتون دوست عزیز

ولی وقتی من



متد ساخته شده در اون فرم که به درد من نمیخوره، چون من اون متد را در یونیت نوشته ام و میخوام از اون استفاده کنه وگرنه در فرم اصلی که این کار مشکلی نداره.

در مورد


این کار را انجام دادم باز هم label1 را نمیشناسد حتی در uses ، unit1 را در نوشتم باز نشناخت.

به نظر شما اصلا این کار شدنیه یا نه؟

بطور کلی دو قسمت جداگانه درون هر یونیت وجود دارد یکی interface و دیگری implementation .
به تعبیری میشه گفت که interface یک محل تعریف عمومی یا Public برای یونیت هست و implementation یک محل خصوصی یا Private ( محلی ) . هر متغیر ، ثابت ، نوع و ... که توی قسمت عمومی نوشته بشه قابل دسترسی از یونیت هایی هست که به این یونیت در اون مورد استفاده قرار گرفته است . برای دسترسی محلی درون خود یونید به روال کافیه اونو در قسمت implementation پیاده سازی کنید و اگر نیاز به تعریف عمومی داشت اون رو در قسمت interface فقط تعریف کنید . برای مثال تعریف خود فرم1 در کد بالا در قسمت interface میباشد و شما میتوانید به کلاس فرم1 از هر یونیتی که از این یونیت استفاده کرده باشد دسترسی داشته باشید .
برای روال مورد نظر شما اگر این روال وابسته به فرم شما نیست می توتانید تعریف آن را قبل از implementation و بیرون از تعریف کلاس فرم قرار دهید تا بصورت عمومی باشد .
توجه کنید که دو یونیت نمیتوانند در بخش interface بصورت همزمان از همدیگر استفاده ( Uses ) کنند و باید یکی از آنها در قسمت implementation تعریف شوند .


موفق باشید

zahra_no
چهارشنبه 09 اسفند 1391, 12:16 عصر
با سلام



اگر قصد دسترسی از خارج از فرم 1 به این متد را دارید این متد را در قسمت Public تعریف کنید .



بطور کلی دو قسمت جداگانه درون هر یونیت وجود دارد یکی interface و دیگری implementation .
به تعبیری میشه گفت که interface یک محل تعریف عمومی یا Public برای یونیت هست و implementation یک محل خصوصی یا Private ( محلی ) . هر متغیر ، ثابت ، نوع و ... که توی قسمت عمومی نوشته بشه قابل دسترسی از یونیت هایی هست که به این یونیت در اون مورد استفاده قرار گرفته است . برای دسترسی محلی درون خود یونید به روال کافیه اونو در قسمت implementation پیاده سازی کنید و اگر نیاز به تعریف عمومی داشت اون رو در قسمت interface فقط تعریف کنید . برای مثال تعریف خود فرم1 در کد بالا در قسمت interface میباشد و شما میتوانید به کلاس فرم1 از هر یونیتی که از این یونیت استفاده کرده باشد دسترسی داشته باشید .
برای روال مورد نظر شما اگر این روال وابسته به فرم شما نیست می توتانید تعریف آن را قبل از implementation و بیرون از تعریف کلاس فرم قرار دهید تا بصورت عمومی باشد .
توجه کنید که دو یونیت نمیتوانند در بخش interface بصورت همزمان از همدیگر استفاده ( Uses ) کنند و باید یکی از آنها در قسمت implementation تعریف شوند .


موفق باشید

ممنون از جوابتون
من کاملا منظور شما رو متوجه شدم ولی نتونستم کد رو تغییر بدم که به اون چیزی که میخوام برسم. یعنی هر طور تغییر دادم جواب نداد. میشه لطفا چیدمان این کد رو صریحا بگید؟

MohsenB
چهارشنبه 09 اسفند 1391, 13:35 عصر
سلام

در زیر دوتا نمونه یونیت براتون نوشتم که اونهایی که قابل دسترس هستند بصورت نمونه استفاده شده ولی اونهایی که قابل دسترسی نیستند توضیح داده شده است :

unit Unit1;

interface

uses
Windows, Messages, Forms;

type
TForm1 = class(TForm)
private
{ Private declarations }
public
procedure MyProc1;
end;

var
Form1: TForm1;

procedure MyProc2;

implementation

{$R *.dfm}

uses Unit2;

//dar in unit MyProc4 ghabel dastras nist

procedure TForm1.MyProc1;
begin
MyProc3;
end;

procedure MyProc2;
begin
MyProc3;
end;
end.


و یونیت دوم :

unit Unit2;

interface

uses
Windows, Messages, Forms , Unit1;

procedure MyProc3;

implementation

procedure MyProc3;
begin
Form1.MyProc1;
MyProc2;
end;

procedure MyProc4;
begin
Form1.MyProc1;
MyProc2;
end;
//MyProc4 az in khat be baad ghabel dastrasi mibashad

end.


موفق باشید

zahra_no
پنج شنبه 10 اسفند 1391, 23:00 عصر
ممنون دوست عزیز با پاسختون
ولی منظور من اون چیزی که شما فرمودین نیست

و البته با تکه کد

Form1.lable1.caption
چون دو یونیت به هم uses میشن خطای

[dcc32 Fatal Error] Unit2.pas(5): F2047 Circular unit reference to 'Unit1' میده.

با این حساب فک کنم اصلا امکان نداره همچین اتفاقی بیفته

MohsenB
جمعه 11 اسفند 1391, 01:05 صبح
ممنون دوست عزیز با پاسختون
ولی منظور من اون چیزی که شما فرمودین نیست

و البته با تکه کد

چون دو یونیت به هم uses میشن خطای

[dcc32 Fatal Error] Unit2.pas(5): F2047 Circular unit reference to 'Unit1' میده.

با این حساب فک کنم اصلا امکان نداره همچین اتفاقی بیفته

سلام

قبلا توضیح دادم :

... توجه کنید که دو یونیت نمیتوانند در بخش interface بصورت همزمان از همدیگر استفاده ( Uses ) کنند و باید یکی از آنها در قسمت implementation تعریف شوند ....

zahra_no
جمعه 11 اسفند 1391, 12:55 عصر
پس چطوری باید از تکه کد Form1.lable1.caption در یونیت دوم استفاده کرد؟؟

MohsenB
جمعه 11 اسفند 1391, 17:31 عصر
سلام

ببینید به خود پیام خطا هم که نگاه می کردید توضیح داده که در استفاده از یونید یک دور اتفاق افتاده یعنی مثلا شما در قسمت Interface ، از یونیت یک استفاده ( Uses ) کرده اید و دوباره در یونید یک از یونیت قبلی استفاده کرده اید و این یعنی دور ( Circular ) . همونطوری که توضیح دادم شما نمیتوانید وقتی از یک یونیت در قسمت Interface استفاده کرده اید ، درون اون یونیت در قسمت اینترفیس از یونیت اول استفاده کنید . به مثالی که درون پست شماره هشت می باشد توجه نمایید .

موفق و پیروز باشید

Felony
شنبه 12 اسفند 1391, 13:25 عصر
کمی هم خودتون زحمت بکشید ، بابت یک سوال ... کلی گست باید زده بشه ...

http://barnamenevis.org/showthread.php?365735-%D8%AD%D9%84-%D9%85%D8%B4%DA%A9%D9%84-Circular-unit-reference-%D8%AA%D9%88%D8%B3%D8%B7-Class-Helper-%D9%87%D8%A7