/* http://developer.apple.com/samplecode/MethodReplacement/listing3.html */
#import <AppKit/AppKit.h>
#import <objc/runtime.h>
@interface NSWindow (TestMethodReplacement)
- (void)TestMethodReplacement_sendEvent:(NSEvent *)event;
@end
@implementation NSWindow (TestMethodReplacement)
+ (void)load {
if (self == [NSWindow class]) {
// Swap the implementations of -[NSWindow sendEvent:] and -[NSWindow TestMethodReplacement_sendEvent:].
// When the -sendEvent: message is sent to an NSWindow instance, -TestMethodReplacement_sendEvent: will
// be called instead. Calling [self TestMethodReplacement_sendEvent:event] thus calls the original method.
Method originalMethod = class_getInstanceMethod(self, @selector(sendEvent:));
Method replacedMethod = class_getInstanceMethod(self, @selector(TestMethodReplacement_sendEvent:));
method_exchangeImplementations(originalMethod, replacedMethod);
}
}
- (void)TestMethodReplacement_sendEvent:(NSEvent *)event {
if ([event type] == NSLeftMouseDown && [event modifierFlags] & NSCommandKeyMask) {
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:1.0];
[[self animator] setAlphaValue:0.0];
[NSAnimationContext endGrouping];
} else {
// Call the original sendEvent: method, whose implementation was exchanged with our own.
// Note: this ISN'T a recursive call, because this method should have been called through -sendEvent:.
NSParameterAssert(_cmd == @selector(sendEvent:));
[self TestMethodReplacement_sendEvent:event];
}
}
@end