Gap高于NSMenuItem自定义视图 [英] Gap above NSMenuItem custom view

查看:118
本文介绍了Gap高于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?

EDIT

我现在正在使用这个代码,但我得到 EXC_BAD_ACCESS c $ c> InstallControlEventHandler 。

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;

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

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