gpt4 book ai didi

objective-c - NSMenuItem 自定义 View 上方的间隙

转载 作者:太空狗 更新时间:2023-10-30 03:14:25 24 4
gpt4 key购买 nike

我在 NSMenuItem 上使用 setView: 方法来设置自定义 View 。在这个自定义 View 中,有一个图像占据了整个 View 。具有此自定义 View 的 NSMenuItem 是菜单中的第一个,但问题是它没有与菜单顶部齐平,如您在此处看到的那样,存在很大差距:

alt text

为什么会发生这种情况,我该如何阻止它?


编辑

我现在正在使用此代码,但我在 InstallControlEventHandler 行上收到了 EXC_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,所以它肯定可以工作吗?

最佳答案

尽管您的示例代码是 C 和 Carbon,但您的帖子被标记为“Objective-C”和“Cocoa”。我假设您更喜欢 Cocoa 解决方案?

在 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;

关于objective-c - NSMenuItem 自定义 View 上方的间隙,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4533816/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com