NSMenuItem 自定义视图上方的间隙 [英] Gap above NSMenuItem custom view

查看:22
本文介绍了NSMenuItem 自定义视图上方的间隙的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 NSMenuItem 上使用 setView: 方法来设置自定义视图.在这个自定义视图中有一个图像,它占据了整个视图.带有这个自定义视图的 NSMenuItem 是菜单中的第一个,但问题是它没有与菜单顶部齐平,你可以在这里看到:

I am using the setView: method on an NSMenuItem to set a custom view. In this custom view there is an image which takes the whole of the view. The NSMenuItem with this custom view is the first in the menu but the problem is it doesn't sit flush with the top of the menu, there is a big gap as you can see here:

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

Why is this happening and how can I stop it?

编辑

我现在正在使用此代码,但我在 InstallControlEventHandler 行上收到 EXC_BAD_ACCESS.

I am using this code now but I am getting EXC_BAD_ACCESS on the line InstallControlEventHandler.

-(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 那么它肯定可以工作吗?

Also note the line metrics.top = 0 this is the line which should remove the gap at the top. However I cannot get it work that far. Does anyone know why I would be recieving an EXC_BAD_ACCESS there. I have already created and allocated statusMenu so surely it should work?

推荐答案

您的帖子被标记为Objective-C"和Cocoa",尽管您的示例代码是 C 和 Carbon.我想您更喜欢 Cocoa 解决方案?

Your post is tagged "Objective-C" and "Cocoa", although your sample code is C and Carbon. I assume you'd prefer a Cocoa solution?

在 Cocoa 中实际上非常简单.唯一的技巧是学习如何在线条外画画.:-)

It's actually pretty simple in Cocoa. The only trick is learning how to draw outside the lines. :-)

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

这篇关于NSMenuItem 自定义视图上方的间隙的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆