Re: Recognizing standard about box
Re: Recognizing standard about box
- Subject: Re: Recognizing standard about box
- From: Ryan Stevens <email@hidden>
- Date: Fri, 28 Jun 2002 07:16:49 -0700
On Thursday, June 27, 2002, at 08:54 PM, Andy Lee wrote:
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.
How big is the about panel? Can your windows/panels be the same size?
How likely is that to happen?
What about doing a count on the contained views?
Do the about panel's views have tags? What are they?
Are there any other things (delegates, lack of title!?, etc.) you can
get a hold of that may give info you can use to figure it out?
Just some random ideas off the top. <shrug>
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.
_______________________________________________
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.