Доброго всем времени суток. Мой вопрос адресован тем, кто занимался разработкой плагинов для Winamp. Я уже задал его на родном форуме (forums.winamp.com), но в течение долгого времени ответа так и не получил. Фишка вот в чем: написал я плагин на делфях (без RTL, как завещал ms-rem), соблюдая все каноны - DLL экспортирует одну функцию winampGeneralPurposePlugin, DLLEntry возвращает в eax 1h, имя самого файла начинается с 'gen_'. Плагин грузится Winamp'ом, но сразу после того, как отрабатывает DLLEntry, выгружается. Сначала я подумал, что что-то в моей DLL'ке не нравится не Winamp'у, а функции LoadLibrary, но как показали тесты, с ней все в поряде и либу выгружает сам Winamp. Просмотрев несколько примеров и отдизасмив парочку рабочих плагинов я не нашел разницы с моей реализацией - везде соблюдаются всё те же каноны. В итоге пришлось написать две библиотеки, одна из которых является loader'ом и грузит вторую либу, которая и несет весь функционал. Но как-то это черезжопно... Вот сейчас сижу и чешу репу - что не нравится Winamp'у? Может кто сталкивался с такой проблемой? Сам плагин с сорцами можно слить со странички http://twister.orgfree.com/other, файл называется plugin.rar (38kb) Всем откликнувшимся заранее спасибо.
del ну надо же хранить 2 файла с одинаковым именем?! вот прямая ссылка http://twister.orgfree.com/other/Plugin.rar
В DllEntry не надо делать логику. Для этого есть спец функция экспортируемая плагином. В SDK все логично: Код (Text): BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) { return TRUE; } А у тебя: Код (Text): hwndWinamp := FindWindow('Winamp v1.x', nil); if hwndWinamp <> 0 then begin InitFPU(); hwndPlayList := SendMessage(hwndWinamp, WM_WA_IPC, IPC_GETWND_PE, IPC_GETWND); if hwndPlayList <> 0 then begin HookProc('User32.dll', 'TrackPopupMenu', @NewTrackPopupMenu, @OldTrackPopupMenu); PE_WndProc := SetWindowLong(hwndPlayList, GWL_WNDPROC, DWORD(@NewPEWindowProc)); end; end; end;
Прямые ссылки не качаются проводником с orgfree.com Погодь. И что, из-за этого Винамп выгружает плагин?
Все. Разобрался. Дело не в DLLEntry - там может быть что угодно. Просто в структуре, возвращаемой winampGetGeneralPurposePlugin должен присутствовать валидный указатель на процедуру инициализации. Та, в свою очередь должна возвращать ноль. Если кому надо, то обновленный плагин с сорцами по прежнему адресу. Суть его в том, что он дает возможность копировать файлы треков прямо из плейлиста. Это удобно для обновления музыки на MP3-флешке. Кстати, еще вопросик. Я добавляю свой пункт меню к всплывающему меню плейлиста динамически, путем перехвата TrackPopupMenu. Но как отличить это меню от других, что вызываются щелчками по кнопкам на окне плейлиста? По координатам мыши не прокатит - некоторые менюшки при стандартном скине всплывают в RECT'е списка треков. Есть какие идеи?
может то оно может, но в данной модели плагинов предусмотрена спец. функция инициализации плагина (как и финализации) Вот на всякий случай структура, на которую должна быть ссылка после отработки функции winampGetGeneralPurposePlugin
К чему ты это? SDK есть и я его курил. Как видишь - с вопросом разобрался. Она есть - глянь в сорцах. Так что по поводу второго вопроса? Есть мысли?
Twister про меню: наверн имеет смысл в начале вызвать меню, тут же вылезет твой хук, ты будешь знать, что это ты сам его вызвал - сохраняешь хэндл меню, меню не показываешь (т.к. ты его показал только для теста). потом просто сравниваешь хэндлы меню.
Это была первая мысль. Но я ее отклонил - Winamp может быть на любом языке. Кол-во итемов в меню тоже не показатель - может смениться при следующей версии или кто-то, как я, может добавить свои пункты. А вот на ID, наверное, стоит обратить внимание. Дома сравню версии старше 5,2... Jupiter Что-то я не совсем понял, что ты имеешь ввиду. А какое меню мне вызывать? Я ж не знаю его хэндл - в том-то и проблема.
не по хэндлу, а по команде через SendMessage, как если бы был сделан клик в меню плейлисте. хэндл плейлиста тебе известен, вот и шли ему WM_CONTEXTMENU. кста ты можешь захучить (1 раз в начале) WM_INITMENUPOPUP, потом расхучить обратно. так понятнее?
Идею Jupiter'a реализовать не вышло - какие бы сообщения на стадии загрузки плагина не посылались окну плейлиста (WM_RBUTTONUP, WM_CONTEXTMENU), меню всегда всплывало не то, которое нужно, а главное меню Winamp'a. Но сама идея натолкнула меня на другую мысль (ну почему хорошие мысли всегда приходят поздно и только после хорошей травы?). Все до ужаса тупо - хук TrackPopupMenu должен добавлять свой пункт только в том случае, если меню было вызвано с помощью сообщения WM_RBUTTONUP, т.к. это сообщение единственный способ вызвать нужное меню. На этом всем откликнувшимся спасибо. Если кому нужно, то обновленные сорцы по старому адресу.
Twister оч. важно подтолкнуть в нужном направлении работает, когда меню выло вызвано нажатием на клавишу на клаве "контекстное меню" ?