Używam metody setView:
na NSMenuItem
, aby ustawić niestandardowy widok. W tym niestandardowym widoku znajduje się obraz, który zajmuje cały widok. NSMenuItem
z tego widoku niestandardowego jest pierwszym w menu, ale problemem jest to, że nie siedzieć w jednej płaszczyźnie z góry menu, istnieje duża różnica jak widać tutaj:Gap powyżej NSMenuItem niestandardowy widok
Dlaczego czy to się dzieje i jak mogę to powstrzymać?
EDIT
używam tego kodu, ale teraz jestem coraz EXC_BAD_ACCESS
na linii 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;
}
Również zwrócić uwagę na linię metrics.top = 0
jest to linia, która powinna usunąć lukę na górze. Jednak nie mogę zrobić tego tak daleko. Czy ktoś wie, dlaczego dostałbym tam EXC_BAD_ACCESS
. Mam już utworzone i przydzielone statusMenu
, więc na pewno powinno działać?
Wygląda na to, że jest biały spacer na górze i na dole każdej menu. Chciałbym też wiedzieć, czy można tego uniknąć. –
Zakładam, że czarna część jest obrazem, a nie luką? Między górną i dolną częścią menu znajduje się dopełnienie, oprócz elementów separujących, ze względów estetycznych. Nie jestem pewien, czy jest to wykonane NSMenu lub NSMenuItem, ale może trzeba podklasy jednego lub drugiego, aby temu zapobiec. – d11wtq
Zrobiłem kilka badań i pojawiłem się na http://www.mail-archive.com/[email protected]/msg26997.html Wygląda na to, że potrzebne będzie niestandardowe NSMenu i trochę prywatnego majsterkowania API . –