我们上次演示的程序在关掉了应用程序的窗口之后,应用程序并没有真正的退出,现在我们就来完成这个任务。

在Mac,Windows或者 Linux平台上,所有的GUI程序都可以称作消息驱动的,就是说整个应用程序就是在处理消息的循环中进行的,用户的操作或者系统发送的一些通知都会被送 到应用程序的消息处理循环中,比如用户通过键盘输入,用鼠标点击窗口等等,有些消息会直接派发给应用程序的对象,比如鼠标按下(MouseDown)的消 息就会直接被送给鼠标按下的那个窗口或者试图,但是有些消息会被系统首先解释,然后在生成其他的消息,比如用户用鼠标单击窗口Frame上的关闭按钮,这 个时候MouseDown事件并没有被送给应用程序的内部对象,而是在应用程序的消息循环中被解释成了窗口将要关闭的消息。

我们这次要处理的这个消息就是 应用程序最后一个窗口关闭的时候, 通知应用程序退出。

Cocoa中处理事件的方式有几种,其中一种是你可以重载类中的对应的事件处理方 法,比如MouseDown事件在NSResponse类中就被方法mouseDown:处理,所以所有继承自NSResponse的类都可以重载 mouseDown:方法来实现对MouseDown事件的处理。另外一种处理方式就是使用Delegate,当一个对象接受到某个事件或者通知的时候, 会向它的Delegate对象查询它是否能够响应这个事件或者通知,如果可以这个对象就会给它的Delegate对象发送一个消息(执行一个方法调用), 在代码中一般用如下的方式来实现。

if (delegate != nil && [delegate espondsToSelector:@selector(theEvent)]{

[delegate performSelector:@selector(theEvent)];

}

所以如果我们想处理一个对象的事件的话,就可以实现它所要求的方法,然后将实现了这个方法的类的实例作为Delegate对象赋值给发出事件的对象。

下面我们就用代码来说明。

 

 

#import 

@interface MyDelegate : NSObject {

}

- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication;

- (BOOL)windowShouldClose:(id)window;

@end

 

@implementation MyDelegate

- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication

{

    return YES;

}

 

- (BOOL)windowShouldClose:(id)window

{

    NSAlert* alert = [[NSAlert alloc] init];

    [alert setAlertStyle:NSInformationalAlertStyle];

    [alert setMessageText:@"Are you sure you want to quit?"];

    [alert addButtonWithTitle:@"Yes"];

    [alert addButtonWithTitle:@"No"];

    NSInteger result = [alert runModal];

    if (result == NSAlertFirstButtonReturn)

    {

        [alert release];

        return YES;

    }

    [alert release];

    return NO;   

}

@end

 

 

int main(int argc, char *argv[])

{

    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

    [NSApplication sharedApplication];

    //Create the main window

    NSRect rc = NSMakeRect(0, 0, 800, 600);

    NSUInteger uiStyle = NSTitledWindowMask | NSResizableWindowMask | NSClosableWindowMask;

    NSBackingStoreType backingStoreStyle = NSBackingStoreBuffered;

    NSWindow* win = [[NSWindow alloc] initWithContentRect:rc styleMask:uiStyle backing:backingStoreStyle defer:NO];

    [win setTitle:@"HelloWin Test"];

    [win center]; //Center main Window