[英]Gap above NSMenuItem custom view
I am using the setView:
method on an NSMenuItem
to set a custom view. 我使用
setView:
方法上NSMenuItem
设置自定义视图。 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: 具有此自定义视图的
NSMenuItem
是菜单中的第一个,但问题是它与菜单顶部没有齐平,有一个很大的差距,你可以在这里看到:
Why is this happening and how can I stop it? 为什么会这样,我怎么能阻止它呢?
EDIT 编辑
I am using this code now but I am getting EXC_BAD_ACCESS
on the line InstallControlEventHandler
. 我现在正在使用此代码,但我在
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;
}
Also note the line metrics.top = 0
this is the line which should remove the gap at the top. 还要注意行
metrics.top = 0
这是应该删除顶部间隙的行。 However I cannot get it work that far. 但是我无法让它工作到那么远。 Does anyone know why I would be recieving an
EXC_BAD_ACCESS
there. 有谁知道为什么我会在那里收到
EXC_BAD_ACCESS
。 I have already created and allocated statusMenu
so surely it should work? 我已经创建并分配了
statusMenu
所以它肯定应该有效吗?
Your post is tagged "Objective-C" and "Cocoa", although your sample code is C and Carbon. 您的帖子被标记为“Objective-C”和“Cocoa”,尽管您的示例代码是C和Carbon。 I assume you'd prefer a Cocoa solution?
我想你更喜欢Cocoa解决方案?
It's actually pretty simple in Cocoa. 在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
Use it like this: 像这样使用它:
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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.