📄 carbonwindowadapter.mm
字号:
- (void)encodeWithCoder:(NSCoder *)coder { // Actually, this will probably never be implemented. M.P. Notice - 8/2/00 NSLog(@"-[NSCarbonWindow encodeWithCoder:] is not implemented.");}// There's no override of frame, despite the fact that NSWindow's returns _frame, because _frame is one of the instance variables whose value we're keeping synchronized with the Carbon window.// Do the right thing for a Carbon window.- (id)initWithCoder:(NSCoder *)coder { // Actually, this will probably never be implemented. M.P. Notice - 8/2/00 NSLog(@"-[NSCarbonWindow initWithCoder:] is not implemented."); [self release]; return nil;}// There's no override of level, despite the fact that NSWindow's returns _level, because _level is one of the instance variables whose value we're keeping synchronized with the Carbon window.// There's no override of miniaturize:, despite the fact that NSWindow's invokes [self windowNumber], because it looks like it might work on Carbon windows as is.// There's no override of resizeToScreenWithEvent:, despite the fact that NSWindow's operates on _windowNum.// It looks like it's only called when an _NSForceResizeEventType event is passed into -[NSWindow sendEvent:], and I can't find any instances of that happening./*// Do the right thing for a Carbon Window.- (void)sendEvent:(NSEvent *)theEvent { // Not all events are handled in the same manner. NSEventType eventType = [theEvent type]; if (eventType==NSAppKitDefined) { // Handle the event the Cocoa way. Carbon won't understand it anyway. [super sendEvent:theEvent]; } }*/// There's no override of setAcceptsMouseMovedEvents:, despite the fact that NSWindow's invokes [self windowNumber], because it looks like it might work on Carbon windows as is.// There's no override of setBackingType:, despite the fact that NSWindow's invokes [self windowNumber], because it's apparently not expected to do anything anyway, judging from the current implementation of PSsetwindowtype().// Do what NSWindow would do, but for a Carbon window.- (void)setContentView:(NSView *)aView { NSRect contentFrameRect; OSStatus osStatus; Rect windowContentBoundsRect; // Precondition check. assert(_borderView); assert([_borderView isKindOfClass:[CarbonWindowFrame class]]); assert(_windowRef); // Parameter check. assert(aView); assert([aView isKindOfClass:[CarbonWindowContentView class]]); // Find out the window's Carbon window structure region (content) bounds. osStatus = GetWindowBounds(_windowRef, kWindowContentRgn, &windowContentBoundsRect); if (osStatus!=noErr) NSLog(@"A Carbon window's content bounds couldn't be gotten."); contentFrameRect.origin = NSZeroPoint; contentFrameRect.size.width = windowContentBoundsRect.right - windowContentBoundsRect.left; contentFrameRect.size.height = windowContentBoundsRect.bottom - windowContentBoundsRect.top; // If the content view is still in some other view hierarchy, pry it free. [_contentView removeFromSuperview]; assert(![_contentView superview]); // Record the content view, and size it to this window's content frame. _contentView = aView; [_contentView setFrame:contentFrameRect]; // Make the content view a subview of the border view. [_borderView addSubview:_contentView]; // Tell the content view it's new place in the responder chain. [_contentView setNextResponder:self];}// There's no override of setDepthLimit:, despite the fact that NSWindow's invokes [self windowNumber], because it looks like it might work on Carbon windows as is.- (BOOL)worksWhenModal { WindowClass windowClass = [self _carbonWindowClass]; return (windowClass == kFloatingWindowClass || windowClass == kUtilityWindowClass);}- (void)_setModalWindowLevel { return;}- _clearModalWindowLevel { return nil;}// There's no override of setLevel:, despite the fact that NSWindow's invokes [self windowNumber], because it looks like it might work on Carbon windows as is.// I thought at first that there should be a mapping between Cocoa level and Carbon window class, but experiments convince me that such is not the case. M.P. Notice - 9/18/00// There's no override of windowNumber, despite the fact that NSWindow's returns _windowNum, because _windowNum is one of the instance variables whose value we're keeping synchronized with the Carbon window.- (UInt32)carbonHICommandIDFromActionSelector:(SEL)inActionSelector { // Initialize with the default return value. UInt32 hiCommandID = 0; // Pretty simple, if tedious. if (inActionSelector==@selector(clear:)) hiCommandID = kHICommandClear; else if (inActionSelector==@selector(copy:)) hiCommandID = kHICommandCopy; else if (inActionSelector==@selector(cut:)) hiCommandID = kHICommandCut; else if (inActionSelector==@selector(paste:)) hiCommandID = kHICommandPaste; else if (inActionSelector==@selector(redo:)) hiCommandID = kHICommandRedo; else if (inActionSelector==@selector(selectAll:)) hiCommandID = kHICommandSelectAll; else if (inActionSelector==@selector(undo:)) hiCommandID = kHICommandUndo; // Done. return hiCommandID;}- (void)sendCarbonProcessHICommandEvent:(UInt32)inHICommandID { EventTargetRef eventTargetRef; HICommand hiCommand; OSStatus osStatus; // Initialize for safe error handling. EventRef eventRef = NULL; // Create a Process Command event. Don't mention anything about the menu item, because we don't want the Carbon Event handler fiddling with it. hiCommand.attributes = 0; hiCommand.commandID = inHICommandID; hiCommand.menu.menuRef = 0; hiCommand.menu.menuItemIndex = 0; osStatus = CreateEvent(NULL, kEventClassCommand, kEventCommandProcess, GetCurrentEventTime(), kEventAttributeNone, &eventRef); if (osStatus!=noErr) { NSLog(@"CreateEvent() returned %i.", (int)osStatus); goto CleanUp; } osStatus = SetEventParameter(eventRef, kEventParamDirectObject, typeHICommand, sizeof(HICommand), &hiCommand); if (osStatus!=noErr) { NSLog(@"SetEventParameter() returned %i.", (int)osStatus); goto CleanUp; } // Send a Carbon event to whatever has the Carbon user focus. eventTargetRef = GetUserFocusEventTarget(); osStatus = SendEventToEventTarget(eventRef, eventTargetRef); if (osStatus!=noErr) { NSLog(@"SendEventToEventTarget() returned %i.", (int)osStatus); goto CleanUp; }CleanUp: // Clean up. if (eventRef) ReleaseEvent(eventRef);}- (Boolean)sendCarbonUpdateHICommandStatusEvent:(UInt32)inHICommandID withMenuRef:(MenuRef)inMenuRef andMenuItemIndex:(UInt16)inMenuItemIndex { EventTargetRef eventTargetRef; HICommand hiCommand; OSStatus osStatus; // Initialize for safe error handling and flag returning. Boolean eventWasHandled = FALSE; EventRef eventRef = NULL; // Create a Process Command event. Don't mention anything about the menu item, because we don't want the Carbon Event handler fiddling with it. hiCommand.attributes = kHICommandFromMenu; hiCommand.commandID = inHICommandID; hiCommand.menu.menuRef = inMenuRef; hiCommand.menu.menuItemIndex = inMenuItemIndex; osStatus = CreateEvent(NULL, kEventClassCommand, kEventCommandUpdateStatus, GetCurrentEventTime(), kEventAttributeNone, &eventRef); if (osStatus!=noErr) { NSLog(@"CreateEvent() returned %i.", (int)osStatus); goto CleanUp; } osStatus = SetEventParameter(eventRef, kEventParamDirectObject, typeHICommand, sizeof(HICommand), &hiCommand); if (osStatus!=noErr) { NSLog(@"SetEventParameter() returned %i.", (int)osStatus); goto CleanUp; } // Send a Carbon event to whatever has the Carbon user focus. eventTargetRef = GetUserFocusEventTarget(); osStatus = SendEventToEventTarget(eventRef, eventTargetRef); if (osStatus==noErr) { eventWasHandled = TRUE; } else if (osStatus!=eventNotHandledErr) { NSLog(@"SendEventToEventTarget() returned %i.", (int)osStatus); goto CleanUp; }CleanUp: // Clean up. if (eventRef) ReleaseEvent(eventRef); // Done. return eventWasHandled;}- (void)_handleRootBoundsChanged{ HIViewRef root = HIViewGetRoot( _windowRef ); HIRect frame; HIViewGetFrame( root, &frame ); [_borderView setFrameSize:*(NSSize*)&frame.size];}- (void)_handleContentBoundsChanged{ HIViewRef root, contentView; HIRect rootBounds, contentFrame; NSRect oldContentFrameRect; root = HIViewGetRoot( _windowRef ); HIViewFindByID( root, kHIViewWindowContentID, &contentView ); HIViewGetFrame( contentView, &contentFrame ); HIViewGetBounds( root, &rootBounds ); // Set the content view's frame rect from the Carbon window's content region bounds. contentFrame.origin.y = rootBounds.size.height - CGRectGetMaxY( contentFrame ); oldContentFrameRect = [_contentView frame]; if ( !NSEqualRects( *(NSRect*)&contentFrame, oldContentFrameRect ) ) { [_contentView setFrame:*(NSRect*)&contentFrame]; }}- (OSStatus)_handleCarbonEvent:(EventRef)inEvent callRef:(EventHandlerCallRef)inCallRef { OSStatus result = eventNotHandledErr; switch ( GetEventClass( inEvent ) ) { case kEventClassControl: { ControlRef control; check( GetEventKind( inEvent ) == kEventControlBoundsChanged ); GetEventParameter( inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof( ControlRef ), NULL, &control ); if ( control == HIViewGetRoot( _windowRef ) ) [self _handleRootBoundsChanged]; else [self _handleContentBoundsChanged]; } break; case kEventClassWindow: switch ( GetEventKind( inEvent ) ) { case kEventWindowShown: [self _setVisible:YES]; break; case kEventWindowHidden: [self _setVisible:NO]; break; case kEventWindowActivated: [self makeKeyWindow]; break; case kEventWindowDeactivated: [self resignKeyWindow]; break; case kEventWindowBoundsChanged: [self reconcileToCarbonWindowBounds]; break; } break; } return result;}// Handle various events that Carbon is sending to our window.static OSStatus NSCarbonWindowHandleEvent(EventHandlerCallRef inEventHandlerCallRef, EventRef inEventRef, void *inUserData) { // default action is to send event to next handler. We modify osStatus as necessary where we don't want this behavior OSStatus osStatus = eventNotHandledErr; // We do different things for different event types. CarbonWindowAdapter *carbonWindow = (CarbonWindowAdapter *)inUserData; osStatus = [carbonWindow _handleCarbonEvent: inEventRef callRef: inEventHandlerCallRef]; // Done. If we want to propagate the event, we return eventNotHandledErr to send it to the next handler return osStatus; }// [3364117] We need to make sure this does not fall through to the AppKit implementation! bad things happen.- (void)_reallyDoOrderWindow:(NSWindowOrderingMode)place relativeTo:(int)otherWin findKey:(BOOL)doKeyCalc forCounter:(BOOL)isACounter force:(BOOL)doForce isModal:(BOOL)isModal {}- (NSRect) _growBoxRect{ WindowAttributes attrs; NSRect retRect = NSZeroRect; GetWindowAttributes( _windowRef, &attrs ); if ( attrs & kWindowResizableAttribute ) { HIRect bounds, rect; HIViewRef view; HIViewGetBounds( HIViewGetRoot( _windowRef ), &bounds ); HIViewFindByID( HIViewGetRoot( _windowRef ), kHIViewWindowGrowBoxID, &view ); HIViewGetFrame( view, &rect ); rect.origin.y = bounds.size.height - CGRectGetMaxY( rect ) - 1; rect.origin.x++; retRect = *(NSRect*)▭ } return retRect;}@end // implementation CarbonWindowAdapter#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -