2010-01-24 1 views
1

Я пытаюсь создать приложение браузера для конкретного сайта. Я создал новое приложение Cocoa, добавил WebView в мое окно и загружаю страницу. Страница содержит Flash-ролик, который можно управлять с клавиатуры. Я хотел бы подключить некоторые команды меню для запуска действий, по-видимому, путем имитации нажатий клавиш.Как отправить ключевые события в Flash-ролик в WebKit?

Я прошел иерархию представлений и нашел NSView, содержащий фильм (с именем класса «WebHostedNetscapePluginView»). Но я застрял в точке отправки его ключей. Я попытался использовать CGEventCreateKeyboardEvent(), но вход продолжает перемещаться в верхний уровень WebView, а не в subview, содержащий фильм.

Я попробовал [[webView window] makeFirstResponder: _myView], чтобы установить цель для ввода.

Является ли CGEventCreateKeyboardEvent() правильной функцией здесь и, если да, то как мне добраться до моего целевого NSView?

Большое спасибо заранее.

ответ

1

Мой первоначальный ответ будет работать только в том случае, если окно было активным. Я также хотел, чтобы он работал, когда окно было скрыто, и придумал код ниже.

Это работает для обычных клавиш (Enter, Space, клавиши со стрелками и т. Д.). Он использует коды клавиш, поэтому он не будет работать для букв и символов, которые могут перемещаться в зависимости от языка и региона пользователя.

И он не обрабатывает ключи-модификаторы, такие как Command. Если кто-то может определить , что Извините, я с радостью отдам им кредит на ответ на этот вопрос.

// For Safari 4.x+ 
if ([[flashView className] isEqual:@"WebHostedNetscapePluginView"]) 
{ 
    CGEventRef event = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)keycode, true); 
    [flashView keyDown:[NSEvent eventWithCGEvent:event]]; 
    CFRelease(event); 
} 
else 
{ 
    EventRecord event; 
    event.what  = keyDown; 
    event.message = keycode << 8; 
    event.modifiers = 0; 

    // For Safari 3.x 
    if ([flashView respondsToSelector:@selector(sendEvent:)]) { 
     [(id)flashView sendEvent:(NSEvent*)&event]; 
     event.what = keyUp; 
     [(id)flashView sendEvent:(NSEvent*)&event]; 
    } 

    // For Safari 4.x 
    else if ([(id)flashView respondsToSelector:@selector(sendEvent:isDrawRect:)]) { 
     [(id)flashView sendEvent:(NSEvent *)&event isDrawRect:NO]; 
     event.what = keyUp; 
     [(id)flashView sendEvent:(NSEvent *)&event isDrawRect:NO];   
    } 
    else 
    { 
     NSLog(@"ERROR: unable to locate event selector for Flash plugin"); 
    } 
} 

Необходимо сначала найти виджет Flash в браузере; передайте свой WebView.

- (NSView*)_findFlashViewInView:(NSView*)view 
{ 
    NSString* className = [view className]; 

    // WebHostedNetscapePluginView showed up in Safari 4.x, 
    // WebNetscapePluginDocumentView is Safari 3.x. 
    if ([className isEqual:@"WebHostedNetscapePluginView"] || 
     [className isEqual:@"WebNetscapePluginDocumentView"]) 
    { 
     // Do any checks to make sure you've got the right player 
     return view; 
    } 

    // Okay, this view isn't a plugin, keep going 
    for (NSView* subview in [view subviews]) 
    { 
     NSView* result = [self _findFlashViewInView:subview]; 
     if (result) return result; 
    } 

    return nil; 
} 
0

Вы убедитесь, что элемент Flash имеет фокус (HTML)?

+0

Вот что я пытаюсь выяснить здесь. Установка его как первого ответчика, похоже, не сработала. – starkos

+0

'_myView' указывает на вид плагина? – Wevah

+0

Что я имею в виду, вам может потребоваться установить элемент object/embed в сфокусированный HTML-элемент в стиле HTML/JS. Я не совсем уверен, как WebViews определяют свой сфокусированный элемент, когда они являются плагинами. – Wevah

0

Мне удалось выяснить это. Вот код:

[[self window] makeFirstResponder:_tunerView]; 

CGEventRef e1 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)49, true); 
CGEventPost(kCGSessionEventTap, e1); 
CFRelease(e1); 

CGEventRef e2 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)49, false); 
CGEventPost(kCGSessionEventTap, e2); 
CFRelease(e2); 

окно это главное окно программы. _tunerView - это WebHostedNetscapePluginView. Я устанавливал первого ответчика, когда окно сначала открывалось, что не работало. Я должен установить его прямо перед отправкой ключей.

Смежные вопросы