Windows의 동기식 트랙 포퍼 머 메누에 대한 코코아에는 동등한 기술이 있습니까?

StackOverflow https://stackoverflow.com/questions/227935

  •  03-07-2019
  •  | 
  •  

문제

RightMouse 이벤트에 응답하여 컨텍스트 메뉴를 표시하고 실행하고 선택한 메뉴 항목에 응답하는 함수를 호출하고 싶습니다. Windows에서는 tpm_returncmd 플래그와 함께 TrackPopupMenu를 사용할 수 있습니다.

코코아에서 이것을 구현하는 가장 쉬운 방법은 무엇입니까? NSMenu처럼 보입니다 : PopupContextMenu는 지정된 NSVIEW에 이벤트를 게시하려고합니다. 더미보기를 만들고 돌아 오기 전에 이벤트를 기다려야합니까? 그렇다면 내 메인으로 돌아 오지 않는 것이 "대기"또는 플러시 이벤트는 어떻게해야합니까?

도움이 되었습니까?

해결책 2

PopupContextMenu는 이미 동기식 인 것 같습니다. NSMENU를 NSVIEW에 알리지 않고 사용하는 방법을 보지 못했기 때문에 임시 NSVIEW를 인스턴스화하는 체계를 생각해 냈습니다. 목표는 팝업 메뉴를 표시하고 단일 기능 호출의 맥락에서 선택한 항목을 반환하는 것입니다. 다음은 제안 된 솔루션의 코드 스 니펫입니다.

// Dummy View class used to receive Menu Events

@interface DVFBaseView : NSView
{
    NSMenuItem* nsMenuItem;
}
- (void) OnMenuSelection:(id)sender;
- (NSMenuItem*)MenuItem;
@end

@implementation DVFBaseView
- (NSMenuItem*)MenuItem
{
    return nsMenuItem;
}

- (void)OnMenuSelection:(id)sender
{
    nsMenuItem = sender;
}

@end

// Calling Code (in response to rightMouseDown event in my main NSView

void HandleRButtonDown (NSPoint pt)
{
    NSRect    graphicsRect;  // contains an origin, width, height
    graphicsRect = NSMakeRect(200, 200, 50, 100);

    //-----------------------------
    // Create Menu and Dummy View
    //-----------------------------

    nsMenu = [[[NSMenu alloc] initWithTitle:@"Contextual Menu"] autorelease];
    nsView = [[[DVFBaseView alloc] initWithFrame:graphicsRect] autorelease];

    NSMenuItem* item = [nsMenu addItemWithTitle:@"Menu Item# 1" action:@selector(OnMenuSelection:) keyEquivalent:@""];

    [item setTag:ID_FIRST];

    item = [nsMenu addItemWithTitle:@"Menu Item #2" action:@selector(OnMenuSelection:) keyEquivalent:@""];

    [item setTag:ID_SECOND];
    //---------------------------------------------------------------------------------------------
// Providing a valid windowNumber is key in getting the Menu to display in the proper location
//---------------------------------------------------------------------------------------------

    int windowNumber = [(NSWindow*)myWindow windowNumber];
    NSRect frame = [(NSWindow*)myWindow frame];
    NSPoint wp = {pt.x, frame.size.height - pt.y};  // Origin in lower left

    NSEvent* event = [NSEvent otherEventWithType:NSApplicationDefined
                     location:wp
                     modifierFlags:NSApplicationDefined 
                     timestamp: (NSTimeInterval) 0
                     windowNumber: windowNumber
                     context: [NSGraphicsContext currentContext]
                     subtype:0
                     data1: 0
                     data2: 0]; 

    [NSMenu popUpContextMenu:nsMenu withEvent:event forView:nsView];      
    NSMenuItem* MenuItem = [nsView MenuItem];

    switch ([MenuItem tag])
    {
    case ID_FIRST: HandleFirstCommand(); break;
    case ID_SECOND: HandleSecondCommand(); break;
    }
 }

다른 팁

Cocoa에서이를 수행하는 '적절한'방법은 메뉴 항목의 대상과 작업이 필요한 방법을 수행하도록하는 것입니다. 그러나 초기 통화 내에서 해야하는 경우 사용할 수 있습니다. [NSView nextEventMatchingMask:] 관심있는 새로운 이벤트를 지속적으로 가져 오려면 처리하고 처리하고 고리하십시오. 오른쪽 마우스 버튼이 해제 될 때까지 기다리는 예는 다음과 같습니다. 당신은 아마도 더 복잡한 마스크 인수를 사용하고 지속적으로 호출하고 싶을 것입니다. [NSView nextEventMatchingMask:] 당신이 원하는 것을 얻을 때까지.

NSEvent *localEvent = [[self window] nextEventMatchingMask: NSRightMouseUpMask];

나는 당신이 훨씬 쉽게 진행할 '적절한'방법을 찾을 것이라고 생각합니다.

더 이상 사용되지 않는 탄소를 제외하고는 직접 동등한 것이 없습니다.

마우스 오른쪽 버튼을 클릭하려면 팔로우하십시오 이 지침. 그들은 마우스 오른쪽 클릭과 오른쪽 클릭을 올바르게 감지하고 메뉴를 표시해야 할 때 메뉴를 표시하고하지 말아야 할 때 표시하지 않아야합니다.

다음 행사의 경우 시도해 볼 수 있습니다 [[NSRunLoop currentRunLoop] runMode:NSEventTrackingRunLoopMode untilDate:[NSDate distantFuture]]. 사용자가 메뉴 항목 중 하나를 선택할 때까지이를 반복적으로 호출해야합니다.

사용 nextEventMatchingMask:NSRightMouseUpMask 전혀 또는 대부분의 경우에는 작동하지 않습니다. 사용자가 오른쪽으로클릭 컨트롤에서는 메뉴 항목을 선택하지 않고 오른쪽 마우스 버튼이 다운 직후에 올라갑니다. 메뉴 항목 선택은 왼쪽 마우스 버튼을 통해 (반드시 필요하지는 않지만) 발생할 수 있습니다. 사용자가 무언가를 선택하거나 메뉴를 해제 할 때까지 런 루프를 반복적으로 실행하는 것이 좋습니다.

사용자가 아무것도 선택하지 않고 메뉴를 해산했다고 말하는 방법을 모르겠습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top