2014-05-08 89 views
1

我有一個顯示另一個模態窗體(B)的模態窗體(A)。 B顯示數據集並允許用戶與之交互。我的問題是,一個動作要求A再次成爲焦點形式,因此用戶可以在不關閉B的情況下輸入某些值。我嘗試了A.BringToFront和A.SetFocus,它確實顯示在前面,但輸入焦點仍然在B當你點擊你不應該的地方時,A中的任何點擊或類似的操作都會導致窗口「叮噹」。代碼有點像在Delphi中切換模態窗體

A.ShowModal; 。 。 。在A的事件中: B.ShowModal(); 。 。 。在事件B中:

someobject.someMethodThatRequiresAFocused;

我的猜測是,一些模糊和奇怪的API調用可能會使A模式再次¿任何想法?

問候

+0

唯一不明白的地方在於你的代碼:-)不,只是在開玩笑。但這就是模態的工作原理,以及爲什麼它被稱爲「模態」。你想要的是一個非模態窗口。 – JensG

+0

爲什麼不把所有東西放在一個表格上?您可以使用pagecontrol分開該部分。你甚至可以以編程方式在頁面之間切換。 – Johan

回答

5

當顯示模式窗體,包括其他模式窗體所有當前可見的形式被禁用。因此,不可能在多種模態形式之間切換。您需要重新考慮您的UI設計,以便B不會回到A以獲得新的輸入。至少,您可以讓B打開一個新的模式窗體C,它提示用戶輸入所需的值並將它們輸入B,然後BC可以用新值更新A

3

沒有API在窗口之間切換模態。無論如何,你正在尋找你的案例的API是EnableWindow。這就是模式的工作方式,除了用戶應該使用的窗口以外的其他窗口都被禁用,以至於他/她無法與其進行交互。這也是「叮叮噹噹」的原因,向用戶提供反饋。

因此,儘管讓用戶使用已被禁用的窗口來支持另一個模式窗口在技術上很簡單,但處理狀態可能並不簡單。下面我將舉一個最低限度的例子來說明它看起來會如何。

'FormB'第一個。讓我們假設你在'Owner'參數中傳遞'FormA'的引用,而'FormA'正在構造'FormB'。下面的是什麼,應該讓「模擬」再次莫代爾可能看起來像代碼:

procedure TFormB.BtnMakeFormAModalAgainClick(Sender: TObject); 
begin 
    Enabled := False;     // so that 'A' will behave like it's modal 
    EnableWindow(TFormA(Owner).Handle, True); // so that 'A' could be interacted 
    TFormA(Owner).SetFocus; 
end; 

運行此代碼時,會發生什麼是「模擬」被啓用並帶到面前,「FormB」被禁用 - 點擊時會產生一個'丁'。

但是我們還沒有完成。因爲我們修改了模態的含義 - 現在我們不希望'FormA'在用戶完成時關閉。以下是如何在「形式上的單位代碼可能看起來像:

type 
    TFormA = class(TForm) 
    BtnShowModalB: TButton; 
    BtnOk: TButton; 
    procedure BtnShowModalBClick(Sender: TObject); 
    procedure BtnOkClick(Sender: TObject); 
    private 
    FModalB: TForm; 
    end; 

implementation 

uses 
    unitOfFormB; 

{$R *.dfm} 

procedure TFormA.BtnShowModalBClick(Sender: TObject); 
begin 
    FModalB := TFormB.Create(Self); // so that FormB can find FormA from the Owner 
    FModalB.ShowModal; 
    FModalB.Free; 
    FModalB := nil; // Need this if we're going to decide if FormB is showing 
        // by testing against this reference 
end; 

procedure TFormA.BtnOkClick(Sender: TObject); 
begin 
    if Assigned(FModalB) then begin // is FormB the actual modal form? 
    EnableWindow(Handle, False); // disable this form so it would 'ding' 
    FModalB.Enabled := True;  // enable FormB, so user can interact with it 
    FModalB.SetFocus; 
    ModalResult := mrNone;  // don't close, FormB is the first one to be closed 
    end else 
    ModalResult := mrOk; 
end; 


我幾乎肯定的,這個例子是不完整的,但這裏的,你要尋找的API。