2009-04-19 46 views
8

我有一個Cocoa應用程序,它使用NSAlert類來顯示應用程序模式警報。我希望警報窗口能浮在所有其他應用程序的窗口之上。這可以用NSAlert完成,還是我需要實現我自己的窗口?可以使用NSAlert創建浮動窗口嗎?

我不知道這是否有任何問題,但應用程序是一個代理應用程序(LSUIElement爲true)作爲NSStatusItem實施。 (有關應用程序的詳細信息,包括源代碼,看看<here>。)

這是顯示警告代碼:

- (void)showTimerExpiredAlert { 
    [NSApp activateIgnoringOtherApps:YES]; 

    NSAlert *alert = [[NSAlert alloc] init]; 
    [alert setAlertStyle:NSInformationalAlertStyle]; 
    [alert setMessageText:NSLocalizedString(@"Menubar Countdown Complete", @"Expiration message")]; 
    [alert setInformativeText:NSLocalizedString(@"The countdown timer has reached 00:00:00.", 
               @"Expiration information")]; 
    [alert addButtonWithTitle:NSLocalizedString(@"OK", @"OK button title")]; 
    [alert addButtonWithTitle:NSLocalizedString(@"Restart Countdown...", @"Restart button title")]; 

    NSInteger clickedButton = [alert runModal]; 
    [alert release]; 

    if (clickedButton == NSAlertSecondButtonReturn) { 
     // ... 
    } 
} 

我試圖把這個runModal調用之前:

[[alert window] setFloatingPanel:YES]; 

我也試過這樣:

[[alert window] setLevel:NSFloatingWindowLevel]; 

但NEIT如果我點擊另一個應用程序的窗口,那麼她的窗口會讓窗口留在其他窗口上方我懷疑runModal只是不尊重這些設置。

+1

每當runModal被調用它重置窗口級別,不知道是否有幫助... – cobbal 2009-04-19 13:53:37

回答

5

前段時間我破壞了我的大腦。

我可以得到這個工作(有點)的唯一方法是子類NSApplication,並覆蓋-sendEvent。在-sendEvent,你首先調用超類的實現,然後做這樣的事情:

id *modalWindow = [self modalWindow]; 
if (modalWindow && [modalWindow level] != MY_DESIRED_MODAL_WINDOW_LEVEL) 
    [modalWindow setLevel: MY_DESIRED_MODAL_WINDOW_LEVEL]; 

除此之外,連這個也不太一塵不染工作 - 切換應用程序時 - 你永遠不會無論如何要做到這一點因爲這是一個公然的黑客攻擊。

所以,是的,遺憾的是你最好寫自己的NSAlert版本。如果你真的關心這種可能性,我會提出一個錯誤。非常奇怪的是[[alert window] setLevel:someLevel]沒有被NSApplication所尊敬,而且爲了能夠做到這一點,必須重新構建NSAlert以及所有它的整齊小自動佈局功能是一件很浪費的事情。

2

我最終做的是放棄NSAlert,而是從NIB加載一個警報NSWindow

這裏是顯示窗口中的代碼:

- (void)showAlert { 
    NSWindow *w = [self window]; 
    [w makeFirstResponder:nil]; 
    [w setLevel:NSFloatingWindowLevel]; 
    [w center]; 
    [w makeKeyAndOrderFront:self]; 
} 

這是爲了讓它像一個警報,但它也漂浮,它不是模態的,所以菜單項可以選擇,同時它已經結束了。

還有什麼我應該做的?