PDA

View Full Version : حرفه ای: انتقال کنترل از به فرمی به فرم دیگر



tiphooo
یک شنبه 09 بهمن 1390, 04:19 صبح
با سلام
من می خواستم بدانم در صورتی که برنامه من MDI نباشد چگونه می توانم بدانم در حال حاضر چند فرم باز است و کنترل را از فرم جاری به فرم دیگر انتقال دهم تقریبا پیاده سازی MDI که با Ctrl+Tab بین فرمها حرکت می کند می باشد ولی به دلیل زیر در برنامه استفاده از MDI جواب نمی دهد البته ظاهرا در ورژنهای بالاتر از Delphi7 این مشکل حل شده است.
مشکل : در صورت استفاده از فرمها به صورت MDI در صورتی که کنترلی در فرم اصلی قرار بگیردمثلا یک Panel با باز شدن هر فرم MDI فرم باز شده زیر کنترل موجود قرار می گیرد و آن بخش از فرم که در زیر کنترل است قابل دسترسی نیست.
حال اینکه اگر این مشکل قابل حل است لطفا راهنمایی فرمائید در غیر اینصورت در مورد سوال اول راهنمایی فرمائید.
با تشکر

Felony
یک شنبه 09 بهمن 1390, 08:26 صبح
خود مایکروسافت استفاده از رابط کاربری MDI رو منسوخ شده اعلام کرده و بهتره ازشون استفاده نکنید ، با کد زیر میتونید ببینید چند تا فرم در حال نمایش هست :

var
objCount, frmCount: Integer;
begin
frmCount:= 0;
for objCount:= 0 to Application.ComponentCount - 1 do
if (Application.Components[objCount] is TForm) and (TForm(Application.Components[objCount]).Visible= True) then
Inc(frmCount);
ShowMessage(IntToStr(frmCount));
end;

توسط متد SetFocus شئ مورد نظر هم میتونید فوکوس رو بهش منتقل کنید .

tiphooo
یک شنبه 09 بهمن 1390, 20:41 عصر
با تشکر
دوست عزیز کد مورد نظر فقط فرم اصلی برنامه رو می بینه چون فرمهای من زمانی که باز می شوند ایجاد می شوند و بعد از استفاده هم Free می شوند و با توجه به اینکه از خاصیت MDI استفاده نشده به خاطر اینکه فرمها زیر هم نیافتند آنها را StayOnTop تعریف کردم و زمانی که StayOnTop تعریف کنید Visible فرم باید False باشد و با دستور SetFocus کنترل را درون یک فرم می توان جابجا کرد و برای انتقال کنترل از فرمی به فرم دیگر باید از Handel آن فرمها استفاده کرد(چطوریش رو نمی دونم) و به یک شکلی فرم را از زیر به رو آورد . و اینکه در برنامه های ERP عدم استفاده از MDI کاربری سیستمها با کیبورد را بسیار مشکل می کند و هدف من هم از اینگونه طراحی تسهیل کاربری برنامه هاست . اگر دستوری برای گرفتن Handel فرمها و انتقال کنترل با استفاده از این Handel وجود دارد شاید بتواند مشکل من را حل کند.

tiphooo
دوشنبه 10 بهمن 1390, 19:13 عصر
از دوستان کسی پیدا نمی شه کمک کنه ؟ ممنون می شم اگه تجربیات خودتون رو در این زمینه بگید.

SAASTN
دوشنبه 10 بهمن 1390, 20:05 عصر
یا فرم هاون رو اینجوری ایجاد کنید:
Application.CreateForm(TChildForm, aChildForm);
تا از طریق کد پست 2 بتونید به فرم ها و هندلشون دسترسی پیدا کنید، یا اینکه یه فیلد از نوع TList تعریف کنید و هر فرمی رو که ایجاد کردید تو این لیست اضافه، و هر فرمی رو که آزاد کردید ازش حذف کنید، به این ترتیب لیست تمام فرمهای باز رو دارید و هندل اونها رو هم که به سادگی می تونید به دست بیارید.
// main form create
FormsList := TList.Create;
// main form destroy
FormsList.Free;
// new child form
NewForm := TMyForm.Create(nil);
FormsList.Add(NewForm);
// close child Form
FormsList.Remove(ClosedForm);
ClosedForm.Free;
// get child handle
for I := 0 to FormsLis.Count - 1 do
TForm(FormsList[I]).Handle;

tiphooo
دوشنبه 10 بهمن 1390, 22:07 عصر
با تشکر از شما منتها چطوری می شه با استفاده از این Handle کنترل رو به یک Handle خاص فرستاد فرض کنید که Tlist ایجاد شده را در یک ListView (عناوین فرمها) بریزیم حال اینکه راهی هست با توجه به اینکه Handle فرمها رو داریم از ListView که انتخاب کنیم اون فرم از زیر بقیه فرمها به رو بیاد و کنترل به آن فرم انتقال یابد.

SAASTN
سه شنبه 11 بهمن 1390, 19:48 عصر
این سوال دو بخش داره، یکی مرتبط کردن فرم ها با Item های ListView که برای اون از TListItem.Data استفاده می کنیم، و بعد انتقال فوکوس به فرم مورد نظر که با SetFocus خود فرم هم انجام میشه، ولی اگه حتما می خواید با Handle فرم این کار رو انجام بدید باید از Windows.SetFocus استفاده کنید:
type
TForm1 = class(TForm)
ButtonNewForm: TButton;
ListView1: TListView;
procedure ButtonNewFormClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ListView1Click(Sender: TObject);
private
procedure ChildClose(Sender: TObject; var Action: TCloseAction);
public
FormsList: TList;
FormsCounter: Integer;
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
uses
Unit2;

procedure TForm1.ButtonNewFormClick(Sender: TObject);
var
NewForm: TForm2;
begin
NewForm := TForm2.Create(nil);
FormsList.Add(NewForm);
NewForm.Name := Format('Form%d', [FormsCounter]);
NewForm.Caption := NewForm.Name;
NewForm.Show;
NewForm.OnClose := ChildClose;
with ListView1.Items.Add do
begin
Caption := IntToStr(FormsCounter);
SubItems.Add(NewForm.Name);
Data := Pointer(NewForm);
end;
Inc(FormsCounter);
end;

procedure TForm1.ChildClose(Sender: TObject; var Action: TCloseAction);
var
I: Integer;
begin
for I := 0 to ListView1.Items.Count - 1 do
if ListView1.Items[I].Data = Pointer(Sender) then
begin
ListView1.Items.Delete(I);
Break;
end;
FormsList.Remove(Sender);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
FormsList := TList.Create;
FormsCounter := 0;
end;

procedure TForm1.ListView1Click(Sender: TObject);
begin
if ListView1.ItemIndex > -1 then
begin
Windows.SetFocus(TForm(ListView1.Selected.Data).Ha ndle);
// TForm(ListView1.Selected.Data).SetFocus;
end;
end;

tiphooo
چهارشنبه 12 بهمن 1390, 05:25 صبح
دوست عزیز ممنون از راهنمائیتون . ولی مشکل کماکان پابرجاست . من یک مثال ساده اینجا گذاشتم که با ایجاد یک فرم Handle اون فرم را به یک ListBox اضافه می کنم و سپس با انتخاب Handle های درج شده در ListBox و دستورات مختلف برای انتقال کنترل به فرم مورد نظر باز هم اگر Handle فرم جاری رو نگاه کنیم روی فرم Main برنامه است و کنترل به فرم مورد نظر انتقال پیدا نمی کند.

SAASTN
چهارشنبه 12 بهمن 1390, 08:38 صبح
مشکل کد شما اینه که هر بار یه فرم جدید ایجاد می کنه، ولی فقط هندل Form2 یا Form3 رو به ListBox اضافه می کنه. اگه اون Form2 رو حذف کنید درست کار می کنه:
with TForm2.Create(Application) do
begin
try
ListBox1.Items.Add (IntToStr(Handle));
Enter;
finally
end;
end;

قبل از اینکه اون Form2 رو حذف کنید می بینید که با هر بار زدن کلید ShowForm2 یه عدد ثابت تو ListBox درج میشه، که نشون میده محتویات متغیر Form2 تغییر نکرده. توجه کنید که شما با هر بار فراخونی TForm2.Create دارید یه نمونه جدید از TForm2 ایجاد می کنید و Form2 خودش یه نمونه دیگه از این کلاسه که قبلا ایجاد شده و ربطی به نمونه هایی که شما ایجاد کردید نداره، مگر اینکه شما با هر بار نمونه سازی نمونه ایجاد شده رو بریزید تو متغیر Form2، که این کار هم باعث می شه دسترسی به Form2 اصلی برای همیشه از بین بره. و البته زمانی که ما خودمون فرم ها رو ایجاد و آزادسازی می کنیم بهتره اونها رو از حالت AutoCreate در بیاریم، چون عملا برناممون دیگه نیازی به اون متغیر Form2 نداره. برای اینکار هم که منوی Project\Options...\Forms. وضعیت فرم رو از AutoCreate به Available تغییر می دیم.

tiphooo
چهارشنبه 12 بهمن 1390, 15:10 عصر
بسیار از راهنمایی شما متشکرم. با این کار مشکل حل شد. فرمها رو چون از اسمشون استفاده کرده بودم مجبور بودم با این که هر بار Create می کنم در حالت AutoCreate هم بگذارم در واقع در برنامه اصلی AutoCreate نیستند ولی با استفاده از این کار دیگر نیازی به AutoCreate نیست و از راهنمائیهای شما کمال تشکر را دارم.