Re: Recognizing standard about box
Re: Recognizing standard about box
- Subject: Re: Recognizing standard about box
- From: Andy Lee <email@hidden>
- Date: Thu, 27 Jun 2002 23:54:39 -0400
At 5:42 PM -0400 6/27/02, Bill Cheeseman wrote:
Is there any way to determine whether an open window is the standard Cocoa
document-based application about box?
I get the list of my application's open windows from [NSApp windows]. To
examine the about box, I run the application in the debugger and make sure
only the about box is open and visible. I can see that it is an NSPanel
object. But I don't see anything distinctive about it that would let my
program recognize which one of many open windows is the standard about panel
at run time.
That was a head-scratcher. I saw what you saw, and couldn't find a
way to distinguish the standard About panel from the other windows.
So I wrote a subclass of NSApplication (source code below) that
overrides -orderFrontStandardAboutPanel:. My "SAPHackApp" class
hangs on to the About panel after opening it and gives you access to
it via +standardAboutPanel.
If you don't want to subclass NSApplication, you can tweak my code
and copy it into its own class. And if there was an easier way that
I missed, then never mind. ;) And of course if you'd rather ignore
all this and roll your own AboutPanelClass, that'll work too.
Some things I learned along the way:
* The standard About panel has as its delegate an NSSystemInfoPanel,
which for some reason appears to be a private class. (Maybe we
should ask Apple to open it up to us?)
* There is an NSSystemInfoPanel.nib in AppKit.framework, which is
presumably used to instantiate the NSPanel. (Does this mean if you
create your own NSSystemInfoPanel.nib in your project, that will get
used instead? I'd try, but I don't know what to name the File's
Owner or its outlets.)
* By default, the About panel is released when closed. That means if
you open it again, it is re-instantiated and appears in the center of
the screen, instead of where you last placed it.
--Andy
==========
-----SAPHackApp.h-----
//
// SAPHackApp.h
//
// Created by Andy Lee on Thu Jun 27 2002.
// Free for anyone to use for any purpose.
//
// This class provides access to the standard About panel opened by
NSApplication's
// -orderFrontStandardAboutPanel: method. Access to that panel is
currently hidden
// in a private AppKit class called NSSystemInfoPanel.
//
#import <Cocoa/Cocoa.h>
@interface SAPHackApp : NSApplication
{
}
// Returns nil if the About panel isn't open.
+ (NSPanel *)standardAboutPanel;
// Retains the About panel after opening it.
- (IBAction)orderFrontStandardAboutPanel:(id)sender;
@end
-----END SAPHackApp.h-----
-----SAPHackApp.m-----
//
// SAPHackApp.m
//
// Created by Andy Lee on Thu Jun 27 2002.
// Free for anyone to use for any purpose.
//
#import "SAPHackApp.h"
@implementation SAPHackApp
static NSPanel *_standardAboutPanel = nil;
+ (NSPanel *)standardAboutPanel
{
return _standardAboutPanel;
}
- (IBAction)orderFrontStandardAboutPanel:(id)sender
{
NSMutableSet *oldSet;
NSMutableSet *newSet;
NSEnumerator *winEnum;
id win;
if (_standardAboutPanel)
{
[super orderFrontStandardAboutPanel:sender];
return;
}
// Open the about panel and figure out what windows this adds. (From trial
// and error it seems that for some reason, two windows get added, only one
// of which is an NSPanel.)
oldSet = [NSMutableSet setWithArray:[NSApp windows]];
[super orderFrontStandardAboutPanel:sender];
newSet = [NSMutableSet setWithArray:[NSApp windows]];
[newSet minusSet:oldSet];
// Figure out which of the new windows is the about panel.
winEnum = [newSet objectEnumerator];
while ((win = [winEnum nextObject]))
{
if ([win isKindOfClass:[NSPanel class]])
{
_standardAboutPanel = [(NSPanel *)win retain];
// Use a notification instead of delegation because
// _standardAboutPanel already has a delegate.
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(standardAboutPanelWillClose:)
name:NSWindowWillCloseNotification
object:_standardAboutPanel];
break;
}
}
NSLog(@"_standardAboutPanel is now %@", _standardAboutPanel);
NSLog(@"[_standardAboutPanel delegate] is now %@",
[_standardAboutPanel delegate]);
}
- (void)standardAboutPanelWillClose:(NSNotification *)aNotification
{
if ([aNotification object] == _standardAboutPanel)
{
NSLog(@"_standardAboutPanel will close");
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:NSWindowWillCloseNotification
object:_standardAboutPanel];
[_standardAboutPanel release];
_standardAboutPanel = nil;
}
}
@end
-----END SAPHackApp.m-----
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.