我在HoudahSpot 2的早期版本中也有同樣的需求。我確實得到了它的一個限制:我的代碼在底部留下方形角的菜單。
我已經放棄了這個設置,因爲HoudahSpot中的BlitzSearch功能發展到需要更復雜的用戶界面,所以我在NSMenu中使用NSViews遇到了其他限制。
無論如何,這裏是原代碼服用這些額外的3個像素的護理:
- (void)awakeFromNib
{
HIViewRef contentView;
MenuRef menuRef = [statusMenu carbonMenuRef];
HIMenuGetContentView (menuRef, kThemeMenuTypePullDown, &contentView);
EventTypeSpec hsEventSpec[1] = {
{ kEventClassMenu, kEventMenuCreateFrameView }
};
HIViewInstallEventHandler(contentView,
NewEventHandlerUPP((EventHandlerProcPtr)hsMenuCreationEventHandler),
GetEventTypeCount(hsEventSpec),
hsEventSpec,
NULL,
NULL);
}
#pragma mark -
#pragma mark Carbon handlers
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));
HIViewInstallEventHandler(content, hsMenuContentEventHandler, GetEventTypeCount(kContentEvents),
kContentEvents, 0, NULL);
}
}
return err;
}
對不起,我忘了一點:
- (MenuRef) carbonMenuRef
{
MenuRef carbonMenuRef = NULL;
if (carbonMenuRef == NULL) {
extern MenuRef _NSGetCarbonMenu(NSMenu *);
carbonMenuRef = _NSGetCarbonMenu(self);
if (carbonMenuRef == NULL) {
NSMenu *theMainMenu = [NSApp mainMenu];
NSMenuItem *theDummyMenuItem = [theMainMenu addItemWithTitle: @"sub" action: NULL keyEquivalent: @""];
if (theDummyMenuItem != nil) {
[theDummyMenuItem setSubmenu:self];
[theDummyMenuItem setSubmenu:nil];
[theMainMenu removeItem:theDummyMenuItem];
carbonMenuRef = _NSGetCarbonMenu(self);
}
}
}
if (carbonMenuRef == NULL) {
extern MenuRef _NSGetCarbonMenu2(NSMenu *);
carbonMenuRef = _NSGetCarbonMenu2(self);
}
return carbonMenuRef;
}
的代碼看起來很有希望,但我一直沒能得到它的工作呢。它在我爲Xcode構建時會產生很多錯誤和警告,現在可能所有這些都被棄用了? – alistairholt 2010-11-01 11:31:18
我用_NSGetCarbonMenu(菜單)替換[menu carbonMenuRef]後實際上沒有錯誤,但它似乎沒有影響菜單。 – alistairholt 2010-11-01 11:44:38
重要的一行是「metrics.top = 0;」 – 2010-11-02 06:54:13