PDA

Просмотр полной версии : отключить кнопку контекстного меню (Zink)


chingachgoog
19.03.2008, 16:05
Отключил в Цинке правую кнопку мыши (ignored), и конечно, по правому клику меню не выскакивает...
Но на клавиатуре есть кнопка контекстного меню (у меня слева от правого контрола, код 93) и при нажатии на ней меню флеш-плеера как миленькое вылазит. :(
Более того, эта кнопка не отлавливаетя в Цинке (хотя отлавливается в среде фле-редактора):


KL={}
KL.onKeyDown=function(){
trace(Key.getCode())
myKey.text=Key.getCode() // тестовое текстовое поле
}
Key.addListener(KL)


Как заблокировать?

alexcon314
19.03.2008, 17:45
написать ДЛЛ, перехватывающую эту кнопку и подключить к цинку.
я делал подобное, подменяя оконную процедуру плеера в цинке. получалось. или же хук.

chingachgoog
19.03.2008, 20:09
Что такое хук?

NB!
Интересное наблюдение. StandAlone плеер (флеша, а не цинка) перехватывает onKeyDown нажатие клавиши контекстного меню (выдает ее код и само меню не открывается).
А вот ActiveX плеер (в ИЕ и Цинке) не отлавливает onKeyDown и открывает меню.

alexcon314
19.03.2008, 22:13
хук - это hook. чти Win32 API. своего рода листенер. только слушает он системные сообщения. разные. кнопка "меню" - это семечки...
но с подменой оконной процедуры проще.

chingachgoog
24.03.2008, 20:36
Что-то никак не пойму, как dll-файл подключить в цинке.

пишу в начале флешки:

myDLL = new mdm.DLL("имя_моей_библиотеки.dll")


файл имя_моей_библиотеки.dll лежит отдельно рядом с флешкой и цинковским экзешником.

При сборке пишет ошибку: не удалось найти компонент bpl...

Как dll подключить? Может его внедрять надо в экзешник как-то?

alexcon314
25.03.2008, 08:42
*.bpl - это из области дэлфи.
1. без этой строчки все работает?
2. что в длл? в чем собирали?
3. что в экзе?
4. версия цинка?

chingachgoog
25.03.2008, 11:29
1. все работает (в смысле приложение, а запрет кнопки контекстного меню как раз не работает) и с этой строчкой (просто сообщение перед запуском выскакивало)
2. Собиралось как раз в дельфи, программист исправил, теперь сообщение не возникает.
3. Не понял насчет экзе? Работает нормально.
4. цинк 2.5.0.18

мне казалось, что в цинке достаточно вот эту строчку прописать

myDLL = new mdm.DLL("имя_моей_библиотеки.dll")

в самом начале кода и при выходе выполнить

myDLL.close();

И все. Но что-то пока не выходит.
Может надо выполнить DLL.call()?

А как узнать что dll-ка загрузилась?

alexcon314
25.03.2008, 12:33
>>мне казалось, что в цинке достаточно вот эту строчку прописать

Код:
myDLL = new mdm.DLL("имя_моей_библиотеки.dll")в самом начале кода и при выходе выполнить

Код:
myDLL.close();>>
так и надо поступать. myDll.call() вызываем по небходимости вызова длл-ной функции, не забывая про список параметров.
у меня версия 2.5.0.34, чего и вам желаю :)
hDll = new mdm.DLL(dllPath);
if (!hDll.isLoaded) {
mdm.prompt("Dll load failed!");
return;
}
только true isLoaded будет при реалной загрузке. если длл уже в оперативке (как например системная какая-нибудь) будет false. но работать все равно должно.
если есть сомнения в работоспособности кода в длл - дебажить надо и все. как - это вопрос отдельный. элементарно: встроить в код длл какой-нибудь мессаджбокс, чтоб выскакивал в нужном месте. ну или debag tools разного рода юзать.

// в длл встраиваем такие функции. ReplaceWndProc вызываем из цинка или
//сразу при загрузке длл из EntryPoint.
//предварительно надо найти окно плеера в цинке

LRESULT CALLBACK GetMsgProc(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam){

switch (nMsg) {
case WM_MOUSEMOVE:
// ...
break;
case WM_MBUTTONUP:
// ...
break;
case WM_RBUTTONUP:
// ...
break;
case WM_LBUTTONDBLCLK:
// ...
break;
case WM_SYSKEYDOWN:
// ...
break;
case WM_KEYDOWN:
switch (wParam)
{
case VK_LEFT:
break;
case VK_RIGHT:
break;
case VK_UP:
break;
case VK_DOWN:
break;
case VK_HOME:
break;
case VK_END:
break;
case VK_INSERT:
break;
case VK_DELETE:
break;
case VK_F2:
break;
case VK_LWIN:
//MessageBox(hwin,(LPCSTR)"left winbuttonb down","",MB_OK);
break;
case 93:// это и есть кнопка "меню"
//MessageBox(hwin,(LPCSTR)"menubutton down","",MB_OK);
return 1; // прекращаем обработку сообщения, меню не вываливается
break;
default:
//
break;
}
default:
//
break;
}
// передаем все далее родной процедуре на обработку
return CallWindowProc((WNDPROC)oldWnd, hwin, nMsg, wParam, lParam);
}
// поиск окна плеера fName - заголовок (title) формы приложения
// имя класса окна плеера можно узреть в WinSpector'e, например.
HWND fwin = FindWindow(NULL,fName);
HWND tpan = FindWindowEx(fwin,NULL,(LPCSTR)"TPanel",NULL);
hwin = FindWindowEx(tpan,NULL,(LPCSTR)"FlashPlayerControl_MacromediaFlashPlayerActiveX_7309416",NULL);
// собственно подмена оконной процедуры
extern "C" __declspec(dllexport)LONG ReplaceWndProc(BOOL bSet){
if(bSet){
oldWnd = SetWindowLong(hwin, GWL_WNDPROC, (LONG)GetMsgProc);
return oldWnd;
} else{

return SetWindowLong(hwin, GWL_WNDPROC, oldWnd);
}
}

откопал кусок исходника рабочего. посмотрите. может пригодится.
Вариант с хуком принципиально не отличается. вместо подмены надо юзать
SetWindowsHookEx(WH_GETMESSAGE, hpHookProc, hHookDll, hthread);

chingachgoog
25.03.2008, 13:19
Спасибо!
Видно дело именно в запрятанном окне цинка (dll-ка была рассчитана на стандартное приложение) Будем искать :)

А теперь такой вопрос:
dll подгружается извне, поэтому возможна ситуация, когда пользователь сможет запустить экзешник без dll-ки и нажав на кнопку контекстного меню увидит-таки флешовое окно. Можно ли внедрить dll прямо в экзешник?

alexcon314
25.03.2008, 13:46
это предусмотрено в механизме создания и внедрения в ехе собственных расширений (в триале недоступно).
вариант: зашить длл в библиотеку (цинк, не путать с флэш-библиотекой) приложения и программно ее распаковывать при старте. далее подрубать длл как обычно из каталога распаковки. (я не пробовал).
вариант с отсутствующей длл, о котором вы говорите, мне представляется маловероятным, ибо распространять приложение вы будете вместе с ней и никак иначе(?), одним инсталл-пакетом, возможно, благо такие возможности у цинка есть. зачем юзеру париться и запускать ехе без длл? ... впрочем, вам виднее.

chingachgoog
25.03.2008, 14:08
Это вариант, если пытливый пользователь все же захочет понять на чем все-таки написано приложение :) А я соответственно никоим образом не хочу показывать окно флеш-плеера :)

Я правильно понимаю, что "распаковка" библиотеки цинка - это при КАЖДОМ запуске экзешника?

alexcon314
25.03.2008, 14:16
проверочку сделали на факт наличия длл в нужной папке, в папке приложения, например, и распаковали если надо. каждый раз при запуске распаковавать - это паранойя :)
попробовал сейчас запаковать-распаковать из либы - все работает как и ожидалось.

chingachgoog
25.03.2008, 15:03
Э...
Я думал это виртуальная распаковка...

Видимо еще недопонял, как библиотека в цинке работает. :(
Она не встраивается в экзешник? Тоже отдельным файлом?

А проверку на наличие dll как сделать? Если только myDll.isLoaded и сразу выходить из Цинка? Интересная мысль. Надо только проверить что будет делать Цинк если долго не грузиться dll (привод раскручивается, например)? Позволит успеть нажать контекстное меню?

alexcon314
25.03.2008, 17:23
посмотрите mdm-класс mdm.Application.Library. вчастности

mdm.Application.Library.extractAllToExecPath();

длл встроится в ехе. встроить ее можно в Zinc IDE на вкладочке Library (окошечко справа над кнопочкой Build), нажав на плюсик и выбрав файлик.
проверочка

var exists = mdm.FileSystem.fileExists(exec_Path+'\\yourdll.dll');
if(!exists){
mdm.Application.Library.extractAllToExecPath();
}
hDll = new mdm.DLL(exec_Path+'\\yourdll.dll');
if (!hDll.isLoaded) {
mdm.prompt("Dll load failed!");
// mdm.Application.exit();
}
}

>> Надо только проверить что будет делать Цинк если долго не грузиться dll (привод раскручивается, например)? Позволит успеть нажать контекстное меню?

это на вас весна так действует ? :)

chingachgoog
25.03.2008, 17:50
Спасибо!
dll-ку программист подкрутил, теперь контекстное меню не беспокоит :)
(только приходиться помимо подгрузки dll, вызвать одну функцию в нем)
Буду разбираться с внедрением в экзешник.



Надо только проверить что будет делать Цинк если долго не грузиться dll (привод раскручивается, например)? Позволит успеть нажать контекстное меню?

это на вас весна так действует ?


Это я про код:

if (!hDll.isLoaded) {
mdm.Application.exit();
}


Если интепретатор приостанавливает работу (синхронный метод), то конечно все отлично, а если нет (асинхронный метод), то тогда проверка может начаться быстрее, чем isLoaded окажется true.
add:
у меня в хелпе вообще по ходу дела ничего про DLL.isLoaded нет. Откуда вы про него узнали?

alexcon314
26.03.2008, 09:59
ASSetPropFlags(_global.mdm, null, 0, 7);
for (i in _global.mdm) {
// трейсим свойства в текстовое поле
}

что-то типа этого
по поводу асинхронности. свойсво isLoaded объекта выставляется по РЕЗУЛЬТАТУ выполнения метода этого-же объекта, выполняющего подгрузку длл. иначе зачем оно? выполнение кода синхронное.

chingachgoog
26.03.2008, 13:39
Про ASSetPropFlags я как-то не подумал. :)
Значит это ошибка в их хелпе:

они пишут

mdm.DLL(dll:String):Boolean
Parameters
dll:String DLL File to Load
Returns
A Boolean


а на самом деле возвращается не булевая величина, а объект со следующими свойствами:


isLoaded true
___id 0
___undefined имя_моей_DLL.dll
__isInstance true
__object DLL
__parent [type Function]
__constructor__ [type Function]
__proto__ [object Object]


Про синхронность кода.
Ведь для того и существуют обработчики событий типа onLoad..., что выполнение кода несинхронное (хотя в локальных приложениях таймлайн замораживается при подгрузке).
А в коде


hDll = new mdm.DLL('имя_моей_DLL.dll');

if (!hDll.isLoaded) {
mdm.prompt("Dll не загружена");
} else {
mdm.prompt("Dll загружена");
}

mdm.prompt("следующая строка кода");

выводит: Dll загружена следующая строка кода
Выходит действительно загрузка синхронная, пока не загрузиться dll выполнение кода приостанавливается.

alexcon314
26.03.2008, 13:56
ASSetPropFlags не имеет к mdm ровным счетом никакого отношения. просто в рантайме в проигрыватель "видит" mdm-классы наравне с обычными AS-классами. и соответственно можно их "пощупать" фор'ином.
другое дело реализация mdm-классов.
пример с синхронностью загрузки длл показывает, что "внутри" данного mdm-класса загрузка длл работает именно так, при том что об этой загрузке плеер ничего не знает и onLoad (чисто плеерный обработчик, причем тут он?) к ней не пририкрутишь. все это зашито в оболочку.

....

над синхронностью выполнения кода в цинке можно и следует подумать. я до конца не разобрался с этим, но есть факты, свидетельствующие о том, что в нек. ситуациях выполнение mdm-кода тормозит выполнение AS-кода, чего быть не должно по-идее.
скажем копирование группы файлов в цикле с промежуточным выводом имени каждого скопированного файла в текстовое поле. у меня поле заполнялось сразу всем списком по окончании копирования всей группы, а не построчно.
впрочем, есть такая фича - вызов mdm-метода c дополнительным параметром mdm.ASYNC.
но с ней тоже есть непонятки, подлежащие экспериментальному иссследованию.

читаем

http://www.multidmedia.com/support/articles/?action=detail&id=1

и

http://www.multidmedia.com/support/technotes/?action=detail&id=38

если вас волнует этот вопрос рекомендую вдумчиво полистать mdm-форум. там есть примеры использования mdm.ASYNC.

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

chingachgoog
26.03.2008, 15:05
добавлю, что из под цинка через длл можно выводить какие-то операции (не плеерные) в отдельные потоки, что бывает хорошим средством "синхронизации". я делал таким образом флэш-прогрессбар для операции копирования файлов.
крутился у меня вариант организации многопоточности через дочерние формы, ибо в них крутятся независимые экземпляры проигрывателя. но дальше первых проб (положительных) я пока не продвинулся.


Круто! У меня была мысль (http://flasher.ru/forum/showpost.php?p=592062&postcount=16) линию загрузки сделать через localConnection с открытием другого флеш-плеера, но дальше теории я не пошел.

Agon
04.04.2008, 07:36
в zinc 3 есть функция отключения этой кнопки (и других).
Application.Kiosk....

alexcon314
04.04.2008, 08:48
>>в zinc 3 есть функция отключения этой кнопки (и других).

обладатели 2.5 не ищут легких путей ! :)

GFreemen
21.04.2008, 21:10
Здравствуйте. У меня нет опыта в написании библиотек, как и компиляторов С++ или Дельфи. Нельзя ли выложить dll-ку с отключением кнопки контекстного меню для всеобщего пользования?
Спасибо.

alexcon314
21.04.2008, 22:50
что-то зачастили D:
http://flasher.ru/forum/showthread.php?t=110772 пост №6
пример расчитан на "доводку" под свои нужды, но вполне рабочий.
...
>>Нельзя ли выложить dll-ку ... для всеобщего пользования.
прежде, чем выкладывать что-то конкретное, нужно четко сформулировать требования насчет того, какой функционал должна реализовывать эта длл.

GFreemen
22.04.2008, 15:48
Большое спасибо.
Требование одно: отключение кнопки контекстного меню на клавиатуре.
По поводу dll.
Выводит:Init dll error with code - 10 Check init parameters.
в коментариях: code -10 - не получен хэндл окна
чтобы это могло быть?
zinc 2.5.0.23
в 9-ом флеше компилирую под 8-ку и соответственно AS2.
Может из-за того, что // Имена объектов file mapping и mutex, создаваемых плеером.
var fileMapping:String = "MacromediaFMOmega";
var MutexObj:String = "MacromediaMutexOmega";
var activex = "FlashPlayerControl_MacromediaFlashPlayerActiveX_7309416";
теперь имеют в названии не Macromedia а что-то типа Adobe?

alexcon314
22.04.2008, 18:40
если вы разбираете пример во .fla из указанного поста, то данная ошибка возникает, когда длл не может определить хэндл окна проигрывателя. возможно вам следует изменить строку

var activex = "FlashPlayerControl_MacromediaFlashPlayerActiveX_7309416";

эта строка - имя класса окна проигрывателя в цинке.
в 2.5.0.34 оно именно такое. выясните какое оно в 2.5.0.23 и поменяйте.
выяснить можно при помощи проги WinSpector - она дает полную информацию о любом окне любого запущенного приложения. посмотрите что она показывает для окна цинк-ехе, когда он запущен.
длл ищет хэндл "пробегая по детям" окна, чей заголовок равен formTitle пока не встретит окно с которым ассоциирован указанный класс.
что касается имен мутекса и файлмаппинг то врядли их названия меняются ( и не меняются) от версии к версии, иначе локалконнекшн не будет иметь обратной соместимости.
...
2.5.0.23 у меня нет в наличии. проверить не могу. попробуйте найти 2.5.0.34, на нем работает.

GFreemen
28.04.2008, 22:26
У меня
var activex = "FlashPlayerControl_MacromediaFlashPlayerActiveX_7297128";
Подключение длл проходит вроди на ура, во всяком случае не ругается.
Но после этого при нажатии любой кнопки на мыше, происходит зависание окна - не отвечает.

alexcon314
28.04.2008, 23:07
мм.. досадно.
сорри.
что-то сделать еще для вас?
могу только предполагать: косяк цинка 2.5.0.23. ибо 34 рулит. сия длл юзается в моей организации и нон проблем .. тьфу.. тьфу.. реплайс нормальнро происходит.
тогда можно попробовать хук чтоли, я не знаю... пути есть решения только время надо ... почему вы не заюзаете 34?
3.0.0... или как там косячит в длл по полной.
..........
блин, да когда ж мы сделаем свою рульную оболочу? достали эти косяки...

GFreemen
30.04.2008, 23:00
2 alexcon314
Спасибо за помощь. Буду искать 34. :(

P.S. Да, действительно в 34-ке все работает на ура. большое спасибо.
И еще такой вопрос: сколько будет стоить включение этого кода и вашей dll в коммерческий проект?

alexcon314
03.05.2008, 09:23
>>И еще такой вопрос: сколько будет стоить включение этого кода и вашей dll в коммерческий проект?
обозначьте просто мое скромное участие и все.

GFreemen
03.05.2008, 21:01
Договорились

chingachgoog
06.06.2008, 18:03
alexcon314, выяснил интересную вещь - при установке совместимости программы под Win98/Ме или ниже (для предотвращения известного глюка Цинка) контекстное меню несмотря на мою dll опять стало открываться! ((((

А ваша dll-ка работает и под Win98/Ме :)

alexcon314
06.06.2008, 18:20
Попробуйте мои. Попробовал в режиме совместимости - такого не наблюдал.

http://flasher.ru/forum/showthread.php?t=111773

А вам убрать заголовок формы не помогает? и переименование файла?

chingachgoog
06.06.2008, 18:26
Даже не пробывал (заголовок формы у меня скриптом написан и так).
Меня сама возможность того, что человек может поменять совместимость вручную и увидеть меню расстроила.
Но ничего - главное, что решить можно (уж не обижайтесь, но хочется сделать dll именно свою, а не использовать чужую :) )

alexcon314
06.06.2008, 18:31
>> хочется сделать dll именно свою, а не использовать чужую ...
Похвально )). Только ведь и я пользовался чужими примерами и исходниками из нета.

chingachgoog
06.06.2008, 18:43
Так ваш труд не пропадет даром :)
Вашу dll-ку разберем по косточкам, как там что работает )))

chingachgoog
19.08.2008, 18:58
Попробывал SWFKit (http://www.swfkit.com/) - там вообще нет проблемы с кнопкой контекстного меню (отрубается видимо по умолчанию).

alexcon314
19.08.2008, 23:00
2 chingachgoog:
Контекстное меню - мелочь на самом деле. Как и многое другое. Меня больше занимает вопрос о standalone :D .Не забыл?

chingachgoog
20.08.2008, 13:25
Не забыл?
Нет. :) Работаем над этим вопросом...