2011-03-22 49 views
5

綜述:如何顯示其所有者窗體頂部的模式窗體(其所有者設置爲fsStayOnTop與否),就像TOpenDialog確實

請參閱從克雷格和Sertac下面的有益的意見。

============================================== ========

如以下最小化代碼所示,TForm10設置爲fsStayOnTopTForm10.btnTryDlgClick致電dlgOpen1.Execute,並顯示對話框如預期。但是,當我在TForm10.btnTryFormClick內調用TForm11.Create(Self).ShowModal時,窗體將隱藏在TForm10的後面。我想知道如何理解這種行爲,爲什麼標準的TOpenDialog可以按預期顯示?任何評論感謝!

PS:一種解決方法是重寫TForm11的CreateParams過程,並將Params.wndParent設置爲0.但是在我看來,使用此解決方法將打破窗口層次結構。

procedure TForm11.CreateParams(var Params: TCreateParams); // override; 
    begin 
    inherited; 
    params.wndParent := 0; 
    end; 

PS:另外一個辦法是由雷米在下文提到的相關網頁SO:setting the modal Form's PopupParent property to be the StayOnTop Form。但在接下來的評論中,Sertac提到這個解決方法也會打破窗口層次結構。

PS:可能相關的SO網頁:
Modal forms hidden by fsStayOnTop forms
How Can I Keep the FindDialog from Staying on Top (Delphi)?
How to make sure a dialog is always front of the main window
Form is hidden behind other forms when ShowModal is called
Make 2 forms able to overlap each other?
Multiple form Delphi applications and dialogs
Newly created modal window loses focus and become inacessible in Windows Vista
Delphi - How to prevent Forms/MsgBoxes to move under prior form?
How to allow Delphi secondary forms behind the main form
Fake modal dialog using Show?
Delphi MainFormOnTaskBar Modal windows bug

來源爲Unit10:

unit Unit10; 

    interface 

    uses 
     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
     Dialogs, StdCtrls; 

    type 
     TForm10 = class(TForm) 
     btnTryDlg: TButton; 
     dlgOpen1: TOpenDialog; 
     btnTryForm: TButton; 
     procedure FormCreate(Sender: TObject); 
     procedure btnTryDlgClick(Sender: TObject); 
     procedure btnTryFormClick(Sender: TObject); 
     end; 

    var 
     Form10: TForm10; 

    implementation 

    {$R *.dfm} 

    uses 
     Unit11; 

    procedure TForm10.FormCreate(Sender: TObject); 
    begin 
     FormStyle := fsStayOnTop; 
    end; 

    procedure TForm10.btnTryDlgClick(Sender: TObject); 
    begin 
     dlgOpen1.Execute; 
    // dlgOpen1.Execute(Self.Handle); 
    end; 

    procedure TForm10.btnTryFormClick(Sender: TObject); 
    begin 
     TForm11.Create(Self).ShowModal; 
    end; 

    end. 

DFM爲Unit10:

object Form10: TForm10 
     Left = 0 
     Top = 0 
     Caption = 'Form10' 
     ClientHeight = 255 
     ClientWidth = 414 
     Color = clBtnFace 
     Font.Charset = DEFAULT_CHARSET 
     Font.Color = clWindowText 
     Font.Height = -11 
     Font.Name = 'Tahoma' 
     Font.Style = [] 
     OldCreateOrder = False 
     OnCreate = FormCreate 
     PixelsPerInch = 96 
     TextHeight = 13 
     object btnTryDlg: TButton 
     Left = 32 
     Top = 24 
     Width = 153 
     Height = 201 
     Caption = 'Try dialog' 
     TabOrder = 0 
     OnClick = btnTryDlgClick 
     end 
     object btnTryForm: TButton 
     Left = 224 
     Top = 24 
     Width = 153 
     Height = 201 
     Caption = 'btnTryForm' 
     TabOrder = 1 
     OnClick = btnTryFormClick 
     end 
     object dlgOpen1: TOpenDialog 
     Left = 96 
     Top = 168 
     end 
    end 

來源爲Unit11:

unit Unit11; 

    interface 

    uses 
     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
     Dialogs; 

    type 
     TForm11 = class(TForm) 
     end; 


    implementation 

    {$R *.dfm} 

    end. 

DFM爲Unit11:

object Form11: TForm11 
     Left = 0 
     Top = 0 
     Caption = 'Form11' 
     ClientHeight = 183 
     ClientWidth = 203 
     Color = clBtnFace 
     Font.Charset = DEFAULT_CHARSET 
     Font.Color = clWindowText 
     Font.Height = -11 
     Font.Name = 'Tahoma' 
     Font.Style = [] 
     OldCreateOrder = False 
     PixelsPerInch = 96 
     TextHeight = 13 
    end 
+1

Xichen - [您提到的問題](http://stackoverflow.com/questions/3408594/modal-forms-hidden-by-fsstayontop-forms)不同之處在於模式形式是從'fsNormal'形式,而應用程序中有另一個'fsStayOnTop'形式。在這個問題中,如果您將模式表單的PopupParent設置爲頂層表單,那麼它顯然將由頂層表單所有,但應該由應用程序設計的表單所擁有。這就是我打破層級的意思。 – 2011-03-22 19:44:33

+2

順便說一句,我複製粘貼你的代碼,並且不能複製問題,當我單擊btnTryForm時,模態窗體在Form10上方。 +1爲鏈接集(研究)雖然.. – 2011-03-22 19:52:09

+0

@Sertac:非常感謝您的時間和有關'窗口層次結構'的有用評論!關於目前的問題,我很抱歉無法複製。 「它在我的機器上起作用......」O_O – SOUser 2011-03-22 21:23:42

回答

3

設置模態窗體的PopupParent屬性,就像Remy建議的一樣。這將使對話框成爲StayOnTop表單,這是對話框的Execute方法已經在做的事情。我不確定Sertac的評論是從哪裏來的,但是使用PopupParent正確設置窗口heirarchy,所以對話框總是在StayOnTop窗體上方。

+0

@克雷格:非常感謝您的建議!你的意思是在這種情況下最好使用PopupParent嗎?你能幫助確認嗎?您是否也可以幫助評論如何在實踐中判斷「窗口層次結構」是否正確保存? – SOUser 2011-03-22 18:45:38

+0

@Craig:此外,如果在這種情況下使用PopupParent是最佳實踐,您是否可以幫助評論標準對話框(如問題開頭提到的TOpenDialog)是否也使用PopupParent實現功能?或者他們有自己的方式? – SOUser 2011-03-22 18:49:13

+2

如果你想要一個特定的對話框總是出現在特定的表單上,那麼是,設置PopupParent屬性。這就是它的目的。您可以*通常*將'Application.ModalPopupMode'設置爲'pmAuto',Delphi將爲您處理所有事情。當它被設置時,對話框將被賦予當前活動窗體(通常是'Application.MainForm'),而不是'Application.Handle',這樣它就不會被卡在主窗體後面。這種情況不起作用的是當你有一個非活動的fsStayOnTop表單時,這種情況下對話框會出現在它後面。 – 2011-03-22 18:54:15

相關問題