First of all, I must tell you that I am new to Objective-C and Cocoa.
I have read several books about this, and now I can create fairly simple programs.
there were 15 days that I was stuck in the program that I am trying to build, and I really don't know anymore where to look.
I want to create a program that can change the brightness of my monitor using DDC / CI, and I want to show / hide the window (where the brightness level is written) in the same way as the brightness of an Apple Leopard or Snow Leopard with the same style.
Using RegisterEventHotKeyvarious functions of IOservices, I was able to increase the brightness, when I press F2 and decrease it, I press F1.
Using a custom NSWindow (TransparentWindow) and a custom NSView (RoundedView), I was able to get a window that displays just like Apple's brightness panel. I put it on awakeFromNib and it looks right and stays there.
What I cannot achieve (and I'm really crazy about it) is to show the window only when I press F1 or F2. (to hide this, I have alredy implemented NSTimer, but now it's offtopic)
I tried different ways:
1) From the NSobject class where I implement RegisterEventHotKey, I created an instance of TransparentWindow, and then sent it orderOutto this instance.
2) I used NSNotificationCenter to send a notification directly to the TransparentWindow class and call orderOutfrom there.
3) and many others that I do not remember now.
, awakeFromNib ( ), , orderOut ( ).
:
TransparentWindow.h:
#import <Cocoa/Cocoa.h>
@interface TransparentWindow : NSWindow
{
IBOutlet NSWindow *window;
}
@property (retain) IBOutlet NSWindow *window;
@end
TransparentWindow.m:
#import "TransparentWindow.h"
@implementation TransparentWindow
@synthesize window;
- (id)initWithContentRect:(NSRect)contentRect
styleMask:(unsigned int)aStyle
backing:(NSBackingStoreType)bufferingType
defer:(BOOL)flag {
window = [super initWithContentRect:contentRect
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO];
if (window != nil) {
[window setLevel: NSStatusWindowLevel];
[window setBackgroundColor: [NSColor clearColor]];
[window setAlphaValue:1.0];
[window setOpaque:NO];
[window setHasShadow:NO];
[window setIgnoresMouseEvents: YES];
NSLog(@"%p", window);
}
return window;
}
- (BOOL) canBecomeKeyWindow
{
return YES;
}
- (void)notify {
[[NSNotificationCenter defaultCenter] postNotificationName:@"MyNotification" object:self];
}
- (void)handleNotification:(NSNotification*)note {
[window orderOut:self];
}
@end
RoundedView.h:
#import <Cocoa/Cocoa.h>
@interface RoundedView : NSView
{
}
@end
RoundedView.m:
#import "RoundedView.h"
@implementation RoundedView
- (void)drawRect:(NSRect)rect
{
NSColor *bgColor = [NSColor colorWithCalibratedWhite:0.0 alpha:0.25];
NSRect bgRect = rect;
int minX = NSMinX(bgRect);
int midX = NSMidX(bgRect);
int maxX = NSMaxX(bgRect);
int minY = NSMinY(bgRect);
int midY = NSMidY(bgRect);
int maxY = NSMaxY(bgRect);
float radius = 20.0;
NSBezierPath *bgPath = [NSBezierPath bezierPath];
[bgPath moveToPoint:NSMakePoint(midX, minY)];
[bgPath appendBezierPathWithArcFromPoint:NSMakePoint(maxX, minY)
toPoint:NSMakePoint(maxX, midY)
radius:radius];
[bgPath appendBezierPathWithArcFromPoint:NSMakePoint(maxX, maxY)
toPoint:NSMakePoint(midX, maxY)
radius:radius];
[bgPath appendBezierPathWithArcFromPoint:NSMakePoint(minX, maxY)
toPoint:NSMakePoint(minX, midY)
radius:radius];
[bgPath appendBezierPathWithArcFromPoint:bgRect.origin
toPoint:NSMakePoint(midX, minY)
radius:radius];
[bgPath closePath];
[bgColor set];
[bgPath fill];
}
MainProgram.h:
#import <Cocoa/Cocoa.h>
#import <carbon/carbon.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <IOKit/IOKitLib.h>
#include <ApplicationServices/ApplicationServices.h>
#include <IOKit/i2c/IOI2CInterface.h>
@interface MainProgram : NSObject {
}
@end
MainProgram.m:
#import "MainProgram.h"
#import <Carbon/Carbon.h>
#import "TransparentWindow.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <IOKit/IOKitLib.h>
#include <ApplicationServices/ApplicationServices.h>
#include <IOKit/i2c/IOI2CInterface.h>
static OSStatus OnHotKeyEvent(EventHandlerCallRef nextHandler,EventRef theEvent,void *userData);
extern int level;
@implementation MainProgram
- (void)awakeFromNib
{
EventHotKeyRef gMyHotKeyRef;
EventHotKeyID gMyHotKeyID;
EventTypeSpec eventType;
eventType.eventClass=kEventClassKeyboard;
eventType.eventKind=kEventHotKeyPressed;
InstallApplicationEventHandler(&OnHotKeyEvent, 1, &eventType, NULL, NULL);
gMyHotKeyID.signature='htk1';
gMyHotKeyID.id=1;
RegisterEventHotKey(122, NULL, gMyHotKeyID, GetApplicationEventTarget(), 0, &gMyHotKeyRef);
gMyHotKeyID.signature='htk2';
gMyHotKeyID.id=2;
RegisterEventHotKey(120, NULL, gMyHotKeyID, GetApplicationEventTarget(), 0, &gMyHotKeyRef);
}
OSStatus OnHotKeyEvent(EventHandlerCallRef nextHandler,EventRef theEvent,
void *userData)
{
EventHotKeyID hkCom;
GetEventParameter(theEvent,kEventParamDirectObject,typeEventHotKeyID,NULL,
sizeof(hkCom),NULL,&hkCom);
int l = hkCom.id;
switch (l) {
case 1:
level = level - 5;
if (level<0) {
level = 0;
}
else {
BrightnessMain(level);
}
break;
case 2:
level = level + 5;
if (level>100) {
level = 100;
}
else {
BrightnessMain(level);
TransparentWindow *object3 = [[TransparentWindow alloc] init];
[[NSNotificationCenter defaultCenter] addObserver:object3 selector:@selector(handleNotification:) name:@"MyNotification" object:nil];
[object3 notify];
}
break;
}
return noErr;
}
@end
?
-, , , .
MainProgram.m:
TransparentWindow *object3 = [[TransparentWindow alloc] init];
:
NSRect contentRect;
NSSize contentSize;
contentSize.width = 210;
contentSize.height = 205;
contentRect.origin = NSMakePoint(855, 140);
contentRect.size = contentSize;
TransparentWindow *object3 = [[TransparentWindow alloc] initWithContentRect:contentRect
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO];
, , .
TransparentWindow.h:
#import <Cocoa/Cocoa.h>
@interface TransparentWindow : NSWindow
{
}
@end
TransparentWindow.m:
#import "TransparentWindow.h"
@implementation TransparentWindow
- (id)initWithContentRect:(NSRect)contentRect
styleMask:(unsigned int)aStyle
backing:(NSBackingStoreType)bufferingType
defer:(BOOL)flag {
self = [super initWithContentRect:contentRect
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO];
if (self != nil) {
[self setLevel: NSStatusWindowLevel];
[self setBackgroundColor: [NSColor clearColor]];
[self setAlphaValue:1.0];
[self setOpaque:NO];
[self setHasShadow:NO];
[self setIgnoresMouseEvents: YES];
NSLog(@"%p", self);
}
return self;
}
- (BOOL) canBecomeKeyWindow
{
return YES;
}
- (void)notify {
[[NSNotificationCenter defaultCenter] postNotificationName:@"MyNotification" object:self];
}
- (void)handleNotification:(NSNotification*)note {
[self orderOut:self];
}
@end
2:
makeKeyAndOrderFront orderFront, .
3 4 F1 F2 , F1 F2 , , :
RoundedFloatingPanel[2346] <Warning>: CGSResolveShmemReference : window.RO.dirtyRegion : Reference offset (38464) exceeds bounds (32768) on shmem obj 0x229
RoundedFloatingPanel[2346] <Warning>: CGSResolveShmemReference : window.RO : Reference offset (38144) exceeds bounds (32768) on shmem obj 0x229
RoundedFloatingPanel[2346] <Error>: kCGErrorFailure: CGSNewWindowWithOpaqueShape: Cannot map window information shmem
RoundedFloatingPanel[2346] <Error>: kCGErrorFailure: Set a breakpoint @ CGErrorBreakpoint() to catch errors as they are logged.
2011-02-17 16:01:42.895 RoundedFloatingPanel[2346:a0f] HIToolbox: ignoring exception 'Error (1000) creating CGSWindow' that raised inside Carbon event dispatch
(
0 CoreFoundation 0x91f186ba __raiseError + 410
1 libobjc.A.dylib 0x999e3509 objc_exception_throw + 56
2 CoreFoundation 0x91f183e8 +[NSException raise:format:arguments:] + 136
3 CoreFoundation 0x91f1835a +[NSException raise:format:] + 58
4 AppKit 0x93408915 _NXCreateWindow + 316
5 AppKit 0x93408720 _NSCreateWindow + 59
6 AppKit 0x93407946 -[NSWindow _commonAwake] + 1784
7 AppKit 0x9340456e -[NSWindow _commonInitFrame:styleMask:backing:defer:] + 1524
8 AppKit 0x934031c1 -[NSWindow _initContent:styleMask:backing:defer:contentView:] + 1568
9 AppKit 0x93402b9b -[NSWindow initWithContentRect:styleMask:backing:defer:] + 71
10 RoundedFloatingPanel 0x000029a6 -[TransparentWindow initWithContentRect:styleMask:backing:defer:] + 119
11 RoundedFloatingPanel 0x000031ec OnHotKeyEvent + 447
12 HIToolbox 0x95ff0ecf _ZL23DispatchEventToHandlersP14EventTargetRecP14OpaqueEventRefP14HandlerCallRec + 1567
13 HIToolbox 0x95ff0196 _ZL30SendEventToEventTargetInternalP14OpaqueEventRefP20OpaqueEventTargetRefP14HandlerCallRec + 411
14 HIToolbox 0x95fefff5 SendEventToEventTargetWithOptions + 58
15 HIToolbox 0x96024c18 _ZL29ToolboxEventDispatcherHandlerP25OpaqueEventHandlerCallRefP14OpaqueEventRefPv + 3006
16 HIToolbox 0x95ff1320 _ZL23DispatchEventToHandlersP14EventTargetRecP14OpaqueEventRefP14HandlerCallRec + 2672
17 HIToolbox 0x95ff0196 _ZL30SendEventToEventTargetInternalP14OpaqueEventRefP20OpaqueEventTargetRefP14HandlerCallRec + 411
18 HIToolbox 0x96012a07 SendEventToEventTarget + 52
19 AppKit 0x93460c3e -[NSApplication sendEvent:] + 7494
20 AppKit 0x933f42a7 -[NSApplication run] + 917
21 AppKit 0x933ec2d9 NSApplicationMain + 574
22 RoundedFloatingPanel 0x00002368 main + 30
23 RoundedFloatingPanel 0x0000231e start + 54
24 ??? 0x00000001 0x0 + 1