2013-07-09 3 views
1

Я пытаюсь создать приложение для Cocoa без nib/xib (Нет, я не хочу использовать nib/xib. Я хочу быть в полный контроль программно), и я, похоже, не могу поймать события, такие как нажатия клавиш и щелчки мышью. Вот код, который я до сих пор:Как я могу обработать события какао в полноэкранном приложении

main.m

#import <Cocoa/Cocoa.h> 
#import "AppDelegate.h" 

int main(int argc, char *argv[]) 
{ 
    @autoreleasepool { 
     NSApplication *app = [NSApplication sharedApplication]; 

     AppDelegate *appDelegate = [[AppDelegate alloc] init]; 

     [app setDelegate:appDelegate]; 
     [app activateIgnoringOtherApps:YES]; 
     [app run]; 
    } 
    return EXIT_SUCCESS; 
} 

AppDelegate.h/м

#import <Cocoa/Cocoa.h> 

@interface AppDelegate : NSObject <NSApplicationDelegate> 
{ 
    NSWindow *window; 
} 

@end 

#import "AppDelegate.h" 
#import "GLView.h" 

@implementation AppDelegate 

- (id)init{ 
    self = [super init]; 
    if (!self) { 
     return nil; 
    } 

    NSRect bounds = [[NSScreen mainScreen] frame]; 

    GLView *view = [[GLView alloc]initWithFrame:bounds]; 

    window = [[NSWindow alloc] initWithContentRect:bounds 
           styleMask:NSBorderlessWindowMask 
           backing:NSBackingStoreBuffered 
           defer:NO]; 
    [window setReleasedWhenClosed:YES]; 
    [window setAcceptsMouseMovedEvents:YES]; 
    [window setContentView:view]; 

    return self; 
} 

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    [window makeKeyAndOrderFront:self]; 
} 

@end 

GLView.h/м

#import <Cocoa/Cocoa.h> 

@interface GLView : NSView 

@end 

#import "GLView.h" 

@implementation GLView 

- (id)initWithFrame:(NSRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     // Initialization code here. 
    } 

    return self; 
} 

- (void)drawRect:(NSRect)dirtyRect 
{ 
    // Drawing code here. 
} 

- (BOOL)canBecomeKeyView 
{ 
    return YES; 
} 

- (BOOL)acceptsFirstResponder 
{ 
    return YES; 
} 

- (BOOL)becomeFirstResponder 
{ 
    return YES; 
} 

- (BOOL)resignFirstResponder 
{ 
    return YES; 
} 

- (void)keyDown:(NSEvent *)theEvent 
{ 
    NSString* const character = [theEvent charactersIgnoringModifiers]; 
    unichar  const code  = [character characterAtIndex:0]; 

    NSLog(@"Key Down: %hu", code); 

    switch (code) 
    { 
     case 27: 
     { 
      EXIT_SUCCESS; 
      break; 
     } 
    } 
} 

- (void)keyUp:(NSEvent *)theEvent 
{ 

} 
@end 

Ничто из того, что я пробовал для него, не сработало. Я думал, что, установив представление в качестве первого ответчика, я смог бы получить события. Пока ... Не работает. Любые идеи о том, как я могу это исправить? Помните, NO NIB.

Спасибо, Тайлер

ответ

1

Во-первых, вы должны убедиться, что ваше окно может фактически стать ключом, с помощью подклассов и возвращения YES из canBecomeKeyWindow, потому что windows without title bars cannot become key by default.

Затем ваша цель сборки должна быть приложением. Я бы предположил, что вы начинаете с шаблона инструмента командной строки в Xcode. Это хорошо, но вам нужно создать пакет приложений, чтобы приложение могло получать ключевые события. Создайте новую цель в своем проекте, которая будет создавать приложение Cocoa. Он должен иметь файл Info.plist (из которого вы хотите удалить запись «Основной базовый класс файла nib») и создать фазу сборки «Copy Bundle Resources».

Я не могу понять, что все остальные различия в процессе сборки, но начиная с вашего кода, я получил окно, чтобы принять ключевые события с этими двумя шагами.

+0

Большое спасибо Josh! Я не знал, что окна без заголовков не могут стать ключевыми по умолчанию. Я по-настоящему создавал приложение для какао по умолчанию, но потом сделал так, как вы сказали, и я создал свой собственный класс подкласса NSWindow, а в разделе реализации добавлено ' - (BOOL) canBecomeKeyWindow { return YES; } ' Теперь мой журнал показывает каждый клик отлично. Еще раз, спасибо. – SonarSoundProgramming

+0

Отлично, рад, что я мог бы помочь. –