1 (изменено: Drugoy, 2013-02-10 14:23:45)

Тема: AHK: DetachVideo (из браузера - в отдельное окно)

Есть замечательный скрипт от Skrommel'a, DetachVideo.

Привожу код этого скрипта, почищенный от лишнего (gui, настройки, возможность сменить hotkey, описание).

#SingleInstance,Force
DetectHiddenWindows,On
SetWinDelay,0

counter=0
OnExit,EXIT
SetTimer,MOVE,500
Return

F12::
SetTimer,MOVE,Off
MouseGetPos,,,window,ctrl,2
WinGetPos,wx,wy,ww,wh,ahk_id %window%
WinGetPos,cx,cy,cw,ch,ahk_id %ctrl%
current:=counter
Loop,% counter+1
{
  If gui_%A_Index%=
  {
    current:=A_Index
    Break
  }
}
If current>%counter%
  counter+=1
Gui,%current%:+AlwaysOnTop +Resize +ToolWindow +LabelAllGui 
Gui,%current%:Show,X0 Y0 W%cw% H%ch%,DetachVideo
Gui,%current%:+LastFound
gui:=WinExist("A")
parent:=DllCall("SetParent","UInt",ctrl,"UInt",gui)
WinMove,ahk_id %ctrl%,,0,0 ;,%cw%,%ch%
ctrl_%current%:=ctrl
gui_%current%:=gui
parent_%current%:=parent
window_%current%:=window
w_%current%:=ww
h_%current%:=wh
SetTimer,MOVE,500
Return

MOVE:
SetTimer,MOVE,Off
Loop,%counter%
{
  ctrl:=ctrl_%A_Index%
  If ctrl=
    Continue
  IfWinExist,ahk_id %ctrl%
    WinMove,ahk_id %ctrl%,,0,0
  Else
    Gui,%A_Index%:Destroy
}
SetTimer,MOVE,500
Return

AllGuiClose:
SetTimer,MOVE,Off
ctrl:=ctrl_%A_Gui%
window:=window_%A_Gui%
DllCall("SetParent","UInt",ctrl_%A_Gui%,"UInt",parent_%A_Gui%)
Gui,%A_Gui%:Destroy
WinMove,ahk_id %ctrl%,,0,0
WinMove,ahk_id %window%,,,,% w_%A_Gui%,% h_%A_Gui%+1
WinMove,ahk_id %window%,,,,% w_%A_Gui%,% h_%A_Gui%
gui_%A_Gui%=
ctrl_%A_Gui%=
parent_%A_Gui%=
SetTimer,MOVE,500
Return

EXIT:
SetTimer,MOVE,Off
Loop,%counter%
{
  ctrl:=ctrl_%A_Index%
  window:=window_%A_Index%
  If ctrl=
    Continue
  DllCall("SetParent","UInt",ctrl_%A_Index%,"UInt",parent_%A_Index%)
  Gui,%A_Index%:Destroy
  WinMove,ahk_id %ctrl%,,0,0
  WinMove,ahk_id %window%,,,,% w_%A_Index%,% h_%A_Index%+1
  WinMove,ahk_id %window%,,,,% w_%A_Index%,% h_%A_Index%
}
ExitApp

http://www.donationcoder.com/Software/Skrommel/DetachVideo/DetachVideoScreen.gif
Скрипт работает так: заходите на ютуб, отключаете html5-плеер (скрипт работает только с плагинными видеопрогирывателями: например, flash) включаете видео, наводите курсор на него и жмёте F12. После этого видео выделяется в отдельное alwaysontop окно, так что можете переключиться на соседнюю вкладку и при этом смотреть видео.
По идее - скрипт кросс-браузерный и кросс-плагинный.

Проблем у скрипта несколько, но основная заключается в том, что у меня в Firefox он не работает с ютубными видео, вставленными не на ютуб страницы.

Я провёл кое-какое расследование, пытаясь выяснить причину, вот его результаты:

Это происходит из-за того, что: (строка №12)

MouseGetPos,,,window,ctrl,2

ctrl пустой, потому что на неютубных страницах у плагин-контейнера, почему-то нет такого же окна, какое оно есть у ютубных страниц с проигрывателем: на ютубных страницах появляется control 'GeckoPluginWindow1', а на неютубных - он не появляется, взамен появляется какой-то Static1, я пробовал подставлять hwnd этого Static1 сразу после 12-ой строки, но результат плачевный: скрипт создаёт новое окно, которое:
а) слишком мелкого размера (а размер создаваемого окна в скрипте - наследуется от родителя же)
б) не содержит в себе проигрывателя (он остаётся на странице).

Почему в лисе флеш-плагин так себя ведёт - я не знаю. Вероятно, там особенности кода таковы, что embedded объекты (т.е. frame/iframe) не получают classNN и своего окна. В лисе вообще окна написаны на XUL, поэтому если глянуть на список окон, которые создаёт лиса через WinSpector - можно с ума сойти: столько их много и так бессвязано они разбросаны.

И тут у меня родилась идея как обойти эту проблему (не решить, а обойти): в ютубном флеш-плеере же есть кнопка перехода в полноэкранный режим, и при её нажатии контейнер плагина создаёт новое полноценное окно, которое видно даже на панели задач. Его размеры можно легко поменять скриптом.
Но возникают разные новые проблемы:
1. иногда случается так, что открываемое окно не терпит потери фокуса: если куда-то кликнуть мимо него - оно исчезает.
2. иногда оно всё таки нормально относится к тому, что оно не в фокусе, но тогда проявляется другая проблема: у этого окна постоянно сбрасывается alwaysontop, даже если его назначить вручную. Можно ведь создать прозрачное Gui окно и "подложить" его под окно с проигрывателем так, чтобы при назначении alwaysontop этому gui-окну прикреплённое к нему окно с проигрывателем фактически тоже становилось alwaysontop (хотя конкретно у его окна метка и будет отсутствовать)?

Помогите пожалуйста.

2

Re: AHK: DetachVideo (из браузера - в отдельное окно)

Странно, но не на всех неютубных страницах скрипт ведёт себя одинаково:
вот здесь: http://www.autohotkey.com/board/topic/52871-«-whats-on-your-mind-»/page-142#entry572594
скрипт срабатывает отлично, хотя страница не ютубная.

3

Re: AHK: DetachVideo (из браузера - в отдельное окно)

Суть "Detach video", для понимания:

; если активно окно firefox
#IfWinActive ahk_class MozillaWindowClass
    ; при клике средней кнопкой мыши
    MButton::
        ; определим handle дочернего окна под курсором
        MouseGetPos,,,, hwndSub, 2
        ; если под курсором в окне firefox нет «классического» дочернего окна — закончим
        if !WinExist("ahk_id" . hwndSub)
            return

        ; определим высоту и ширину найденного окна флеш-плеера
        ControlGetPos,,, w, h
        ; создадим новое окно, сохраним его handle в переменной hwndNewParent
        Gui +hwndhwndNewParent -Caption -Border +ToolWindow +AlwaysOnTop
        ; назначим найденному дочернему окну плеера нового «родителя» — окно созданное нами
        DllCall("SetParent", "UPtr", hwndSub, "UPtr", hwndNewParent)
        ; отобразим созданное окно
        Gui Show,  w%w% h%h%
        return

Вероятно, там особенности кода таковы, что embedded объекты (т.е. frame/iframe) не получают classNN и своего окна.

Вероятно

4

Re: AHK: DetachVideo (из браузера - в отдельное окно)

Нда, единственный выход, который мне видится - это использование ActiveX для загрузки страницы в окне GUI, но это совсем не то, чего хотелось бы :-(