Получение mouseMoved / mouseDragged за пределами окна моего NSView - PullRequest
3 голосов
/ 13 июня 2011

В настоящее время я портирую приложение (или, если быть более точным, VST-плагин) из Windows в OSX. Я немного новичок в программировании OSX, но я использую Cocoa NSView, добавленный в окно Carbon (которое я получаю от хоста), используя HICocoaCreateView.

В любом случае ... Внутри этого представления я хочу получить события mouseMoved и mouseDragged, но при перетаскивании я также хочу получить эти события, даже когда мышь покидает мой NSView (и также родительское окно), но я просто не могу кажется, чтобы это произошло.

В Windows я бы сделал SetCapture для mouseDown, чтобы получить все события мыши на некоторое время. Самая близкая вещь, которую я нашел в Какао, это «addGlobalMonitorForEventsMatchingMask», но это только 10.6+, и мне трудно поверить, что это было невозможно сделать до этого. (В конце концов, это то, что обычно используется для перетаскиваемых компонентов, таких как полосы прокрутки и т. Д.)

Это сводит меня с ума!

UPDATE:

Также есть нечто, называемое CGEventTapCreate, которое, насколько я могу судить по скудным документам, похоже на addGlobalMonitor ... но в Carbon. Я не понял, как именно углерод и какао связаны друг с другом и что работает где. Можно ли его использовать, хотя мой основной материал - какао? (Окно, которое я получаю от хозяина, может быть как Какао, так и Углеродом. Это действительно беспорядок.)

Ответы [ 2 ]

3 голосов
/ 13 июня 2011

Материал CGEventTap не совсем углерод.Это в Кварце, который можно рассматривать как подкаркас Какао (который на самом деле просто конгломерат других каркасов).Carbon - это устаревшая (и не рекомендуемая) среда, которая была создана для облегчения перехода между Mac OS 9, где разработка приложений в основном выполнялась на C, и Mac OS X, где используется Objective-C.Не каждая функция C, предоставляемая Apple, является Carbon;Кварц и Grand Central Dispatch сразу же приходят на ум как современные фреймворки, использующие C (я полагаю, из-за небольшого преимущества в скорости).

После того, как фон был удален, эти функции прекрасно работают с кодом Какао.Насколько я могу понять, addGlobalEventMonitor... и addLocalEventMonitor... - это всего лишь обертки Obj-C вокруг CGEventTap s.

Я думаю, что CGEventTap - это путь.Документы для них редки, да, но они просты.Ответ Дэйва Делонга на этот ТАК вопрос может поставить вас на правильный путь.

2 голосов
/ 13 июня 2011

Я думаю, тебе нужно сделать что-то вроде этого ...

EventHandlerRef     m_ApplicationMouseDragEventHandlerRef;          
EventHandlerRef     m_MonitorMouseDragEventHandlerRef;

{
    OSStatus ErrStatus;

    static const EventTypeSpec kMouseDragEvents[] =
      {
        { kEventClassMouse, kEventMouseDragged }
      };

    ErrStatus = InstallEventHandler(GetEventMonitorTarget(), NewEventHandlerUPP(MouseHasDragged), GetEventTypeCount(kMouseDragEvents), kMouseDragEvents, this, &m_MonitorMouseDragEventHandlerRef);

    ErrStatus = InstallApplicationEventHandler(NewEventHandlerUPP(MouseHasDragged), GetEventTypeCount(kMouseDragEvents), kMouseDragEvents, this, &m_ApplicationMouseDragEventHandlerRef);

    return true;
}

//implement these functions
OSStatus MouseHasDragged(EventHandlerCallRef inCaller, EventRef inEvent, void *pUserData){}

EventTypeSpec необходимо обновить / изменить для перемещения, а остальные должны быть такими же. Это код углерода. Но вы также можете посмотреть на кварцевые настольные сервисы.

ура!

...