tags:

views:

1228

answers:

3

I'm learning how to build program with Cocoa. I'm using a sample Apple application that record video from WebCam. I'd like to start ant stop video capture by key press. I've tried to override Keydown event but I've read that It's not possible in an NSObject. How can I handle this kind of event?

The class of application extends a NSObject class.

This is the code:

- (void)keyDown:(NSEvent *)event {
  NSLog(@"Hi there");
  NSString *characters = [event characters];
  if ([characters length]) {
    switch ([characters characterAtIndex:0]) {
      case NSUpArrowFunctionKey:
      NSLog(@"Key UP");
      break;
  }
}

}

thanks a lot and sorry for my very bad english!

Andrea

PS: What's a very good book to start learn MacOS Programming?

+2  A: 

I've tried to override Keydown event but I've read that It's not possible in an NSObject.

Correct. Only a responder can respond to events.

How can I handle this kind of event?

Implement a responder. Subclassing NSWindow or NSWindowController will work. Make sure you make your actual window or window controller an instance of your subclass.

The Cocoa documentation explains further.

The class of application extends a NSObject class.

Why? Normally, the principal class of the application bundle is NSApplication or a subclass of that—and there aren't many good reasons to subclass NSApplication.

PS: What's a very good book to start learn MacOS Programming?

I didn't learn by the Hillegass book, myself (I stuck to Apple's docs), but it's a very popular recommendation and I have read it and can tell you it's good.

Peter Hosey
Be careful that the window controller, if present, is the last responder for events messages. The delegates only get action messages, not event messages.
IlDan
Good catch. I'll edit my answer to not claim that being the window delegate will work.
Peter Hosey
A: 

From the Cocoa Event-Handling Guide - The Responder Chain:

The responder chain is a linked series of responder objects to which an event or action message is applied. When a given responder object doesn’t handle a particular message, the object passes the message to its successor in the chain (that is, its next responder).

When you press a key the window receives the keyDown event. Then it dispatches the event to the first responder, that usually is the control with a blue bezel around its border (try to click on the address field in Safari or Firefox, when it's blue-bezeled then it has first-responder status).

If the first responder does not eat the keypress (the Safari address field does eat it when it displays a character) then it passes it down the responder chain to the next responder in the view hierarchy, then to the window and to the window controller as you can see in the Guide. (Take care that the action responder is another story.)

So you have to implement the keyDown: on a view of your window or in the window itself, if it has no views that eat events. The simplest way to test is to override the keyDown: method of an empty window

To put your hands into the inner workings you can even try overriding the sendEvent: method of a window. sendEvent: dispatches the events to the views of the window, and from there you can for example log all the events managed by the window.

IlDan
+1  A: 

Subclassing NSWindow or NSWindowController will work.

Similarly, you can subclass NSView and override its event-handling methods.

What's a very good book to start learn MacOS Programming?

Learn Objective-C on the Mac by Dalrymple is really straightforward, covers enough basics and moves fast enough to get you off the ground in a short bit. It touches on everything from Xcode and Interface Builder to OOP and Objective-C practices. Particularly helpful to beginners (IMHO) are the source file organization and Foundation kit chapters.

Best of luck!

Old McStopher
"Make sure you make your actual window or window controller an instance of your subclass." Another thanks to Peter. This helped on another thread: http://stackoverflow.com/questions/1854112/keyup-event-heard-overridden-nsview-method
Old McStopher