AIMP Forum
AIMP for Windows => Дополнения / Addons => Разработка / Development => Topic started by: zoonman on October 13, 2009, 12:16:47
-
Пытаюсь сделать плагин в C++ Builder. Пока такой вот код:
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#include "aimp2_sdk.h"
IAIMP2Controller *aimp;
char * WINAPI __stdcall GetPluginName() {
ShowMessage("plg name");
return "plug in ";
}
char * WINAPI __stdcall GetPluginAuthor() {
ShowMessage("plg aut");
return "zoonman@gmail.com";
}
void WINAPI Initialize(IAIMP2Controller *AController) {
unsigned int ver = AController->AIMP_GetSystemVersion();
ShowMessage(IntToStr(ver));
aimp = AController;
ShowMessage("init");
}
void WINAPI ShowSettingsDialog(HWND AParentWindow){
ShowMessage("sett");
}
void WINAPI Finalize() {
ShowMessage("fin");
}
BOOL WINAPI GetHasSettingsDialog() {
ShowMessage("ghsd");
return 0;
}
extern "C" __declspec(dllexport) IAIMPAddonHeader* AIMP_QueryAddon(AIMPAddonHeader *str) {
str->version = 0;
str->InitFuncPtr = Initialize;
str->PlgNameFuncPtr = GetPluginName;
str->AutorFuncPtr = GetPluginAuthor;
str->FreeFuncPtr = Finalize;
ShowMessage("query");
return (IAIMPAddonHeader*)str;
}
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
//ShowMessage("reason:" + IntToStr(reason));
return 1;
}
Честно говоря, не могу понять, как правильно написать функцию AIMP_QueryAddon(). Самую простую хотя бы.
И в продолжение, как можно будет отловить события смены трека/состояния playback'a.
Смотрел примеры на Delphi, но не знаю, как их в C++ Builder перевести.
-
https://www.aimp.ru/forum/index.php?topic=420.0 - в последнем обновлении есть SDK на C++. Там объявления этих методов даны.
-
Спасибо Артем, я скачал этот файл ранее. Включил в заголовки. (#include "aimp2_sdk.h")
typedef BOOL (WINAPI *AIMPAddonHeaderProc)(IAIMPAddonHeader *AHeader);
// Export function name: AIMP_QueryAddonEx
это описание функции?
AIMP_QueryAddonEx - это уже для версии 2.6, отлаживаюсь на 2.51 потому пытаюсь с AIMP_QueryAddon
Вот это абстрактный класс
class IAIMPAddonHeader
:public IUnknown
{
public:
virtual BOOL WINAPI GetHasSettingsDialog() = 0;
virtual PWCHAR WINAPI GetPluginAuthor() = 0;
virtual PWCHAR WINAPI GetPluginName() = 0;
virtual void WINAPI Finalize() = 0;
virtual void WINAPI Initialize(IAIMP2Controller *AController) = 0;
virtual void WINAPI ShowSettingsDialog(HWND AParentWindow) = 0;
};
Что с ним делать, я не знаю((
Можно на пальцах объяснить, что в нее передается и что должно быть возвращено?
-
Для 2.51 выглядит это так:
TAIMPAddonHeader plugin =
{
PLUGIN_VERSION,
0,
GetPlgName,
GetAuthor,
Init,
Config,
Free
};
...
extern "C" __declspec( dllexport ) PAIMPAddonHeader AIMP_QueryAddon()
{
return &plugin;
}
Добавлено через 41 сек.
IAIMPAddonHeader - этот интерфейс должен реализовывать плагин и отдавать его плееру при обращении к AIMP_QueryAddonEx
-
TAIMPAddonHeader - структура (aimp2_sdk.h)
struct AIMPAddonHeader
{
DWORD version;
DWORD DllInstance;
GetPlgNameFunc PlgNameFuncPtr;
GetAutorFunc AutorFuncPtr;
InitFunc InitFuncPtr;
ConfigFunc ConfigFuncPtr;
FreeFunc FreeFuncPtr;
};
PAIMPAddonHeader - указатель на эту структуру.
-
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#include "aimp2_sdk.h"
#include <alloc.h>
#define PLUGIN_VERSION 1
IAIMP2Controller *aimp;
PCHAR WINAPI __stdcall GetPlgName() {
return "My Plugin";
}
PCHAR WINAPI __stdcall GetAuthor() {
return "zoonman";
}
// callback функция при смене трека
void __stdcall TrackPlay(DWORD User, DWORD dwCBType) {
AIMP2FileInfo *aif;
bool r;
r = aimp->AIMP_GetCurrentTrack(aif);
if (r) ShowMessage("True!");
AnsiString a;
a = WideCharToString(aif->sArtist);
ShowMessage(a);
}
void WINAPI Init(IAIMP2Controller *AController) {
AController->AIMP_CallBack_Set(AIMP_PLAY_FILE,TrackPlay, 1);
// функция, вызывается при смене состояния
aimp = AController;
}
void WINAPI Config(DWORD Handle, DWORD Win) {
//
}
void WINAPI Free() {
//ShowMessage("fin");
};
/*
Инициализация структуры плагина
*/
AIMPAddonHeader plugin = {
PLUGIN_VERSION,
0,
GetPlgName,
GetAuthor,
Init,
Config,
Free
};
extern "C" __declspec( dllexport ) AIMPAddonHeader* AIMP_QueryAddon()
{
return &plugin;
}
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
// ShowMessage("reason:" + IntToStr(reason));
return 1;
}
Почему-то не получается считать исполнителя.
На Delphi там идет FillChar, а в С++ Builder'e вроде как memset есть, но у меня с ним не заладилось.
aimp->AIMP_GetCurrentTrack(aif); // все время возвращает false
Я так понимаю, что структуру aif нужно как-то правильно проинициализировать.
sArtist - указатель на строку
nArtistLen - длина строки в символах (unicode ведь)
cbSizeOf - по идее размер структуры.
Как быть с вышеприведенными параметрами? Их как задавать?
-
1) У вас AIF объявлен как указатель - значит надо под него надо выделить память.
2) cbSizeOf - размер самой стурктуры AIMP2FileInfo
3) nArtistLen - сюда вы должны записать максимальное кол-во символов, которое можно поместить в выделенный вами буфер
4) sArtist - тот самый буфер, который вам надо выделить под "артиста"
P.S. Возможно, в С++ Builder есть ZeroMemory - структуру надо обязательно очистить перед использованием.
Должно быть как-то так:
var
APls: TAIMP2FileInfo;
ATitleBuf: array[0..127] of WideChar; // Buffer for restore title of track
begin
// Собственно это и есть запрос информации о файле
FillChar(APls, SizeOF(APls), 0);
APls.cbSizeOF := SizeOF(APls);
// Инициализация буфера
APls.sTitle := @ATitleBuf;
APls.nTitleLen := 128;
//
if AIMPController.AIMP_GetCurrentTrack(@APls) then
-
ZeroMemory(&aif, sizeof(AIMP2FileInfo));
порождает
[Linker Error] Unresolved external 'memset' referenced from D:\PRJ\CPPBUILDER6\AIMP_PLG\UNIT1.OBJ
покопался в сети, что-то везде одни и теже рекомендации, но не работают.
-
Так. С ошибкой линковки разобрался. Нужно перенастроить IDE: Project/Options/Advanced Compiler/Calling convention [Standard call]
При запуске с ZeroMemory ничего не происходит.
void WINAPI __stdcall TrackPlay(DWORD User, DWORD dwCBType) {
AIMP2FileInfo *aif;
WCHAR sArt[128]={101};
bool r;
/* allocate memory */
if ((aif = (AIMP2FileInfo *) malloc(1024)) == NULL)
{
MessageBox(NULL, "no memory","--",MB_OK );
// exit(1); /* terminate program if out of memory */
}
//_wmemset((void *)aif, 0, sizeof(aif) );
aif->cbSizeOf = 1024;
aif->sArtist = sArt;
aif->nArtistLen=64;
// _wmemset((void *)aif, 0, sizeof(aif) );
ZeroMemory(&aif, sizeof(aif));
r = aimp->AIMP_GetCurrentTrack(aif);
if (r) ShowMessage("True!");
AnsiString a;
a = WideCharToString(aif->sArtist);
ShowMessage(a);
}
-
aif->cbSizeOf = 1024; - почему 1024? надо брать SizeOf(сткруктура).
sizeof(aif) - боюсь, что здесь результат будет = 4, а не размеру стуктуры
-
Подскажите, пожалуйста, как правильно прописать получение длины трека. Так как сейчас - естесственно вызывает ошибку.
IAIMP2Controller *cnt;
int lng=cnt->AIMP_Status_Get(AIMP_STS_LENGTH);
Edit3->Text=lng;
-
Если вызываю только саму функцию - вылазит вот это:
-
Давно тут не появлялся, разработка временно заморожена по причине недостатка свободного времени.
Поделюсь минимальным рабочим кодом для C++ Builder 6:
То самое, что в Unit1.cpp, чтобы работало
#include <vcl.h>
#include <windows.h>
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#pragma hdrstop
#include "aimp2_sdk.h"
#include "unit1.h"
#define PLUGIN_VERSION 1
int s;
WSADATA lpWSAData;
IAIMP2Controller *aimp;
PCHAR WINAPI __stdcall GetPlgName() {
return "My Plugin";
}
PCHAR WINAPI __stdcall GetAuthor() {
return "zoonman";
}
// функция, которая вызывается, когда начинает проигрываться трек
void WINAPI __stdcall TrackPlay(DWORD User, DWORD dwCBType) {
AIMP2FileInfo aif;
WCHAR sArt[256]={L""};
WCHAR sTit[256]={L""};
bool r;
// чистим память
ZeroMemory(&aif, sizeof(aif));
aif.cbSizeOf = sizeof(aif);
aif.sArtist = sArt;
aif.nArtistLen=256;
aif.sTitle = sTit;
aif.nTitleLen = 256;
r = aimp->AIMP_GetCurrentTrack(&aif);
if (r) {
// ShowMessage(WideCharToString(aif.sArtist) + '=' + WideCharToString(aif.sTitle));
}
AnsiString st,str,rstr;
str = WideCharToString(aif.sTitle);
// теперь в str строчка с заголовком трека
}
// ---
void WINAPI Init(IAIMP2Controller *AController) {
// связываем функцию-обработчик TrackPlay() с событием AIMP_PLAY_FILE
AController->AIMP_CallBack_Set(AIMP_PLAY_FILE,TrackPlay, 1);
aimp = AController;
}
void WINAPI Config(DWORD Handle, DWORD Win) {
// тут надо бы поместить код для настройки св-в модуля
}
void WINAPI Free() {
// а тут по-хорошему грохнуть структуру aimp
};
/*
Инициализация структуры плагина
*/
AIMPAddonHeader plugin = {
PLUGIN_VERSION,
0,
GetPlgName,
GetAuthor,
Init,
Config,
Free
};
extern "C" __declspec( dllexport ) AIMPAddonHeader* AIMP_QueryAddon()
{
return &plugin;
}
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
//---------------------------------------------------------------------------
При компилянии не забудьте про Project/Options/Advanced Compiler/Calling convention [Standard call]
И про создание DLL в Билдере обязательно почитать!
-
То, что доктор прописал.
-
Вопрос.. Возможно глупый. Не могу правильно указать относительный путь к файлу. Уже по-всякому пробовал. Например EXE в папке \Aimp, а нужно прочитать из \Aimp\Plugins\config.ini
-
см. функицю AIMP_GetPath и параметр AIMP_CFG_PLUGINS
-
Спасибо. Вопрос решен :)
-
При каких изменениях в состоянии плеера посылается сallback на событие AIMP_TRACK_POS_CHANGED ? У меня оно срабатывает при "абсолютно неизменяемом" состоянии плеера примерно раз в секунду.
-
Да, сейчас оно срабатывает на обновлении дисплея, независимо от того, поменялась ли позиция. Я собираюсь это поправить, будет срабатывать только при изменении позиции
-
А вот такой вопрос. Написал вот так:
int index=pmanager->AIMP_PLS_ID_PlayingGet() ;
PLSInfo plifo;
aimp->AIMP_PLS_Info(index,&plifo);
String s= plifo.PLSName;
Я подумал, что AIMP_PLS_ID_PlayingGet() должна возвращать индекс проигрываемого листа :) , но ф-я ничего не возвращает... Почему-то.. Я поставил всё это на AIMP_PLAY_FILE. Может не так?
-
Она возвращает ID плейлиста, а не его индекс.
AIMP_PLS_Info возвращает информацию по индексу, чтобы по ID получить информацию о файле:
function AIMP_PLS_GetFilesCount(ID: HPLS): Integer; stdcall;
function AIMP_PLS_GetInfo(ID: HPLS; out ADuration, ASize: Int64): HRESULT; stdcall;
function AIMP_PLS_GetName(ID: HPLS; ABuffer: PWideChar; ABufferSizeInChars: Integer): HRESULT; stdcall;
а AIMP_PLS_Info функция устраевшая...
-
Ну так я хочу получить название текущего листа. ID описан, как int, но вот это int x=pman2->AIMP_PLS_ID_PlayingGet(); не работает. Что не так?
-
Получить имя можно через:
AIMP_PLS_GetName
ID описан как HPLS (который является Int)
-
Не получается :(
wchar_t *Buf;
int x=0;
x=pman2->AIMP_PLS_ID_PlayingGet();
pman2->AIMP_PLS_GetName(x,Buf,50);
OSDdisp->Label1->Caption=WideCharToString(Buf);
-
а где инициализируется буфер?
-
И всё еще не разобрался... Буфер ладно... до него дойдет.
Вот это int x=pman2->AIMP_PLS_ID_PlayingGet(); должно вернуть какое-то конкретное значение? Или там указатель.. или что.. Попробовал вывести x как строчку. - пусто.
-
X - как строчку? Х должен стать каким-нибудь числом > 0.
-
Не.. ну с IntToStr(int) конечно.. Странно. Можно на Delphi пример? (получения имени листа)
-
Такое ощущение, что AIMP_PLS_ID_PlayingGet() не работает. Она ничего не возвращает и, плюс, вешает всё остальное в обработчике, в котором прописана.
Подскажите примером, как надо? Пожалуйста... Нет сил уже :(
-
Подскажите пожалуйста, как узнать хендл GW?
-
http://slydiman.narod.ru/download/WinTreeInfo.zip
-
Вопрос не в этом. Как кодом узнать хендл GW. Пытаюсь решить проблему потери фокуса плеера при появлении моего OSD.
Пробовал вот так:
ha=FindWindow(AIMP2_RemoteClass, AIMP2_RemoteClass);
(FARPROC &)SwitchToThisWindow = GetProcAddress(hLib, "SwitchToThisWindow");
SwitchToThisWindow(ha,true);
Плеер получает фокус, но ,например, изменение громкости колесом всё-равно не работает.
-
Лучше тогда показывать свое окно без передачи на него фокуса, например, так:
ShowWindow(Handle, SW_SHOWNOACTIVATE)
-
Не помогло :( Результат такой же как и с моим кодом. После закрытия окна по CloseWindow(handle) моё OSD сворачивается над панелью задач и фокус плеера всё-равно теряется. Для того, что бы форма не появлялась на панели задач, первоначально я прописал на OnCreate вот такое
SetWindowLongPtr(Handle, GWL_EXSTYLE, WS_EX_TOOLWINDOW | WS_EX_LAYERED);
-
Тогда лучше так:
ASavedFocus := GetFocus;
...
SetFocus(ASavedFocus);
Ведь не обязательно фокус был конкретно на главном окне, он мог быть в плейлисте, эквалайзере или вообще в другом приложении...
-
Здравствуйте.
IAIMPAddonHeader - этот интерфейс должен реализовывать плагин и отдавать его плееру при обращении к AIMP_QueryAddonEx
IAIMPAddonHeader - это настоящий (наследуемый от IUnknown) интерфейс? Если да, то как там должны быть реализованы ф-ции QueryInterface, AddRef и Release? Хотелось бы посмотреть пример минимальной реализации (можно без тел функций) плагина-аддона к SDK v2.60 (можно на Delphi), например, чуть-чуть исходника плагина aimp_update.dll :-).
Заранее благодарен.
-
В дельфи есть такой класс TInterfacedObject, он уже имеет в себе реализацию IUnknown, поэтому Вам не нужно заморачиваться на этот счет.
-
В дельфи есть такой класс TInterfacedObject, он уже имеет в себе реализацию IUnknown, поэтому Вам не нужно заморачиваться на этот счет.
Спасибо, с этим я уже разобрался (нашел архив Tests+for+Addons, не очень удобно, что файлы разбросаны по всему форуму... :)). Существует какой-нибудь более быстрый способ для связи с Вами, например, Аська?
На данный момент меня интересует, что делают ф-ции IAIMP2PlaylistManager::AIMP_PLS_PlayFile и IAIMP2PlaylistManager::AIMP_PLS_ID_PlayingSetTrackIndex? Как можно просто добавить файл в плейлист и узнать его индекс? Можно ли вставить файл в определенное место в плейлисте?
Заранее благодарен.
-
Спасибо, с этим я уже разобрался (нашел архив Tests+for+Addons, не очень удобно, что файлы разбросаны по всему форуму... :)).
Как только допишу этот самый Tests for Addons - SDK появится на сайте. Просто руки никак не дойдут...
Существует какой-нибудь более быстрый способ для связи с Вами, например, Аська?
В ЛС отправил.
-
...Хотелось бы посмотреть пример минимальной реализации (можно без тел функций) плагина-аддона к SDK v2.60...
см. пост №12.
-
см. пост №12.
В посте 12 пример для старой версии SDK, мне был интересен пример для новой версии SDK (v2.60), с использованием интерфейса IAIMPAddonHeader, но, как я уже писал, с этим разобрались :-)
-
ДОбрый день.
Хотелось бы пример как использовать SDK под 2.6.x.x.
Не до конца понятно как использовать AIMP_QueryAddonEx(IAIMPAddonHeader *AHeader).
Поиск по форуму результатов не дал.
Спасибо.
-
Что именно не понятно?
-
class IIAIMPAddonHeader :public IAIMPAddonHeader
{
protected:
int m_nRefCount;
public:
BOOL WINAPI GetHasSettingsDialog()
{
return 1;
}
PWCHAR WINAPI GetPluginAuthor() {
ShowMessage("GetAutorFunc");
//wchar_t*
return (wchar_t*)"ildarM";
}
PWCHAR WINAPI GetPluginName()
{
ShowMessage("GetPluginName");
return (wchar_t*)"to flylink";
}
void WINAPI Finalize()
{
int i;
}
void WINAPI Initialize(IAIMP2Controller *AController)
{
ShowMessage("InitFunc");
}
void WINAPI ShowSettingsDialog(HWND AParentWindow)
{
int i;
}
STDMETHOD(QueryInterface)( REFIID refiid, void FAR* FAR* ppvObject )
{
*ppvObject = ( refiid == IID_IUnknown ) ? this : NULL;
if ( *ppvObject != NULL )
( (LPUNKNOWN)*ppvObject )->AddRef();
return *ppvObject == NULL ? E_NOINTERFACE : S_OK;
}
STDMETHOD_(ULONG, AddRef)( void )
{
return ++m_nRefCount;
}
STDMETHOD_(ULONG, Release)( void )
{
int nRefCount = --m_nRefCount;
if ( nRefCount == 0 )
delete this;
return nRefCount;
}
};
extern "C" __declspec (dllexport) BOOL __stdcall AIMP_QueryAddonEx(IAIMPAddonHeader *AHeader)
{
AHeader = new IIAIMPAddonHeader;
return 1;
}
Плагин в списке появился, но методы класса не вызываются
-
Вот код на Delphi, думаю разберетесь.
library aimp_addon;
uses
AIMP_SDK;
type
TMainClass = class(TInterfacedObject, IAIMPAddonHeader)
function GetHasSettingsDialog: LongBool; stdcall;
function GetPluginAuthor: PWideChar; stdcall;
function GetPluginName: PWideChar; stdcall;
procedure Finalize; stdcall;
procedure Initialize(AController: IAIMP2Controller); stdcall;
procedure ShowSettingsDialog(AParentWindow: HWND); stdcall;
end;
procedure TMainClass.Initialize(AController: IAIMP2Controller);
begin
// Тут вы инициализируете/создаете все компоненты вашего плагина, т.е. меню
// окна и т.д.
end;
procedure TMainClass.Finalize;
begin
// В этой процедуре нужно освобождать все ресурсы
// созданные в Initialize
end;
function TMainClass.GetPluginAuthor: PWideChar;
begin
Result := 'Автор плагина';
end;
function TMainClass.GetPluginName: PWideChar;
begin
Result := 'Название плагина';
end;
function TMainClass.GetHasSettingsDialog: LongBool;
begin
// Если есть окно с настройками то возвращаете True
// иначе False
Result := False;
end;
procedure TMainClass.ShowSettingsDialog(AParentWindow: HWND);
begin
// Если имеется окно с настройками, показываем его,
// иначе эта процедура игнорируется
end;
function AIMP_QueryAddonEx(out AHeader: IAIMPAddonHeader): LongBool; stdcall;
begin
// Тут необходимо вернуть ссылку на интерфейс, в нашем случае
// это будет выглядеть так:
AHeader := TMainClass.Create;
Result := True;
end;
exports
AIMP_QueryAddonEx;
begin
end.
-
По своему опыту скажу: главное не потерять stdcall (ну или что там в C++ Builder).
-
class IIAIMPAddonHeader :public /*IUnknown, */IAIMPAddonHeader
{
protected:
int m_nRefCount;
public:
BOOL WINAPI __stdcall GetHasSettingsDialog()
{
return FALSE;
}
PWCHAR WINAPI __stdcall GetPluginAuthor() {
ShowMessage("GetAutorFunc");
//wchar_t*
return (wchar_t*)"ildarM";
}
PWCHAR WINAPI __stdcall GetPluginName()
{
ShowMessage("GetPluginName");
return (wchar_t*)"to flylink";
}
void WINAPI __stdcall Finalize()
{
int i;
}
void WINAPI __stdcall Initialize(IAIMP2Controller *AController)
{
unsigned int ver = AController->AIMP_GetSystemVersion();
ShowMessage(IntToStr(__int64(ver)));
aimp = AController;
ShowMessage("InitFunc");
}
void WINAPI __stdcall ShowSettingsDialog(HWND AParentWindow)
{
int i;
}
STDMETHOD(QueryInterface)( REFIID refiid, void FAR* FAR* ppvObject )
{
*ppvObject = ( refiid == IID_IUnknown ) ? this : NULL;
if ( *ppvObject != NULL )
( (LPUNKNOWN)*ppvObject )->AddRef();
return *ppvObject == NULL ? E_NOINTERFACE : S_OK;
}
STDMETHOD_(ULONG, AddRef)( void )
{
return ++m_nRefCount;
}
STDMETHOD_(ULONG, Release)( void )
{
int nRefCount = --m_nRefCount;
if ( nRefCount == 0 )
delete this;
return nRefCount;
}
};
extern "C" __declspec (dllexport) BOOL __stdcall AIMP_QueryAddonEx(IAIMPAddonHeader *AHeader)
{
AHeader = NULL;
AHeader =(IAIMPAddonHeader*)new IIAIMPAddonHeader;
return TRUE;
}
вот что тут не так?
-
А в чем, собственно, вопрос. Этот код компилируется? Если нет, то что говорит компилятор? Если да, где возникают ошибки?
-
всё компилируется, ошибок нет, в меню плагинов появляется, но как мне его сделать активным?
отрабатывается только конструктор, а на методы не ходит...
-
...но как мне его сделать активным?
В смысле?
на методы не ходит...
На какие методы, он должен ходить?
-
плагин сейчас находиться в списке не загруженных.
при нажатии на чекбокс, он не отправляется в подключенные.
не ходит по методам "GetPluginAuthor() " например
-
Вы как отлаживаете плагин? Руками запускаете АИМП, для того чтобы осмотреть результат. Или из Builder-а по нажатию Run?
-
а разница?
создал объект, передал указатель на него... и всё Initialize не вызывается.
олтладчиком пользоваться умею
-
олтладчиком пользоваться умею
Good.
Тогда возникает заключение, что объект AHeader не создается, т.е. = NULL.
Проверьте строчку:
AHeader =(IAIMPAddonHeader*)new IIAIMPAddonHeader;
После неё значение AHeader должно быть отлично от NULL.
-
так и есть, значение не NULL. Объек создается
Добавлено через 6 мин. 28 сек.
могу прислать проект...
пишу на 2010 студии... но в принципе проблем быть не должно...
-
так и есть, значение не NULL. Объек создается
Ну даже, не знаю, в чем подвох.
могу прислать проект...
Выкладывайте на форум, посмотрим.
-
уверен что где-то моя ошибка, но пока понять не могу где именно
-
Мне кажется, что процедура AIMP_QueryAddonEx должна выглядеть как-то так:
{
(* AHeader) = new IIAIMPAddonHeader;
return TRUE;
}
-
нет, так не прокатило.
-
для работоспособности пока что сделал следующее( с подсказки Artem):
поменял в SDK строку
typedef BOOL (WINAPI *AIMPAddonHeaderProc)(IAIMPAddonHeader *AHeader);
на
typedef BOOL (WINAPI *AIMPAddonHeaderProc)(IAIMPAddonHeader **AHeader);
в экспортируемой функции плагина:
*AHeader = reinterpret_cast<IAIMPAddonHeader*>(new IIAIMPAddonHeader);
где IIAIMPAddonHeader наследник IAIMPAddonHeader.
после чего методы начали работать, но вылетает AV, ждем комментариев Artem-а
-
miketsoft подсказал (без изменений в SDK):
//---------------------------------------------------------------------------
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#include "aimp2_sdk.h"
//---------------------------------------------------------------------------
class TMyPlug: public TInterfacedObject, public IAIMPAddonHeader
{
private:
IAIMP2Controller *ctrl;
public:
HRESULT __stdcall QueryInterface(const GUID& IID, void **Obj)
{ return TInterfacedObject::QueryInterface(IID, (void *)Obj); }
ULONG __stdcall AddRef()
{ return TInterfacedObject::_AddRef(); }
ULONG __stdcall Release()
{ return TInterfacedObject::_Release(); }
BOOL __stdcall GetHasSettingsDialog() { return false; }
PWCHAR __stdcall GetPluginAuthor() { return L"MikeTSoft"; }
PWCHAR __stdcall GetPluginName() { return L"Cool MikeTSoft Plugin"; }
void __stdcall Finalize() {}
void __stdcall Initialize(IAIMP2Controller *AController) { ctrl=AController; }
void __stdcall ShowSettingsDialog(HWND AParentWindow) {}
};
//---------------------------------------------------------------------------
extern "C" __declspec(dllexport) BOOL __stdcall AIMP_QueryAddonEx(IAIMPAddonHeader *&AHeader)
{
AHeader=dynamic_cast<IAIMPAddonHeader *>(new TMyPlug());
return TRUE;
}
//---------------------------------------------------------------------------
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
//---------------------------------------------------------------------------
-
после чего методы начали работать, но вылетает AV, ждем комментариев Artem-а
Последовательность такая:
FAddonHeader := AHeader;
FPluginAuthor := AHeader.GetPluginAuthor;
FPluginName := AHeader.GetPluginName;
FAddonHeader.Initialize(AddonController);
-
Прототип ф-ции должен быть аналогичен прототипу ф-ции QueryInterface, имхо, например, такой:
extern "C" __declspec(dllexport) BOOL __stdcall AIMP_QueryAddonEx(IAIMPAddonHeader* &AHeader);
Т.е. нужно передавать ссылку на указатель на интерфейс (ну или указатель на указатель, кому как больше нравится). Делфя все эти вещи очень хитро скрывает... :)
Каком Ваш вердикт, братья-Сишники? :)
-
Переписал один из своих аддонов "по-новому" и появился вот такой "варнинг":
[BCC32 Warning] aimp2_sdk.h(10): W8058 Cannot create pre-compiled header: initialized data in header
Добавлено через 31 сек.
?
-
А ты aimp2_sdk.h подключил до строки "#pragma hdrstop" или после? Скорее всего, до. Переcтавь include после этой строки и должно пройти :)
-
Да. :) Перенёс все #includ'ы после #pragma hdrstop и стало хорошо.
-
miketsoft и bescheidener
есть примеры на новом SDK
-
Где?
-
извиняюсь, это был вопрос)
-
извиняюсь, это был вопрос)
Тот, что в 60-ом посте, не пробовал?
-
Выкладываю свой (подправленный и дополненный официальный) заголовочный файл aimp2_sdk.h и два примера плагинов (общий и визуализация) созданных с этим файлом. В заголовочный файл добавлены описания (пока еще не везде) и вспомогательный класс для создания плагинов. Все еще находится в стадии отладки, так что комментарии и замечания приветствуются (особенно от разрабов AIMP'а) :)
Добавлено через 3 мин. 23 сек.
Почему-то не добавился архив с плагами
-
Как мне запустить таймер при инициализации с этой новой структурой?
Это TimerP=SetTimer(NULL, 0, 500 , (TIMERPROC)Timer);
не работает.
-
Как мне запустить таймер при инициализации с этой новой структурой?
Это TimerP=SetTimer(NULL, 0, 500 , (TIMERPROC)Timer);
не работает.
Хз, нужно глянуть весь код... А почему бы не использовать компонент VCL TTimer?
-
Ну что там код... Как написал выше, таймер пытаюсь запустить из Init-функции. А функцию таймера
void CALLBACK _export TimerProc(HWND hwnd, UINT msg, UINT idTimer, DWORD dwTime)
размещаю "вне" и "до" класса. Плагин собирается и в списке плеера появляется, но не грузится.
-
Помогите с GDI+
Как начать, что нужно. Нашел в сети какой-то проектик для примера (аттач). Но он не компилится. Вылезает вот такой ворох ошибок и варнингов (BCB6):
[C++ Warning] Unit1.cpp(22): W8018 Assigning unsigned long to TColor
[C++ Warning] Unit1.cpp(37): W8018 Assigning unsigned long to TColor
[C++ Warning] Unit1.cpp(40): W8018 Assigning unsigned long to TColor
[C++ Error] GdiplusTypes.h(459): E2268 Call to undefined function 'min'
[C++ Error] GdiplusTypes.h(461): E2268 Call to undefined function 'max'
[C++ Error] GdiplusTypes.h(483): E2268 Call to undefined function 'max'
[C++ Error] GdiplusTypes.h(484): E2268 Call to undefined function 'max'
[C++ Error] GdiplusTypes.h(485): E2268 Call to undefined function 'min'
[C++ Error] GdiplusTypes.h(486): E2268 Call to undefined function 'min'
[C++ Error] GdiplusTypes.h(647): E2268 Call to undefined function 'min'
[C++ Error] GdiplusTypes.h(648): E2268 Call to undefined function 'min'
[C++ Error] GdiplusTypes.h(649): E2268 Call to undefined function 'max'
[C++ Error] GdiplusTypes.h(650): E2268 Call to undefined function 'max'
[C++ Error] GdiplusTypes.h(671): E2268 Call to undefined function 'max'
[C++ Error] GdiplusTypes.h(672): E2268 Call to undefined function 'max'
[C++ Error] GdiplusTypes.h(673): E2268 Call to undefined function 'min'
[C++ Error] GdiplusTypes.h(674): E2268 Call to undefined function 'min'
[C++ Warning] GdiplusHeaders.h(582): W8022 'Bitmap::Clone(const Rect &,int)' hides virtual function 'Image::Clone()'
[C++ Warning] GdiplusBrush.h(617): W8027 Functions containing for are not expanded inline
[C++ Warning] GdiplusBrush.h(656): W8027 Functions containing for are not expanded inline
[C++ Warning] GdiplusPen.h(316): W8027 Functions containing switch are not expanded inline
[C++ Warning] GdiplusPath.h(124): W8027 Functions containing some if statements are not expanded inline
[C++ Warning] GdiplusPath.h(1204): W8027 Functions containing for are not expanded inline
[C++ Warning] GdiplusPath.h(1234): W8027 Functions containing for are not expanded inline
[C++ Warning] GdiplusPath.h(1374): W8027 Functions containing for are not expanded inline
[C++ Warning] GdiplusPath.h(1416): W8027 Functions containing for are not expanded inline
[C++ Warning] GdiplusGraphics.h(1410): W8027 Functions containing for are not expanded inline
[C++ Error] GdiplusGraphics.h(34): E2015 Ambiguity between 'Gdiplus::Graphics::Graphics(void *)' and 'Gdiplus::Graphics::Graphics(void *,int)'
[C++ Warning] GdiplusFontCollection.h(70): W8027 Functions containing for are not expanded inline
[C++ Warning] GdiplusFont.h(127): W8027 Functions containing some if statements are not expanded inline
[C++ Error] gdip.cpp(25): E2015 Ambiguity between 'Gdiplus::Graphics::Graphics(void *)' and 'Gdiplus::Graphics::Graphics(void *,int)'
-
Ну что там код... Как написал выше, таймер пытаюсь запустить из Init-функции. А функцию таймера void CALLBACK _export TimerProc(HWND hwnd, UINT msg, UINT idTimer, DWORD dwTime)
размещаю "вне" и "до" класса. Плагин собирается и в списке плеера появляется, но не грузится.
Долго мучался с этой проблемой. Решение(на Delphi): добавить к процедуре stdcall.
procedure TimerProcedure(Handle: HWND; uMsg: UINT;
idEvent: UINT_PTR; dwTime: DWORD); stdcall;
begin
. . .
end;
-
Помогите люди добрые (степень доброты значения не имеет ;D )
Если решится данная проблема, то скрорее всего AOSD3 будет готов в недельный срок.
Пороблема вот в чём:
- для обновления содержимого окна я написал такую процедурку:
void RenderForm(void)
{
TopLeft = Point(Form2->Left,Form2->Top);
DC = GetDC(0);
::UpdateLayeredWindow(Form2->Handle,DC,&TopLeft, &zsize, sdc,&zpoint,0, &zbf, ULW_ALPHA);
ReleaseDC(0,DC);
}
С этой процедурой проблем нет.
HDC sdc; //объявлена глобально
Есть битмап, на котором рисуется OSD.
Gdiplus::Bitmap BT;
Затем мне нужно обновить sdc в соответствии с BT.
Для этого я делаю:
sdc = GetBitmapDC(BT,Form2->Canvas->Handle);
где GetBitmapDC() это
HDC GetBitmapDC(Gdiplus::Bitmap *b, HWND handle)
{
HDC shdc;
HBITMAP hbmp;
HGDIOBJ temp;
shdc = CreateCompatibleDC (handle);
b->GetHBITMAP (NULL, &hbmp);
temp = SelectObject (shdc, hbmp);
return shdc;
}
Вот с последней функцией проблемы. С каждым её вызовом подъедается оператива.
Помогите освободить память!
Или может есть какой-то другой способ обновлять (рисовать) слоистое окно.?
-
Нужно не забывать убивать hbmp (создает функция b->GetHBITMAP) и shdc, когда они уже не нужны
-
Ну вот покопался и добавил вначале последней ф-и
DeleteObject (SelectObject (sdc, temp));
DeleteDC (sdc);
т.е. удаляю глобальный HDC sdc; и определяю его снова.
- вроде поутихло, при прорисовке битмапов на BT и редраве оператива на месте.
А почему нужно убивать hbmp b shdc ? Они же живут только пока работает GetBitmapDC() или нет?
Опять же, непонятно, как удалить кисть или шрифт - заметил, что там тоже утечка.
-
>> GetBitmapDC() или нет?
Нет.
>> Опять же, непонятно, как удалить кисть или шрифт - заметил, что там тоже утечка.
DeleteObject()
-
Привет всем :)
Пытаюсь показать иконку около созданного меню плагином...
Написал код, меню добавляется корректно, иконка не отображается:
//Собственно загрузка иконки из ресурсов в HBITMAP
HBITMAP hImage = LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_BITMAP1));
AIMPMenuInfo nfo;
ZeroMemory(&nfo, sizeof(nfo));
nfo.Checkbox = false;
nfo.RadioItem = false;
nfo.Checked = false;
nfo.Enabled = true;
nfo.Bitmap = hImage;
nfo.ProcPtr = (int)MenuProc;
nfo.Caption = L"test";
nfo.User = 0;
Controller->AIMP_Menu_Create(AIMP_PLS_MENU, &nfo);
Что я делаю не правильно? :)
Так же есть еще вопрос... Добавляю URL в плейлист, файл добавляется в категорию "None". Что отвечает за имя категории? А то None как-то некрасиво =)))
И еще при добавлении URL заполняю в структуре AIMP2FileInfo поле Artist, Title, Album - все добавляется нормально, в информации о файле в плеере все ок, а при запуске проигрывания файла в имени вместо "Artist - Title" выводится ссылка... Как оставить формат "Artist - Title"?
И последний вопрос. Может быть на форуме уже где-то и было, не нашел) . Есть ли возможность создавать "Аимповые" окошки? Или рисовать под оформление Аимпа вручную?
Заранее спасибо за ответы =)
-
Привет всем :)
Пытаюсь показать иконку около созданного меню плагином...
Написал код, меню добавляется корректно, иконка не отображается:
//Собственно загрузка иконки из ресурсов в HBITMAP
HBITMAP hImage = LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_BITMAP1));
AIMPMenuInfo nfo;
ZeroMemory(&nfo, sizeof(nfo));
nfo.Checkbox = false;
nfo.RadioItem = false;
nfo.Checked = false;
nfo.Enabled = true;
nfo.Bitmap = hImage;
nfo.ProcPtr = (int)MenuProc;
nfo.Caption = L"test";
nfo.User = 0;
Controller->AIMP_Menu_Create(AIMP_PLS_MENU, &nfo);
Что я делаю не правильно? :)
Так же есть еще вопрос... Добавляю URL в плейлист, файл добавляется в категорию "None". Что отвечает за имя категории? А то None как-то некрасиво =)))
И еще при добавлении URL заполняю в структуре AIMP2FileInfo поле Artist, Title, Album - все добавляется нормально, в информации о файле в плеере все ок, а при запуске проигрывания файла в имени вместо "Artist - Title" выводится ссылка... Как оставить формат "Artist - Title"?
И последний вопрос. Может быть на форуме уже где-то и было, не нашел) . Есть ли возможность создавать "Аимповые" окошки? Или рисовать под оформление Аимпа вручную?
Заранее спасибо за ответы =)
GetModuleHandle(NULL)
уверены, что вы получаете handle вашей dll а не AIMP.exe, попробуйте указать имя DLL.
Есть ли возможность создавать "Аимповые" окошки?
нет.
-
Написал код, меню добавляется корректно, иконка не отображается:
//Собственно загрузка иконки из ресурсов в HBITMAP
HBITMAP hImage = LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_BITMAP1));
AIMPMenuInfo nfo;
ZeroMemory(&nfo, sizeof(nfo));
nfo.Checkbox = false;
nfo.RadioItem = false;
nfo.Checked = false;
nfo.Enabled = true;
nfo.Bitmap = hImage;
nfo.ProcPtr = (int)MenuProc;
nfo.Caption = L"test";
nfo.User = 0;
Controller->AIMP_Menu_Create(AIMP_PLS_MENU, &nfo);
Что я делаю не правильно? :)
Дело в этой строке:
HBITMAP hImage = LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_BITMAP1));
Попробуйте так:
HBITMAP hImage = LoadBitmap(GetModuleHandle(NULL),"IDB_BITMAP1");
или вот так:
HBITMAP hImage = LoadBitmap(hInst, "IDB_BITMAP1");
Так же есть еще вопрос... Добавляю URL в плейлист, файл добавляется в категорию "None". Что отвечает за имя категории? А то None как-то некрасиво =)))
И еще при добавлении URL заполняю в структуре AIMP2FileInfo поле Artist, Title, Album - все добавляется нормально, в информации о файле в плеере все ок, а при запуске проигрывания файла в имени вместо "Artist - Title" выводится ссылка... Как оставить формат "Artist - Title"?
Таков движок аимпа :)
-
акукусики,
HBITMAP hImage = LoadBitmap(GetModuleHandle(L"AIMP_IMS.dll"),MAKEINTRESOURCE(IDB_BITMAP1));
тоже не работает((( иконка 16х16 должна быть? Может там в чем-то ошибся...
Lyuter,
Попробовал все варианты кроме последнего, не работает :(
а в последнем не могу получить HINSTANCE
-
мне все-таки кажется это неверный хэндл возвращается, там вообще значение отличное от NULL получается?
пробуйте либо GetModuleHandle("имя_вашей_DLL") либо в структуре AddonHeader в AIMP SDK есть такое поле DllInstance Если я не ошибаюсь, не зря же его вводили)
Добавлено через 44 сек.
акукусики,
HBITMAP hImage = LoadBitmap(GetModuleHandle(L"AIMP_IMS.dll"),MAKEINTRESOURCE(IDB_BITMAP1));
тоже не работает((( иконка 16х16 должна быть? Может там в чем-то ошибся...
Lyuter,
Попробовал все варианты кроме последнего, не работает :(
а в последнем не могу получить HINSTANCE
без DLL, "AIMP_IMS" просто
-
акукусики,
Без .dll пробовал тоже...
Ну тогда попробую поковыряю AddonHeader...
-
акукусики,
Без .dll пробовал тоже...
Ну тогда попробую поковыряю AddonHeader...
если не работает, о можете не ковырять, потому что GetModuleHandle("имя вашей сборки")=AIMPAddonHeader.DllInstance, я так думаю. значит причина не только в этом. проще кинуть код)
LoadBitmap(GetModuleHandle(L"AIMP_IMS"),MAKEINTRESOURCE(IDB_BITMAP1));
Если действительно ваша DLL так называется и если действительно имеется изображение в ресурсах с таким идентификатором, то ошибки быть не должно) проверьте возвращаемое значение.
-
Если действительно ваша DLL так называется и если действительно имеется изображение в ресурсах с таким идентификатором, то ошибки быть не должно) проверьте возвращаемое значение.
все, заработало)) спасибо!
Оказывается вся проблема была в том, что я для тестирования создал картинку желтого цвета, а он выводился как прозрачный)))
Я вообще уже не знал, что делать)))
Спасибо за помощь!
-
все, заработало)) спасибо!
Оказывается вся проблема была в том, что я для тестирования создал картинку желтого цвета, а он выводился как прозрачный)))
Я вообще уже не знал, что делать)))
;D
Ничего страшного так иногда бывает. ;)
-
все, заработало)) спасибо!
Оказывается вся проблема была в том, что я для тестирования создал картинку желтого цвета, а он выводился как прозрачный)))
Я вообще уже не знал, что делать)))
Спасибо за помощь!
не за что, это MSDN (http://msdn.microsoft.com/en-us/library/ms683199(VS.85).aspx)молодец)
If this parameter is NULL, GetModuleHandle returns a handle to the file used to create the calling process (.exe file).
кстати можно и extension указывать) если не указывать то по умолчанию добавляется .DLL
-
Привет всем!
Как анулировать вызов AIMP_CallBack_Set(AIMP_TRACK_POS_CHANGED,TrackPlay, 1) при помощи функции AIMP_CallBack_Remove. На сколько я понимаю первый параметр в ней такой же что и AIMP_CallBack_Set, а вот что за второй параметр int ProcPtr.
Спасибо!
-
function AIMP_CallBack_Set(dwCBType: DWORD; Proc: Pointer; User: DWORD): Boolean; stdcall;
function AIMP_CallBack_Remove(dwCBType: DWORD; Proc: Pointer): Boolean; stdcall;
Логично предположить что тотже что и у Set
-
Спасибо, я уже разобрался!
-
Извините за глупый вопрос но как можно на с++ через sdk например остановить песню
-
Сам пытаюсь разобраться. Мне необходимо остановить воспроизведение файла в одном плейлисте, перейти в другой плейлист и там случайным образом выбрать файл и начать его воспроизведение. Если получится - напишу.
-
Из плагина.
У IAIMP2Controller есть функция AIMP_Status_Set
AIMP_Status_Set(AIMP_STS_Player,0) - Stop
AIMP_Status_Set(AIMP_STS_Player,1) - Play
AIMP_Status_Set(AIMP_STS_Player,2) - Pause
Это по идее, не проверял
-
Еще в ветке по делфи Артем писал следующие
IAIMP2Controller.AIMP_CallFunction(AIMP_PLAY) - Play
По аналогий
IAIMP2Controller.AIMP_CallFunction(AIMP_STOP) - Stop
IAIMP2Controller.AIMP_CallFunction(AIMP_PAUSE) - Pause
-
А как получить вообще какой-нибудь объект из SDK например IAIMP2Controller, на с++
-
С помощью функции инициализации плагина
void WINAPI Init(IAIMP2Controller *AController)
Как видно, она содержит указатель на объект IAIMP2Controller. Все остальные объекты вызываются при помощи функции AIMP_QueryObject
-
А кто-нибудь знает как поставить на паузу трек, потом включить воспроизведение другой композиции, а в конце вернутся к первой композиции и продолжить воспроизведение именно с того же места где она была поставлена на паузу?
-
А кто-нибудь знает как поставить на паузу трек, потом включить воспроизведение другой композиции, а в конце вернутся к первой композиции и продолжить воспроизведение именно с того же места где она была поставлена на паузу?
По идее создаешь переменную которая хранят текущую позицию файла и ставишь его в очередь:) или еще в одной переменной хранишь путь к предыдущему файлу и по окончании переходишь к нему :)
-
Есть ли какаято книга или ученбик?
-
Есть ли какаято книга или ученбик?
google.ru
-
Что захотелоь покопаться с новым SDK... пока безуспешно :)
"Накалякал" вот такое (С++ Builder XE2):
//---------------------------------------------------------------------------
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#include "AIMPSDKAddons.h"
#include "AIMPSDKCommon.h"
#include "AIMPSDKCore.h"
//---------------------------------------------------------------------------
class Tnew_st: public TInterfacedObject, public IAIMPAddonPlugin
{
public:
HRESULT __stdcall QueryInterface(const GUID& IID, void **Obj)
{ return TInterfacedObject::QueryInterface(IID, (void *)Obj); }
ULONG __stdcall AddRef()
{ return TInterfacedObject::_AddRef(); }
ULONG __stdcall Release()
{ return TInterfacedObject::_Release(); }
protected:
PWCHAR __stdcall GetPluginAuthor();
PWCHAR __stdcall GetPluginInfo();
PWCHAR __stdcall GetPluginName();
DWORD __stdcall GetPluginFlags();
HRESULT __stdcall Initialize(IAIMPCoreUnit *ACoreUnit);
HRESULT __stdcall Finalize();
HRESULT __stdcall ShowSettingsDialog(HWND AParentWindow);
};
//---------------------------------------------------------------------------
PWCHAR __stdcall Tnew_st::GetPluginAuthor()
{return L"author";};
PWCHAR __stdcall Tnew_st::GetPluginInfo()
{return L"info";};
PWCHAR __stdcall Tnew_st::GetPluginName()
{return L"x2_dev";};
DWORD __stdcall Tnew_st::GetPluginFlags()
{return AIMP_ADDON_FLAGS_HAS_DIALOG;};
HRESULT __stdcall Tnew_st::Initialize(IAIMPCoreUnit *ACoreUnit)
{return 1;};
HRESULT __stdcall Tnew_st::Finalize()
{return 1;};
HRESULT __stdcall Tnew_st::ShowSettingsDialog(HWND AParentWindow)
{ShowMessage("Opt_dlg");
return S_OK;};
//---------------------------------------------------------------------------
extern "C"__declspec(dllexport) BOOL __stdcall AIMP_QueryAddon3(IAIMPAddonPlugin *&AHeader)
{
AHeader= new Tnew_st();
return 1;
}
Плеер плагин видит, загружает/выгружает. При открытии настроек выскакиевает MessageBox - всё нормально. Закрываю этот "бокс". Всё: больше кнопка настроек не работает, а при выгрузке плагин летит в Unstable.
Помогите пожалуйста допилить этот минимум кода.
-
Можешь бинарник дать? дома посмотрю.
-
не уверен, что он будет работать без "билдера".
-
ты скомпили его без рантайм-пакетов, тогда будет.
-
-
хм, падает при попытке обращения к методу _Release интерфейса IUnknown, который у тебя судя по всему реализуется классом TInterfacedObject.
Я не совсем понял, зачем ты переопределил методы IUnknown-а в наследнике?
-
...Вот эта какашка компилится и работает, кроме закоментированной строки
(Выдает:
[ILINK32 Error] Error: Unresolved external '_IID_IAIMPAddonsPlayerManager' referenced from E:\DOCUMENTS\AIMP_DEV\API3\DEBUG\M3.OBJ)
Помогите кто чем может. :)
#include <vcl.h>
#include <windows.h>
#include "m3.h"
#include "AIMPSDKAddons.h"
#include "AIMPSDKCore.h"
#include "Settings.h"
#pragma hdrstop
IAIMPCoreUnit* ACore;
IAIMPAddonsPlayerManager *APlayerManager;
String GetV(void)
{ String ret;
TAIMPVersionInfo* ui;
ui = new TAIMPVersionInfo;
ACore->GetVersion(ui);
ret = "Aimp build is: "+IntToStr(ui->BuildNumber);
delete ui;
return ret;
}
typedef class AddonPlugin: public IAIMPAddonPlugin {
private:
public:
virtual PWCHAR WINAPI GetPluginAuthor() { return L"bener"; }
virtual PWCHAR WINAPI GetPluginInfo() { return L"dev_proj."; }
virtual PWCHAR WINAPI GetPluginName() { return L"api_3"; }
virtual DWORD WINAPI GetPluginFlags() { return AIMP_ADDON_FLAGS_HAS_DIALOG;}
virtual HRESULT WINAPI Initialize(IAIMPCoreUnit* ACoreUnit)
{Form1 = new TForm1(Form1);
ACore = ACoreUnit;
//ACoreUnit->QueryInterface(IID_IAIMPAddonsPlayerManager, (void **)&APlayerManager);
return S_OK;}
virtual HRESULT WINAPI ShowSettingsDialog(HWND AParentWindow)
{Form1->Show();
return S_OK;}
virtual HRESULT WINAPI Finalize()
{
delete Form1;
return S_OK;}
virtual HRESULT WINAPI QueryInterface(const IID &,void **) { return S_OK; }
virtual ULONG WINAPI AddRef(void) { return S_OK; }
virtual ULONG WINAPI Release(void) { return S_OK; }
}TAddonPlugin;
extern "C" __declspec(dllexport) BOOL WINAPI AIMP_QueryAddon3(IAIMPAddonPlugin **AHeader) {
*AHeader = new TAddonPlugin();
return true;
}
-
Проблему решил, поправив определение IID_IAIMPAddonsPlayerManager в заголовочном файле.