2010-12-26 2 views
18

나는 NSMenuItem에서 setView: 메서드를 사용하여 사용자 정의보기를 설정합니다. 이 사용자 정의보기에는 전체보기를 차지하는 이미지가 있습니다.위의 갭 NSMenuItem 사용자 정의보기

alt text

이유 :이 사용자 정의보기를 가진 NSMenuItem 메뉴의 첫 번째하지만 문제는이 메뉴 상단과 같은 높이 앉아하지 않습니다, 당신은 여기에서 볼 수 있듯이 큰 차이가있다 이 일이 어떻게되고 그것을 멈출 수 있습니까?


지금이 코드를 사용하고 있지만이 라인 InstallControlEventHandlerEXC_BAD_ACCESS을 얻고있다

편집 할 수 있습니다.

-(void)applicationDidFinishLaunching:(NSNotification *)aNotification { 
    HIViewRef contentView; 
    MenuRef menuRef = [statusMenu carbonMenuRef]; 

    HIMenuGetContentView(menuRef, kThemeMenuTypePullDown, &contentView); 

    EventTypeSpec hsEventSpec[1] = { 
     { kEventClassMenu, kEventMenuCreateFrameView } 
    }; 

    InstallControlEventHandler(contentView, 
          NewEventHandlerUPP((EventHandlerProcPtr)hsMenuCreationEventHandler), 
          GetEventTypeCount(hsEventSpec), 
          hsEventSpec, 
          NULL, 
          NULL); // Get EXC_BAD_ACCESS here. 
} 

static OSStatus hsMenuContentEventHandler(EventHandlerCallRef caller, EventRef event, void* refcon) 
{ 
    OSStatus err; 

    check(GetEventClass(event) == kEventClassControl); 
    check(GetEventKind(event) == kEventControlGetFrameMetrics); 

    err = CallNextEventHandler(caller, event); 
    if (err == noErr) 
    { 
     HIViewFrameMetrics metrics; 

     verify_noerr(GetEventParameter(event, kEventParamControlFrameMetrics, typeControlFrameMetrics, NULL, 
             sizeof(metrics), NULL, &metrics)); 

     metrics.top = 0; 

     verify_noerr(SetEventParameter(event, kEventParamControlFrameMetrics, typeControlFrameMetrics, 
             sizeof(metrics), &metrics)); 
    } 

    return err; 
} 

static OSStatus hsMenuCreationEventHandler(EventHandlerCallRef caller, EventRef event, void* refcon) 
{ 
    OSStatus err = eventNotHandledErr; 

    if (GetEventKind(event) == kEventMenuCreateFrameView) 
    { 
     err = CallNextEventHandler(caller, event); 
     if (err == noErr) 
     { 
      static const EventTypeSpec kContentEvents[] = 
      { 
       { kEventClassControl, kEventControlGetFrameMetrics } 
      }; 

      HIViewRef   frame; 
      HIViewRef   content; 

      verify_noerr(GetEventParameter(event, kEventParamMenuFrameView, typeControlRef, NULL, 
              sizeof(frame), NULL, &frame)); 
      verify_noerr(HIViewFindByID(frame, kHIViewWindowContentID, &content)); 
      InstallControlEventHandler(content, hsMenuContentEventHandler, GetEventTypeCount(kContentEvents), 
             kContentEvents, 0, NULL); 
     } 
    } 

    return err; 
} 

의이 상단에있는 간극을 제거한다 라인 선 metrics.top = 0 참고. 그러나 나는 그렇게까지 일할 수 없습니다. 누구든지 내가 왜 EXC_BAD_ACCESS을 받는지 알 수 있습니까? 나는 이미 만들어서 statusMenu을 할당 했으므로 확실하게 작동해야합니까?

+0

것 같습니다. 나는 또한 그것을 피할 수 있는지 알고 싶습니다. –

+0

검정색 부분이 이미지가 아니라 틈새라고 가정합니다. 미묘한 이유 때문에 구분 기호 항목 사이뿐만 아니라 메뉴의 상단과 하단 사이에 약간의 패딩이 있습니다. 이 일을 NSMenu 또는 NSMenuItem, 잘 모르겠지만 중 하나 또는 다른이를 방지하기 위해 하위 클래스가 필요할 수 있습니다. – d11wtq

+0

몇 가지 조사를 해본 결과이 http://www.mail-archive.com/[email protected]/msg26997.html 사용자 지정 NSMenu가 필요하고 일부 개인 API 땜질이처럼 보입니다. . –

답변

15

샘플 코드가 C 및 Carbon이지만 게시물에 "Objective-C"및 "Cocoa"태그가 지정됩니다. 나는 당신이 코코아 솔루션을 선호한다고 가정합니까?

실제로 코코아에서는 매우 간단합니다. 유일한 트릭은 줄 밖의 그림 그리는 방법을 배우는 것입니다. :-)

@interface FullMenuItemView : NSView 
@end 

@implementation FullMenuItemView 
- (void) drawRect:(NSRect)dirtyRect 
{ 
    NSRect fullBounds = [self bounds]; 
    fullBounds.size.height += 4; 
    [[NSBezierPath bezierPathWithRect:fullBounds] setClip]; 

    // Then do your drawing, for example... 
    [[NSColor blueColor] set]; 
    NSRectFill(fullBounds); 
} 
@end 

이처럼 사용하여 모든 메뉴의 상단과 하단에 흰색 스페이서가 같은

CGFloat menuItemHeight = 32; 

NSRect viewRect = NSMakeRect(0, 0, /* width autoresizes */ 1, menuItemHeight); 
NSView *menuItemView = [[[FullMenuItemView alloc] initWithFrame:viewRect] autorelease]; 
menuItemView.autoresizingMask = NSViewWidthSizable; 

yourMenuItem.view = menuItemView; 
+0

잘 작동합니다! 'initWithRect :'가'initWithFrame :'이어야한다고 말했지만, 코드에서 오타가 발견되었습니다. 대단히 고마워, 나는 결코 이것처럼 쉽지 않을 것이다! – Joshua

+0

오, 고마워, 오타가 수정되었습니다. 다행히 당신의 문제를 해결했습니다! – skue

+0

joshua : 위의 코드가 EXC_BAD_ACCESS없이 작동하려면 여전히 http : // stackoverflow 게시물을 확인하십시오.com/questions/6633843/how-to-remove-nsmenuitem-gap- 위의 사용자 정의보기 해결 – AmitSri