mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-17 17:05:46 -04:00
Initial community commit
This commit is contained in:
147
Src/Plugins/Library/ml_nowplaying/common.cpp
Normal file
147
Src/Plugins/Library/ml_nowplaying/common.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
#include "./common.h"
|
||||
#include "./wasabi.h"
|
||||
|
||||
#include <strsafe.h>
|
||||
|
||||
LPWSTR Plugin_MallocString(size_t cchLen)
|
||||
{
|
||||
return (LPWSTR)calloc(cchLen, sizeof(WCHAR));
|
||||
}
|
||||
|
||||
void Plugin_FreeString(LPWSTR pszString)
|
||||
{
|
||||
if (NULL != pszString)
|
||||
{
|
||||
free(pszString);
|
||||
}
|
||||
}
|
||||
|
||||
LPWSTR Plugin_ReAllocString(LPWSTR pszString, size_t cchLen)
|
||||
{
|
||||
return (LPWSTR)realloc(pszString, sizeof(WCHAR) * cchLen);
|
||||
}
|
||||
|
||||
LPWSTR Plugin_CopyString(LPCWSTR pszSource)
|
||||
{
|
||||
if (NULL == pszSource)
|
||||
return NULL;
|
||||
|
||||
INT cchSource = lstrlenW(pszSource) + 1;
|
||||
|
||||
LPWSTR copy = Plugin_MallocString(cchSource);
|
||||
if (NULL != copy)
|
||||
{
|
||||
CopyMemory(copy, pszSource, sizeof(WCHAR) * cchSource);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
LPSTR Plugin_MallocAnsiString(size_t cchLen)
|
||||
{
|
||||
return (LPSTR)calloc(cchLen, sizeof(CHAR));
|
||||
}
|
||||
|
||||
LPSTR Plugin_CopyAnsiString(LPCSTR pszSource)
|
||||
{
|
||||
if (NULL == pszSource)
|
||||
return NULL;
|
||||
|
||||
INT cchSource = lstrlenA(pszSource) + 1;
|
||||
|
||||
LPSTR copy = Plugin_MallocAnsiString(cchSource);
|
||||
if (NULL != copy)
|
||||
{
|
||||
CopyMemory(copy, pszSource, sizeof(CHAR) * cchSource);
|
||||
}
|
||||
return copy;
|
||||
|
||||
}
|
||||
void Plugin_FreeAnsiString(LPSTR pszString)
|
||||
{
|
||||
Plugin_FreeString((LPWSTR)pszString);
|
||||
}
|
||||
|
||||
LPSTR Plugin_WideCharToMultiByte(UINT codePage, DWORD dwFlags, LPCWSTR lpWideCharStr, INT cchWideChar, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar)
|
||||
{
|
||||
INT cchBuffer = WideCharToMultiByte(codePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, lpDefaultChar, lpUsedDefaultChar);
|
||||
if (0 == cchBuffer) return NULL;
|
||||
|
||||
LPSTR buffer = Plugin_MallocAnsiString(cchBuffer);
|
||||
if (NULL == buffer) return NULL;
|
||||
|
||||
if (0 == WideCharToMultiByte(codePage, dwFlags, lpWideCharStr, cchWideChar, buffer, cchBuffer, lpDefaultChar, lpUsedDefaultChar))
|
||||
{
|
||||
Plugin_FreeAnsiString(buffer);
|
||||
return NULL;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
LPWSTR Plugin_MultiByteToWideChar(UINT codePage, DWORD dwFlags, LPCSTR lpMultiByteStr, INT cbMultiByte)
|
||||
{
|
||||
if (NULL == lpMultiByteStr) return NULL;
|
||||
INT cchBuffer = MultiByteToWideChar(codePage, dwFlags, lpMultiByteStr, cbMultiByte, NULL, 0);
|
||||
if (NULL == cchBuffer) return NULL;
|
||||
|
||||
if (cbMultiByte > 0) cchBuffer++;
|
||||
|
||||
LPWSTR buffer = Plugin_MallocString(cchBuffer);
|
||||
if (NULL == buffer) return NULL;
|
||||
|
||||
if (0 == MultiByteToWideChar(codePage, dwFlags, lpMultiByteStr, cbMultiByte, buffer, cchBuffer))
|
||||
{
|
||||
Plugin_FreeString(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cbMultiByte > 0)
|
||||
{
|
||||
buffer[cchBuffer - 1] = L'\0';
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
LPWSTR Plugin_DuplicateResString(LPCWSTR pszResource)
|
||||
{
|
||||
return (IS_INTRESOURCE(pszResource)) ?
|
||||
(LPWSTR)pszResource :
|
||||
Plugin_CopyString(pszResource);
|
||||
}
|
||||
|
||||
void Plugin_FreeResString(LPWSTR pszResource)
|
||||
{
|
||||
if (!IS_INTRESOURCE(pszResource))
|
||||
Plugin_FreeString(pszResource);
|
||||
}
|
||||
|
||||
HRESULT Plugin_CopyResString(LPWSTR pszBuffer, INT cchBufferMax, LPCWSTR pszString)
|
||||
{
|
||||
if (NULL == pszBuffer)
|
||||
return E_INVALIDARG;
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (NULL == pszString)
|
||||
{
|
||||
pszBuffer[0] = L'\0';
|
||||
}
|
||||
else if (IS_INTRESOURCE(pszString))
|
||||
{
|
||||
if (NULL == WASABI_API_LNG)
|
||||
hr = E_FAIL;
|
||||
else
|
||||
WASABI_API_LNGSTRINGW_BUF((INT)(INT_PTR)pszString, pszBuffer, cchBufferMax);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = StringCchCopy(pszBuffer, cchBufferMax, pszString);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
void Plugin_SafeRelease(IUnknown *pUnk)
|
||||
{
|
||||
if (NULL != pUnk)
|
||||
pUnk->Release();
|
||||
}
|
58
Src/Plugins/Library/ml_nowplaying/common.h
Normal file
58
Src/Plugins/Library/ml_nowplaying/common.h
Normal file
@ -0,0 +1,58 @@
|
||||
#ifndef NULLSOFT_NOWPLAYING_PLUGIN_COMMON_HEADER
|
||||
#define NULLSOFT_NOWPLAYING_PLUGIN_COMMON_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
#include "../nu/trace.h"
|
||||
|
||||
#define CSTR_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)
|
||||
|
||||
#ifndef ARRAYSIZE
|
||||
#define ARRAYSIZE(blah) (sizeof(blah)/sizeof(*blah))
|
||||
#endif
|
||||
|
||||
#ifndef LONGX86
|
||||
#ifdef _WIN64
|
||||
#define LONGX86 LONG_PTR
|
||||
#else /*_WIN64*/
|
||||
#define LONGX86 LONG
|
||||
#endif /*_WIN64*/
|
||||
#endif // LONGX86
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define SENDMSG(__hwnd, __msgId, __wParam, __lParam) ::SendMessageW((__hwnd), (__msgId), (__wParam), (__lParam))
|
||||
#else
|
||||
#define SENDMSG(__hwnd, __msgId, __wParam, __lParam) SendMessageW((__hwnd), (__msgId), (__wParam), (__lParam))
|
||||
#endif // __cplusplus
|
||||
|
||||
#define SENDMLIPC(__hwndML, __ipcMsgId, __param) SENDMSG((__hwndML), WM_ML_IPC, (WPARAM)(__param), (LPARAM)(__ipcMsgId))
|
||||
#define SENDWAIPC(__hwndWA, __ipcMsgId, __param) SENDMSG((__hwndWA), WM_WA_IPC, (WPARAM)(__param), (LPARAM)(__ipcMsgId))
|
||||
|
||||
#define MSGRESULT(__hwnd, __result) { SetWindowLongPtrW((__hwnd), DWL_MSGRESULT, ((LONGX86)(LONG_PTR)(__result))); return TRUE; }
|
||||
|
||||
#define SENDCMD(__hwnd, __ctrlId, __eventId, __hctrl) (SENDMSG((__hwnd), WM_COMMAND, MAKEWPARAM(__ctrlId, __eventId), (LPARAM)(__hctrl)))
|
||||
|
||||
|
||||
LPWSTR Plugin_MallocString(size_t cchLen);
|
||||
LPWSTR Plugin_ReAllocString(LPWSTR pszString, size_t cchLen);
|
||||
void Plugin_FreeString(LPWSTR pszString);
|
||||
LPWSTR Plugin_CopyString(LPCWSTR pszSource);
|
||||
|
||||
LPSTR Plugin_MallocAnsiString(size_t cchLen);
|
||||
LPSTR Plugin_CopyAnsiString(LPCSTR pszSource);
|
||||
void Plugin_FreeAnsiString(LPSTR pszString);
|
||||
|
||||
LPWSTR Plugin_DuplicateResString(LPCWSTR pszResource);
|
||||
void Plugin_FreeResString(LPWSTR pszResource);
|
||||
HRESULT Plugin_CopyResString(LPWSTR pszBuffer, INT cchBufferMax, LPCWSTR pszString);
|
||||
|
||||
LPSTR Plugin_WideCharToMultiByte(UINT codePage, DWORD dwFlags, LPCWSTR lpWideCharStr, INT cchWideChar, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar);
|
||||
LPWSTR Plugin_MultiByteToWideChar(UINT codePage, DWORD dwFlags, LPCSTR lpMultiByteStr, INT cbMultiByte);
|
||||
|
||||
void Plugin_SafeRelease(IUnknown *pUnk);
|
||||
|
||||
|
||||
#endif //NULLSOFT_NOWPLAYING_PLUGIN_COMMON_HEADER
|
110
Src/Plugins/Library/ml_nowplaying/external.cpp
Normal file
110
Src/Plugins/Library/ml_nowplaying/external.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
#include "main.h"
|
||||
#include "./resource.h"
|
||||
#include "./external.h"
|
||||
|
||||
ExternalDispatch::ExternalDispatch()
|
||||
: ref(1)
|
||||
{
|
||||
}
|
||||
|
||||
ExternalDispatch::~ExternalDispatch()
|
||||
{
|
||||
}
|
||||
|
||||
HRESULT ExternalDispatch::CreateInstance(ExternalDispatch **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
|
||||
*instance = new ExternalDispatch();
|
||||
if (NULL == *instance) return E_OUTOFMEMORY;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LPCWSTR ExternalDispatch::GetName()
|
||||
{
|
||||
return L"NowPlaying";
|
||||
}
|
||||
|
||||
|
||||
ULONG ExternalDispatch::AddRef(void)
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&ref);
|
||||
}
|
||||
|
||||
|
||||
ULONG ExternalDispatch::Release(void)
|
||||
{
|
||||
if (0 == ref)
|
||||
return ref;
|
||||
|
||||
LONG r = InterlockedDecrement((LONG*)&ref);
|
||||
if (0 == r)
|
||||
delete(this);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
STDMETHODIMP ExternalDispatch::QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
if (NULL == ppvObject) return E_POINTER;
|
||||
|
||||
if (IsEqualIID(riid, IID_IDispatch))
|
||||
*ppvObject = static_cast<IDispatch*>(this);
|
||||
else if (IsEqualIID(riid, IID_IUnknown))
|
||||
*ppvObject = static_cast<IUnknown*>(this);
|
||||
else
|
||||
{
|
||||
*ppvObject = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT ExternalDispatch::GetIDsOfNames(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid)
|
||||
{
|
||||
bool unknowns = false;
|
||||
for (unsigned int i = 0;i != cNames;i++)
|
||||
{
|
||||
if (_wcsicmp(rgszNames[i], L"hidden") == 0)
|
||||
rgdispid[i] = DISPATCH_HIDDEN;
|
||||
else
|
||||
{
|
||||
rgdispid[i] = DISPID_UNKNOWN;
|
||||
unknowns = true;
|
||||
}
|
||||
}
|
||||
if (unknowns)
|
||||
return DISP_E_UNKNOWNNAME;
|
||||
else
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT ExternalDispatch::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT ExternalDispatch::GetTypeInfoCount(unsigned int FAR * pctinfo)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT ExternalDispatch::Invoke(DISPID dispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr)
|
||||
{
|
||||
switch(dispId)
|
||||
{
|
||||
case DISPATCH_HIDDEN:
|
||||
if (NULL != pvarResult)
|
||||
{
|
||||
HWND hLibrary = Plugin_GetLibrary();
|
||||
VariantInit(pvarResult);
|
||||
V_VT(pvarResult) = VT_BOOL;
|
||||
V_BOOL(pvarResult) = (NULL == hLibrary || FALSE == SENDMLIPC(hLibrary, ML_IPC_IS_VISIBLE, 0));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
}
|
44
Src/Plugins/Library/ml_nowplaying/external.h
Normal file
44
Src/Plugins/Library/ml_nowplaying/external.h
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef NULLSOFT_NOWPLAYING_PLUGIN_EXTERNAL_HEADER
|
||||
#define NULLSOFT_NOWPLAYING_PLUGIN_EXTERNAL_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
class ExternalDispatch : public IDispatch
|
||||
{
|
||||
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
DISPATCH_HIDDEN = 777,
|
||||
} DispatchCodes;
|
||||
|
||||
protected:
|
||||
ExternalDispatch();
|
||||
~ExternalDispatch();
|
||||
|
||||
public:
|
||||
static HRESULT CreateInstance(ExternalDispatch **instance);
|
||||
static LPCWSTR GetName();
|
||||
|
||||
public:
|
||||
STDMETHOD(QueryInterface)(REFIID riid, PVOID *ppvObject);
|
||||
STDMETHOD_(ULONG, AddRef)(void);
|
||||
STDMETHOD_(ULONG, Release)(void);
|
||||
|
||||
// *** IDispatch Methods ***
|
||||
STDMETHOD (GetIDsOfNames)(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid);
|
||||
STDMETHOD (GetTypeInfo)(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo);
|
||||
STDMETHOD (GetTypeInfoCount)(unsigned int FAR * pctinfo);
|
||||
STDMETHOD (Invoke)(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr);
|
||||
|
||||
protected:
|
||||
ULONG ref;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //NULLSOFT_NOWPLAYING_PLUGIN_EXTERNAL_HEADER
|
47
Src/Plugins/Library/ml_nowplaying/handler.cpp
Normal file
47
Src/Plugins/Library/ml_nowplaying/handler.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include "main.h"
|
||||
#include "service.h"
|
||||
#include "navigation.h"
|
||||
#include "handler.h"
|
||||
#include "../Agave/URIHandler/svc_urihandler.h"
|
||||
#include <api/service/waservicefactory.h>
|
||||
#include "api.h"
|
||||
#include "../ml_online/config.h"
|
||||
#include "../replicant/nu/Autowide.h"
|
||||
|
||||
int NowPlayingURIHandler::ProcessFilename(const wchar_t *filename)
|
||||
{
|
||||
if (!_wcsnicmp(filename, L"winamp://Now Playing", 20) || !_wcsnicmp(filename, L"winamp://Now%20Playing", 22))
|
||||
{
|
||||
size_t index = 0;
|
||||
if (filename[12] == L' ')
|
||||
index = 20;
|
||||
else
|
||||
index = 22;
|
||||
|
||||
wchar_t fullUrl[1024] = L"http://client.winamp.com/nowplaying";
|
||||
lstrcpynW(fullUrl, AutoWide(g_config->ReadString("nowplayingurl", "http://client.winamp.com/nowplaying")), ARRAYSIZE(fullUrl));
|
||||
|
||||
if (filename[index] != 0)
|
||||
{
|
||||
StringCchCatW(fullUrl, 1024, filename + index);
|
||||
}
|
||||
Navigation_ShowService(SERVICE_ID, fullUrl, NAVFLAG_FORCEACTIVE | NAVFLAG_ENSUREMLVISIBLE | NAVFLAG_ENSUREITEMVISIBLE);
|
||||
return HANDLED_EXCLUSIVE;
|
||||
}
|
||||
return NOT_HANDLED;
|
||||
}
|
||||
|
||||
int NowPlayingURIHandler::IsMine(const wchar_t *filename)
|
||||
{
|
||||
if (!_wcsnicmp(filename, L"winamp://Now Playing", 20 ) || !_wcsnicmp(filename, L"winamp://Now%20Playing", 22))
|
||||
return HANDLED;
|
||||
else
|
||||
return NOT_HANDLED;
|
||||
}
|
||||
|
||||
#define CBCLASS NowPlayingURIHandler
|
||||
START_DISPATCH;
|
||||
CB(PROCESSFILENAME, ProcessFilename);
|
||||
CB(ISMINE, IsMine);
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
19
Src/Plugins/Library/ml_nowplaying/handler.h
Normal file
19
Src/Plugins/Library/ml_nowplaying/handler.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "../Agave/URIHandler/svc_urihandler.h"
|
||||
|
||||
// {7A8BAF83-3995-4550-B15B-12D297A9220E}
|
||||
static const GUID ml_nowplaying_uri_handler =
|
||||
{ 0x7a8baf83, 0x3995, 0x4550, { 0xb1, 0x5b, 0x12, 0xd2, 0x97, 0xa9, 0x22, 0xe } };
|
||||
|
||||
class NowPlayingURIHandler : public svc_urihandler
|
||||
{
|
||||
public:
|
||||
static const char *getServiceName() { return "Now Playing URI Handler"; }
|
||||
static GUID getServiceGuid() { return ml_nowplaying_uri_handler; }
|
||||
int ProcessFilename(const wchar_t *filename);
|
||||
int IsMine(const wchar_t *filename); // just like ProcessFilename but don't actually process
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
68
Src/Plugins/Library/ml_nowplaying/local_menu.cpp
Normal file
68
Src/Plugins/Library/ml_nowplaying/local_menu.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
#include "main.h"
|
||||
#include "./local_menu.h"
|
||||
#include "./wasabi.h"
|
||||
#include "./resource.h"
|
||||
#include "./navigation.h"
|
||||
#include "../gen_ml/ml_ipc_0313.h"
|
||||
#include "../nu/menuHelpers.h"
|
||||
|
||||
#define SUBMENU_NAVIGATIONCONTEXT 0
|
||||
|
||||
static HMENU Menu_GetNavigationContext(HMENU baseMenu)
|
||||
{
|
||||
HMENU hMenu = GetSubMenu(baseMenu, SUBMENU_NAVIGATIONCONTEXT);
|
||||
if (NULL == hMenu) return NULL;
|
||||
|
||||
hMenu = MenuHelper_DuplcateMenu(hMenu);
|
||||
if (NULL == hMenu) return NULL;
|
||||
|
||||
HNAVITEM hActive = Navigation_GetActive(NULL);
|
||||
if (NULL != hActive)
|
||||
{
|
||||
EnableMenuItem(hMenu, ID_NAVIGATION_OPEN, MF_BYCOMMAND | MF_GRAYED | MF_DISABLED);
|
||||
}
|
||||
else
|
||||
{
|
||||
EnableMenuItem(hMenu, ID_NAVIGATION_OPEN, MF_BYCOMMAND | MF_ENABLED);
|
||||
SetMenuDefaultItem(hMenu, ID_NAVIGATION_OPEN, FALSE);
|
||||
}
|
||||
|
||||
return hMenu;
|
||||
}
|
||||
|
||||
HMENU Menu_GetMenu(UINT menuKind)
|
||||
{
|
||||
HMENU baseMenu = WASABI_API_LOADMENUW(IDR_CONTEXTMENU);
|
||||
if (NULL == baseMenu)
|
||||
return NULL;
|
||||
|
||||
switch(menuKind)
|
||||
{
|
||||
case MENU_NAVIGATIONCONTEXT:
|
||||
{
|
||||
HMENU menu = Menu_GetNavigationContext(baseMenu);
|
||||
if (!GetModuleHandle(L"ml_online.dll"))
|
||||
{
|
||||
if (DeleteMenu(menu, ID_PLUGIN_PREFERENCES, MF_BYCOMMAND))
|
||||
{
|
||||
DeleteMenu(menu, 2, MF_BYPOSITION);
|
||||
}
|
||||
}
|
||||
return menu;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL Menu_ReleaseMenu(HMENU hMenu, UINT menuKind)
|
||||
{
|
||||
if (NULL == hMenu) return FALSE;
|
||||
|
||||
switch(menuKind)
|
||||
{
|
||||
case MENU_NAVIGATIONCONTEXT:
|
||||
return DestroyMenu(hMenu);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
15
Src/Plugins/Library/ml_nowplaying/local_menu.h
Normal file
15
Src/Plugins/Library/ml_nowplaying/local_menu.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef NULLSOFT_NOWPLAYING_PLUGIN_MENU_HEADER
|
||||
#define NULLSOFT_NOWPLAYING_PLUGIN_MENU_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
#define MENU_NAVIGATIONCONTEXT 0
|
||||
|
||||
HMENU Menu_GetMenu(UINT menuKind);
|
||||
BOOL Menu_ReleaseMenu(HMENU hMenu, UINT menuKind);
|
||||
|
||||
#endif //NULLSOFT_NOWPLAYING_PLUGIN_MENU_HEADER
|
160
Src/Plugins/Library/ml_nowplaying/main.cpp
Normal file
160
Src/Plugins/Library/ml_nowplaying/main.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
#include "main.h"
|
||||
#include "./navigation.h"
|
||||
#include "./wasabi.h"
|
||||
#include "./resource.h"
|
||||
#include "./external.h"
|
||||
#include "./wasabiCallback.h"
|
||||
#include "../nu/MediaLibraryInterface.h"
|
||||
#include "../replicant/nu/AutoChar.h"
|
||||
#include "../winamp/wa_ipc.h"
|
||||
#include "handler.h"
|
||||
#include "../nu/Singleton.h"
|
||||
#include "../ml_online/config.h"
|
||||
#include <strsafe.h>
|
||||
|
||||
static NowPlayingURIHandler uri_handler;
|
||||
static SingletonServiceFactory<svc_urihandler, NowPlayingURIHandler> uri_handler_factory;
|
||||
|
||||
static DWORD externalCookie = 0;
|
||||
static SysCallback *wasabiCallback = NULL;
|
||||
C_Config *g_config = NULL;
|
||||
|
||||
static INT Plugin_Init(void);
|
||||
static void Plugin_Quit(void);
|
||||
static INT_PTR Plugin_MessageProc(INT msg, INT_PTR param1, INT_PTR param2, INT_PTR param3);
|
||||
|
||||
EXTERN_C winampMediaLibraryPlugin plugin =
|
||||
{
|
||||
MLHDR_VER,
|
||||
"nullsoft(ml_nowplaying.dll)",
|
||||
Plugin_Init,
|
||||
Plugin_Quit,
|
||||
Plugin_MessageProc,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
|
||||
HINSTANCE Plugin_GetInstance(void)
|
||||
{
|
||||
return plugin.hDllInstance;
|
||||
}
|
||||
|
||||
HWND Plugin_GetWinamp(void)
|
||||
{
|
||||
return plugin.hwndWinampParent;
|
||||
}
|
||||
|
||||
HWND Plugin_GetLibrary(void)
|
||||
{
|
||||
return plugin.hwndLibraryParent;
|
||||
}
|
||||
|
||||
void initConfigCache()
|
||||
{
|
||||
wchar_t iniFileName[2048] = {0};
|
||||
mediaLibrary.BuildPath(L"Plugins\\ml", iniFileName, 2048);
|
||||
CreateDirectory(iniFileName, NULL);
|
||||
mediaLibrary.BuildPath(L"Plugins\\ml\\ml_online.ini", iniFileName, 2048);
|
||||
AutoChar charFn(iniFileName);
|
||||
g_config = new C_Config(AutoChar(iniFileName));
|
||||
}
|
||||
|
||||
static INT Plugin_Init(void)
|
||||
{
|
||||
if (!WasabiApi_Initialize(Plugin_GetInstance()))
|
||||
return 1;
|
||||
|
||||
if (NULL == OMBROWSERMNGR)
|
||||
{
|
||||
WasabiApi_Release();
|
||||
return 2;
|
||||
}
|
||||
|
||||
mediaLibrary.library = plugin.hwndLibraryParent;
|
||||
mediaLibrary.winamp = plugin.hwndWinampParent;
|
||||
mediaLibrary.instance = plugin.hDllInstance;
|
||||
|
||||
initConfigCache();
|
||||
|
||||
if (NULL != WASABI_API_LNG)
|
||||
{
|
||||
static wchar_t szDescription[256];
|
||||
StringCchPrintf(szDescription, ARRAYSIZE(szDescription), WASABI_API_LNGSTRINGW(IDS_PLUGIN_NAME),
|
||||
PLUGIN_VERSION_MAJOR, PLUGIN_VERSION_MINOR);
|
||||
plugin.description = (char*)szDescription;
|
||||
}
|
||||
|
||||
ExternalDispatch *externalDispatch;
|
||||
if (SUCCEEDED(ExternalDispatch::CreateInstance(&externalDispatch)))
|
||||
{
|
||||
DispatchInfo dispatchInfo;
|
||||
dispatchInfo.id = 0;
|
||||
dispatchInfo.name =(LPWSTR)externalDispatch->GetName();
|
||||
dispatchInfo.dispatch = externalDispatch;
|
||||
|
||||
if (0 == SENDWAIPC(Plugin_GetWinamp(), IPC_ADD_DISPATCH_OBJECT, (WPARAM)&dispatchInfo))
|
||||
externalCookie = dispatchInfo.id;
|
||||
|
||||
externalDispatch->Release();
|
||||
}
|
||||
|
||||
if(NULL != WASABI_API_SYSCB && NULL == wasabiCallback &&
|
||||
SUCCEEDED(WasabiCallback::CreateInstance((WasabiCallback**)&wasabiCallback)))
|
||||
{
|
||||
WASABI_API_SYSCB->syscb_registerCallback(wasabiCallback, 0);
|
||||
for (;;)
|
||||
{
|
||||
SysCallback *callback = WASABI_API_SYSCB->syscb_enum(SysCallback::BROWSER, 0);
|
||||
if (NULL == callback || callback == wasabiCallback)
|
||||
{
|
||||
if (NULL != callback)
|
||||
callback->Release();
|
||||
break;
|
||||
}
|
||||
|
||||
WASABI_API_SYSCB->syscb_deregisterCallback(callback);
|
||||
WASABI_API_SYSCB->syscb_registerCallback(callback, 0);
|
||||
callback->Release();
|
||||
}
|
||||
}
|
||||
|
||||
uri_handler_factory.Register(plugin.service, &uri_handler);
|
||||
Navigation_Initialize();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void Plugin_Quit(void)
|
||||
{
|
||||
if (NULL != wasabiCallback)
|
||||
{
|
||||
if (NULL != WASABI_API_SYSCB)
|
||||
WASABI_API_SYSCB->syscb_deregisterCallback(wasabiCallback);
|
||||
wasabiCallback->Release();
|
||||
wasabiCallback = NULL;
|
||||
}
|
||||
|
||||
if (0 != externalCookie)
|
||||
{
|
||||
HWND hWinamp = Plugin_GetWinamp();
|
||||
SENDWAIPC(hWinamp, IPC_REMOVE_DISPATCH_OBJECT, (WPARAM)externalCookie);
|
||||
externalCookie = 0;
|
||||
}
|
||||
uri_handler_factory.Deregister(plugin.service);
|
||||
WasabiApi_Release();
|
||||
}
|
||||
|
||||
static INT_PTR Plugin_MessageProc(INT msg, INT_PTR param1, INT_PTR param2, INT_PTR param3)
|
||||
{
|
||||
INT_PTR result = 0;
|
||||
if (FALSE != Navigation_ProcessMessage(msg, param1, param2, param3, &result))
|
||||
return result;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
EXTERN_C __declspec(dllexport) winampMediaLibraryPlugin *winampGetMediaLibraryPlugin()
|
||||
{
|
||||
return &plugin;
|
||||
}
|
22
Src/Plugins/Library/ml_nowplaying/main.h
Normal file
22
Src/Plugins/Library/ml_nowplaying/main.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef NULLSOFT_NOWPLAYING_PLUGIN_MAIN_HEADER
|
||||
#define NULLSOFT_NOWPLAYING_PLUGIN_MAIN_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
#include "../gen_ml/ml.h"
|
||||
#include "./common.h"
|
||||
|
||||
#define PLUGIN_VERSION_MAJOR 4
|
||||
#define PLUGIN_VERSION_MINOR 1
|
||||
|
||||
HINSTANCE Plugin_GetInstance(void);
|
||||
HWND Plugin_GetWinamp(void);
|
||||
HWND Plugin_GetLibrary(void);
|
||||
|
||||
#include "../ml_online/config.h"
|
||||
extern C_Config *g_config;
|
||||
|
||||
#endif //NULLSOFT_NOWPLAYING_PLUGIN_MAIN_HEADER
|
99
Src/Plugins/Library/ml_nowplaying/ml_nowplaying.rc
Normal file
99
Src/Plugins/Library/ml_nowplaying/ml_nowplaying.rc
Normal file
@ -0,0 +1,99 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""version.rc2""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu
|
||||
//
|
||||
|
||||
IDR_CONTEXTMENU MENU
|
||||
BEGIN
|
||||
POPUP "Navigation"
|
||||
BEGIN
|
||||
MENUITEM "&Open", ID_NAVIGATION_OPEN
|
||||
MENUITEM "Open in &New Window", ID_NAVIGATION_OPENNEWWINDOW
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Preferences", 40006
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Help", ID_NAVIGATION_HELP
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_PLUGIN_NAME "Nullsoft Now Playing v%d.%02d"
|
||||
65535 "{7F31F590-6602-45c9-B3F8-F61AE05BD1D3}"
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_SERVICE_NAME "Now Playing"
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
#include "version.rc2"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
30
Src/Plugins/Library/ml_nowplaying/ml_nowplaying.sln
Normal file
30
Src/Plugins/Library/ml_nowplaying/ml_nowplaying.sln
Normal file
@ -0,0 +1,30 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29613.14
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ml_nowplaying", "ml_nowplaying.vcxproj", "{CB59733D-8D69-4DC4-AB67-C831DAE5A80F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{CB59733D-8D69-4DC4-AB67-C831DAE5A80F}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{CB59733D-8D69-4DC4-AB67-C831DAE5A80F}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{CB59733D-8D69-4DC4-AB67-C831DAE5A80F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CB59733D-8D69-4DC4-AB67-C831DAE5A80F}.Debug|x64.Build.0 = Debug|x64
|
||||
{CB59733D-8D69-4DC4-AB67-C831DAE5A80F}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{CB59733D-8D69-4DC4-AB67-C831DAE5A80F}.Release|Win32.Build.0 = Release|Win32
|
||||
{CB59733D-8D69-4DC4-AB67-C831DAE5A80F}.Release|x64.ActiveCfg = Release|x64
|
||||
{CB59733D-8D69-4DC4-AB67-C831DAE5A80F}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {0DF91B23-5CCB-4CD1-8A07-03B96BB9324E}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
280
Src/Plugins/Library/ml_nowplaying/ml_nowplaying.vcxproj
Normal file
280
Src/Plugins/Library/ml_nowplaying/ml_nowplaying.vcxproj
Normal file
@ -0,0 +1,280 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{CB59733D-8D69-4DC4-AB67-C831DAE5A80F}</ProjectGuid>
|
||||
<RootNamespace>ml_nowplaying</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
|
||||
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
|
||||
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
|
||||
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
|
||||
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg">
|
||||
<VcpkgEnableManifest>true</VcpkgEnableManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<VcpkgInstalledDir>..\..\..\external_dependencies\vcpkg</VcpkgInstalledDir>
|
||||
<VcpkgUseStatic>true</VcpkgUseStatic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<VcpkgInstalledDir>..\..\..\external_dependencies\vcpkg</VcpkgInstalledDir>
|
||||
<VcpkgUseStatic>true</VcpkgUseStatic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<VcpkgInstalledDir>..\..\..\external_dependencies\vcpkg</VcpkgInstalledDir>
|
||||
<VcpkgUseStatic>true</VcpkgUseStatic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<VcpkgInstalledDir>..\..\..\external_dependencies\vcpkg</VcpkgInstalledDir>
|
||||
<VcpkgUseStatic>true</VcpkgUseStatic>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..;..\..\..\;..\..\..\wasabi;..\..\..\agave;..\..\..\ombrowser;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;TEST_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>shlwapi.lib;comctl32.lib;rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName).dll</OutputFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D $(OutDir)*.dll ..\..\..\..\..\Winamp_$(PlatformShortName)_$(Configuration)\plugins\
|
||||
xcopy /Y /D $(OutDir)*.pdb ..\..\..\..\..\Winamp_$(PlatformShortName)_$(Configuration)\plugins\ </Command>
|
||||
<Message>Post build event: 'xcopy /Y /D $(OutDir)*.dll ..\..\..\..\..\Winamp_$(PlatformShortName)_$(Configuration)\plugins\'</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..;..\..\..\;..\..\..\wasabi;..\..\..\agave;..\..\..\ombrowser;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;_USRDLL;TEST_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>shlwapi.lib;comctl32.lib;rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName).dll</OutputFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D $(OutDir)*.dll ..\..\..\..\..\Winamp_$(PlatformShortName)_$(Configuration)\plugins\
|
||||
xcopy /Y /D $(OutDir)*.pdb ..\..\..\..\..\Winamp_$(PlatformShortName)_$(Configuration)\plugins\ </Command>
|
||||
<Message>Post build event: 'xcopy /Y /D $(OutDir)*.dll ..\..\..\..\..\Winamp_$(PlatformShortName)_$(Configuration)\plugins\'</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<AdditionalIncludeDirectories>..;..\..\..\;..\..\..\wasabi;..\..\..\agave;..\..\..\ombrowser;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x601;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>shlwapi.lib;comctl32.lib;rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName).dll</OutputFile>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D $(OutDir)*.dll ..\..\..\..\..\Winamp_$(PlatformShortName)_$(Configuration)\plugins\ </Command>
|
||||
<Message>Post build event: 'xcopy /Y /D $(OutDir)*.dll ..\..\..\..\..\Winamp_$(PlatformShortName)_$(Configuration)\plugins\'</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<AdditionalIncludeDirectories>..;..\..\..\;..\..\..\wasabi;..\..\..\agave;..\..\..\ombrowser;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_WIN32_WINNT=0x601;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>shlwapi.lib;comctl32.lib;rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName).dll</OutputFile>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D $(OutDir)*.dll ..\..\..\..\..\Winamp_$(PlatformShortName)_$(Configuration)\plugins\ </Command>
|
||||
<Message>Post build event: 'xcopy /Y /D $(OutDir)*.dll ..\..\..\..\..\Winamp_$(PlatformShortName)_$(Configuration)\plugins\'</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\General\gen_ml\menu.cpp" />
|
||||
<ClCompile Include="..\ml_online\config.cpp" />
|
||||
<ClCompile Include="..\..\..\nu\MediaLibraryInterface.cpp" />
|
||||
<ClCompile Include="..\..\..\nu\menuHelpers.cpp" />
|
||||
<ClCompile Include="..\..\..\nu\trace.cpp" />
|
||||
<ClCompile Include="common.cpp" />
|
||||
<ClCompile Include="external.cpp" />
|
||||
<ClCompile Include="handler.cpp" />
|
||||
<ClCompile Include="local_menu.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="navigation.cpp" />
|
||||
<ClCompile Include="service.cpp" />
|
||||
<ClCompile Include="wasabi.cpp" />
|
||||
<ClCompile Include="wasabiCallback.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\General\gen_ml\menu.h" />
|
||||
<ClInclude Include="..\ml_online\config.h" />
|
||||
<ClInclude Include="..\..\..\nu\MediaLibraryInterface.h" />
|
||||
<ClInclude Include="common.h" />
|
||||
<ClInclude Include="external.h" />
|
||||
<ClInclude Include="handler.h" />
|
||||
<ClInclude Include="local_menu.h" />
|
||||
<ClInclude Include="main.h" />
|
||||
<ClInclude Include="navigation.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="service.h" />
|
||||
<ClInclude Include="wasabi.h" />
|
||||
<ClInclude Include="wasabiCallback.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="ml_nowplaying.rc" />
|
||||
<ResourceCompile Include="png.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\omBrowser\omBrowser.vcxproj">
|
||||
<Project>{fc74db95-5008-4d22-9147-1c052f43cdd3}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\Wasabi\Wasabi.vcxproj">
|
||||
<Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
107
Src/Plugins/Library/ml_nowplaying/ml_nowplaying.vcxproj.filters
Normal file
107
Src/Plugins/Library/ml_nowplaying/ml_nowplaying.vcxproj.filters
Normal file
@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="common.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ml_online\config.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="external.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="handler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="local_menu.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\nu\MediaLibraryInterface.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\gen_ml\menu.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\nu\menuHelpers.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="navigation.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="service.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\nu\trace.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="wasabi.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="wasabiCallback.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="common.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ml_online\config.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="external.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="handler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="local_menu.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="main.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\nu\MediaLibraryInterface.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\gen_ml\menu.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="navigation.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="service.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="wasabi.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="wasabiCallback.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="png.rc">
|
||||
<Filter>Header Files</Filter>
|
||||
</ResourceCompile>
|
||||
<ResourceCompile Include="ml_nowplaying.rc">
|
||||
<Filter>Ressource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{a1f12bb1-c2c0-49d3-b74a-5f8bbac3dee6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Ressource Files">
|
||||
<UniqueIdentifier>{8fef1ee3-d193-47aa-872e-843f5178bcc5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{f17e7245-8101-4787-b60f-874085ddb8a7}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
684
Src/Plugins/Library/ml_nowplaying/navigation.cpp
Normal file
684
Src/Plugins/Library/ml_nowplaying/navigation.cpp
Normal file
@ -0,0 +1,684 @@
|
||||
#include "main.h"
|
||||
#include "./navigation.h"
|
||||
#include "./resource.h"
|
||||
#include "./wasabi.h"
|
||||
#include "./service.h"
|
||||
#include "../omBrowser/browserView.h"
|
||||
#include "../winamp/wa_ipc.h"
|
||||
#include "../replicant/nu/Autowide.h"
|
||||
#include "../gen_ml/ml_ipc_0313.h"
|
||||
#include "./local_menu.h"
|
||||
#include "../gen_ml/menu.h"
|
||||
#include <strsafe.h>
|
||||
|
||||
#define NAVITEM_PREFIX L"nowplaying_svc_"
|
||||
|
||||
#define E_NAVITEM_UNKNOWN E_NOINTERFACE
|
||||
|
||||
typedef struct __NAVENUMRESULT
|
||||
{
|
||||
HNAVITEM hItem;
|
||||
OmService *service;
|
||||
UINT serviceId;
|
||||
LPCWSTR pszPrefix;
|
||||
INT cchPrefix;
|
||||
HWND hLibrary;
|
||||
NAVITEM itemInfo;
|
||||
WCHAR szBuffer[256];
|
||||
} NAVENUMRESULT;
|
||||
|
||||
typedef struct __FORCEURLDATA
|
||||
{
|
||||
UINT serviceId;
|
||||
LPWSTR url;
|
||||
} FORCEURLDATA;
|
||||
|
||||
#define FORCEURLPROP L"MLNOWPLAYING_FORCEURL"
|
||||
|
||||
static void Navigation_RemoveForceUrl()
|
||||
{
|
||||
HWND hLibrary = Plugin_GetLibrary();
|
||||
if (NULL == hLibrary) return;
|
||||
|
||||
FORCEURLDATA *data = (FORCEURLDATA*)GetProp(hLibrary, FORCEURLPROP);
|
||||
RemoveProp(hLibrary, FORCEURLPROP);
|
||||
if (NULL != data)
|
||||
{
|
||||
Plugin_FreeString(data->url);
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT Navigation_SetForceUrl(UINT serviceId, LPCWSTR pszUrl)
|
||||
{
|
||||
if (NULL == pszUrl) return E_INVALIDARG;
|
||||
|
||||
HWND hLibrary = Plugin_GetLibrary();
|
||||
if (NULL == hLibrary) return E_FAIL;
|
||||
|
||||
FORCEURLDATA *data = (FORCEURLDATA*)GetProp(hLibrary, FORCEURLPROP);
|
||||
|
||||
if (NULL != data)
|
||||
{
|
||||
Plugin_FreeString(data->url);
|
||||
if (data->serviceId != serviceId)
|
||||
{
|
||||
free(data);
|
||||
data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL == data)
|
||||
{
|
||||
data = (FORCEURLDATA*)calloc(1, sizeof(FORCEURLDATA));
|
||||
if (NULL == data) return E_OUTOFMEMORY;
|
||||
data->serviceId = serviceId;
|
||||
}
|
||||
|
||||
data->url = Plugin_CopyString(pszUrl);
|
||||
if (NULL == data->url || FALSE == SetProp(hLibrary, FORCEURLPROP, data))
|
||||
{
|
||||
Navigation_RemoveForceUrl();
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT Navigation_GetForceUrl(UINT serviceId, const wchar_t **ppszUrl)
|
||||
{
|
||||
if (NULL == ppszUrl) return E_POINTER;
|
||||
*ppszUrl = NULL;
|
||||
|
||||
HWND hLibrary = Plugin_GetLibrary();
|
||||
if (NULL == hLibrary) return E_FAIL;
|
||||
|
||||
FORCEURLDATA *data = (FORCEURLDATA*)GetProp(hLibrary, FORCEURLPROP);
|
||||
|
||||
if (NULL == data || data->serviceId != serviceId)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
*ppszUrl = data->url;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static INT Navigation_GetIconIndex(LPCWSTR pszImage)
|
||||
{
|
||||
HWND hLibrary = Plugin_GetLibrary();
|
||||
if (NULL == hLibrary) return -1;
|
||||
|
||||
HMLIMGLST hmlilNavigation = MLNavCtrl_GetImageList(hLibrary);
|
||||
if (NULL == hmlilNavigation) return -1;
|
||||
|
||||
MLIMAGESOURCE mlis;
|
||||
ZeroMemory(&mlis, sizeof(mlis));
|
||||
mlis.cbSize = sizeof(mlis);
|
||||
mlis.hInst = NULL;
|
||||
mlis.bpp = 24;
|
||||
mlis.lpszName = pszImage;
|
||||
mlis.type = SRC_TYPE_PNG;
|
||||
mlis.flags = ISF_FORCE_BPP | ISF_PREMULTIPLY | ISF_LOADFROMFILE;
|
||||
|
||||
MLIMAGELISTITEM item;
|
||||
ZeroMemory(&item, sizeof(item));
|
||||
item.cbSize = sizeof(item);
|
||||
item.hmlil = hmlilNavigation;
|
||||
item.filterUID = MLIF_FILTER3_UID;
|
||||
item.pmlImgSource = &mlis;
|
||||
|
||||
return MLImageList_Add(hLibrary, &item);
|
||||
}
|
||||
|
||||
static HNAVITEM Navigation_CreateItem(HWND hLibrary, HNAVITEM hParent, OmService *service)
|
||||
{
|
||||
if (NULL == hLibrary || NULL == service)
|
||||
return NULL;
|
||||
|
||||
WCHAR szName[256] = {0}, szInvariant[64] = {0};
|
||||
if (FAILED(service->GetName(szName, ARRAYSIZE(szName))))
|
||||
return NULL;
|
||||
|
||||
if (FAILED(StringCchPrintf(szInvariant, ARRAYSIZE(szInvariant), NAVITEM_PREFIX L"%u", service->GetId())))
|
||||
return NULL;
|
||||
|
||||
NAVINSERTSTRUCT nis = {0};
|
||||
nis.hInsertAfter = NULL;
|
||||
nis.hParent = hParent;
|
||||
|
||||
WCHAR szIcon[512] = {0};
|
||||
INT iIcon = (SUCCEEDED(service->GetIcon(szIcon, ARRAYSIZE(szIcon)))) ?
|
||||
Navigation_GetIconIndex(szIcon) : -1;
|
||||
|
||||
nis.item.cbSize = sizeof(NAVITEM);
|
||||
nis.item.mask = NIMF_TEXT | NIMF_STYLE | NIMF_TEXTINVARIANT | NIMF_PARAM;
|
||||
if (-1 != iIcon)
|
||||
nis.item.mask |= (NIMF_IMAGE | NIMF_IMAGESEL);
|
||||
|
||||
nis.item.id = 0;
|
||||
nis.item.pszText = szName;
|
||||
nis.item.pszInvariant = szInvariant;
|
||||
nis.item.style = NIS_ALLOWCHILDMOVE;
|
||||
nis.item.styleMask = nis.item.style;
|
||||
nis.item.lParam = (LPARAM)service;
|
||||
nis.item.iImage = iIcon;
|
||||
nis.item.iSelectedImage = iIcon;
|
||||
|
||||
HNAVITEM hItem = MLNavCtrl_InsertItem(hLibrary, &nis);
|
||||
if (NULL != hItem)
|
||||
service->AddRef();
|
||||
|
||||
return hItem;
|
||||
}
|
||||
|
||||
static HNAVITEM Navigation_GetMessageItem(INT msg, INT_PTR param1)
|
||||
{
|
||||
HWND hLibrary = Plugin_GetLibrary();
|
||||
HNAVITEM hItem = (msg < ML_MSG_NAVIGATION_FIRST) ? MLNavCtrl_FindItemById(hLibrary, param1) : (HNAVITEM)param1;
|
||||
return hItem;
|
||||
}
|
||||
|
||||
static HRESULT Navigation_GetService(HWND hLibrary, HNAVITEM hItem, OmService **service)
|
||||
{
|
||||
WCHAR szBuffer[64] = {0};
|
||||
|
||||
if (NULL == service) return E_POINTER;
|
||||
*service = NULL;
|
||||
|
||||
if (NULL == hLibrary || NULL == hItem) return E_INVALIDARG;
|
||||
|
||||
NAVITEM itemInfo = {0};
|
||||
itemInfo.cbSize = sizeof(NAVITEM);
|
||||
itemInfo.hItem = hItem;
|
||||
itemInfo.pszInvariant = szBuffer;
|
||||
itemInfo.cchInvariantMax = ARRAYSIZE(szBuffer);
|
||||
itemInfo.mask = NIMF_PARAM | NIMF_TEXTINVARIANT;
|
||||
|
||||
if (FALSE == MLNavItem_GetInfo(hLibrary, &itemInfo))
|
||||
return E_FAIL;
|
||||
|
||||
INT cchInvariant = lstrlen(szBuffer);
|
||||
INT cchPrefix = ARRAYSIZE(NAVITEM_PREFIX) - 1;
|
||||
if (cchInvariant <= cchPrefix ||
|
||||
CSTR_EQUAL != CompareString(CSTR_INVARIANT, 0, NAVITEM_PREFIX, cchPrefix, szBuffer, cchPrefix))
|
||||
{
|
||||
return E_NAVITEM_UNKNOWN;
|
||||
}
|
||||
|
||||
*service = (OmService*)itemInfo.lParam;
|
||||
(*service)->AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
static BOOL CALLBACK Navigation_ItemEnumerator(HNAVITEM hItem, LPARAM param)
|
||||
{
|
||||
if (NULL == hItem) return TRUE;
|
||||
NAVENUMRESULT *result = (NAVENUMRESULT*)param;
|
||||
if (NULL == result) return FALSE;
|
||||
|
||||
result->itemInfo .hItem = hItem;
|
||||
if (FALSE != MLNavItem_GetInfo(result->hLibrary, &result->itemInfo) &&
|
||||
CSTR_EQUAL == CompareString(CSTR_INVARIANT, NORM_IGNORECASE, result->itemInfo.pszInvariant, result->cchPrefix,
|
||||
result->pszPrefix, result->cchPrefix))
|
||||
{
|
||||
OmService *service = (OmService*)result->itemInfo.lParam;
|
||||
if (NULL != service && service->GetId() == result->serviceId)
|
||||
{
|
||||
result->hItem = hItem;
|
||||
result->service = service;
|
||||
service->AddRef();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static HRESULT Navigation_CreateView(HNAVITEM hItem, HWND hParent, HWND *hView)
|
||||
{
|
||||
if (NULL == hView) return E_POINTER;
|
||||
*hView = NULL;
|
||||
|
||||
HWND hLibrary = Plugin_GetLibrary();
|
||||
if (NULL == hLibrary) return E_UNEXPECTED;
|
||||
|
||||
if (NULL == hItem || NULL == hParent) return E_INVALIDARG;
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
OmService *service = NULL;
|
||||
hr = Navigation_GetService(hLibrary, hItem, &service);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (NULL == OMBROWSERMNGR)
|
||||
hr = E_UNEXPECTED;
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = OMBROWSERMNGR->Initialize(NULL, Plugin_GetWinamp());
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
LPCWSTR forceUrl;
|
||||
if (FAILED(Navigation_GetForceUrl(service->GetId(), &forceUrl)))
|
||||
forceUrl = NULL;
|
||||
|
||||
hr = OMBROWSERMNGR->CreateView(service, hParent, forceUrl, 0, hView);
|
||||
Navigation_RemoveForceUrl();
|
||||
}
|
||||
}
|
||||
|
||||
wchar_t nowplayingurl[1024] = {0};
|
||||
// May 2022 - this service url is dead and would need either fixing up or replacing
|
||||
lstrcpynW(nowplayingurl, AutoWide(g_config->ReadString("nowplayingurl", "http://client.winamp.com/nowplaying")), ARRAYSIZE(nowplayingurl));
|
||||
service->SetUrl(nowplayingurl[0] ? nowplayingurl : SERVICE_HOMEURL);
|
||||
service->Release();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static BOOL Navigation_GetViewRect(RECT *rect)
|
||||
{
|
||||
if (NULL == rect) return FALSE;
|
||||
|
||||
HWND hWinamp = Plugin_GetWinamp();
|
||||
HWND hLibrary = Plugin_GetLibrary();
|
||||
if (NULL == hWinamp || NULL == hLibrary)
|
||||
return FALSE;
|
||||
|
||||
HWND hFrame = (HWND)SENDMLIPC(hLibrary, ML_IPC_GETCURRENTVIEW, 0);
|
||||
if (NULL == hFrame)
|
||||
hFrame = hLibrary;
|
||||
|
||||
return GetWindowRect(hFrame, rect);
|
||||
}
|
||||
|
||||
static HRESULT Navigation_CreatePopup(HNAVITEM hItem, HWND *hWindow)
|
||||
{
|
||||
if (NULL == hWindow) return E_POINTER;
|
||||
*hWindow = NULL;
|
||||
|
||||
HWND hLibrary = Plugin_GetLibrary();
|
||||
if (NULL == hLibrary) return E_UNEXPECTED;
|
||||
|
||||
if (NULL == hItem) return E_INVALIDARG;
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
OmService *service;
|
||||
hr = Navigation_GetService(hLibrary, hItem, &service);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
HWND hWinamp = Plugin_GetWinamp();
|
||||
|
||||
if (NULL == OMBROWSERMNGR)
|
||||
hr = E_UNEXPECTED;
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = OMBROWSERMNGR->Initialize(NULL, hWinamp);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
RECT rect;
|
||||
if (FALSE == Navigation_GetViewRect(&rect))
|
||||
hr = E_FAIL;
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
rect.left += 16;
|
||||
rect.top += 16;
|
||||
|
||||
hr = OMBROWSERMNGR->CreatePopup(service, rect.left, rect.top,
|
||||
rect.right - rect.left, rect.bottom - rect.top, hWinamp, NULL, 0, hWindow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
service->Release();
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
static void Navigation_OnDestroy()
|
||||
{
|
||||
Navigation_RemoveForceUrl();
|
||||
|
||||
if (NULL != OMBROWSERMNGR)
|
||||
{
|
||||
OMBROWSERMNGR->Finish();
|
||||
}
|
||||
}
|
||||
|
||||
static void Navigation_OpenPreferences()
|
||||
{
|
||||
winampMediaLibraryPlugin *(*gp)();
|
||||
gp = (winampMediaLibraryPlugin * (__cdecl *)(void))GetProcAddress(GetModuleHandle(L"ml_online.dll"), "winampGetMediaLibraryPlugin");
|
||||
if (gp)
|
||||
{
|
||||
winampMediaLibraryPlugin *mlplugin = gp();
|
||||
if (mlplugin && (mlplugin->version >= MLHDR_VER_OLD && mlplugin->version <= MLHDR_VER))
|
||||
{
|
||||
mlplugin->MessageProc(ML_MSG_CONFIG, 0, 0, 0);
|
||||
}
|
||||
else
|
||||
SendMessage(Plugin_GetWinamp(), WM_WA_IPC, (WPARAM)-1, IPC_OPENPREFSTOPAGE);
|
||||
}
|
||||
else
|
||||
SendMessage(Plugin_GetWinamp(), WM_WA_IPC, (WPARAM)-1, IPC_OPENPREFSTOPAGE);
|
||||
}
|
||||
|
||||
static HRESULT Navigation_ShowContextMenu(HNAVITEM hItem, HWND hHost, POINTS pts)
|
||||
{
|
||||
if (NULL == hItem || NULL == hHost)
|
||||
return E_INVALIDARG;
|
||||
|
||||
HWND hLibrary = Plugin_GetLibrary();
|
||||
if (NULL == hLibrary) return E_UNEXPECTED;
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
OmService *service;
|
||||
hr = Navigation_GetService(hLibrary, hItem, &service);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
POINT pt;
|
||||
POINTSTOPOINT(pt, pts);
|
||||
if (-1 == pt.x || -1 == pt.y)
|
||||
{
|
||||
NAVITEMGETRECT itemRect;
|
||||
itemRect.fItem = FALSE;
|
||||
itemRect.hItem = hItem;
|
||||
if (MLNavItem_GetRect(hLibrary, &itemRect))
|
||||
{
|
||||
MapWindowPoints(hHost, HWND_DESKTOP, (POINT*)&itemRect.rc, 2);
|
||||
pt.x = itemRect.rc.left + 2;
|
||||
pt.y = itemRect.rc.top + 2;
|
||||
}
|
||||
}
|
||||
|
||||
HMENU hMenu = Menu_GetMenu(MENU_NAVIGATIONCONTEXT);
|
||||
if (NULL != hMenu)
|
||||
{
|
||||
INT commandId = Menu_TrackPopup(hLibrary, hMenu,
|
||||
TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD,
|
||||
pt.x, pt.y, hHost, NULL);
|
||||
|
||||
Menu_ReleaseMenu(hMenu, MENU_NAVIGATIONCONTEXT);
|
||||
|
||||
switch(commandId)
|
||||
{
|
||||
case ID_NAVIGATION_OPEN:
|
||||
MLNavItem_Select(hLibrary, hItem);
|
||||
break;
|
||||
|
||||
case ID_NAVIGATION_OPENNEWWINDOW:
|
||||
{
|
||||
HWND hWindow;
|
||||
if (SUCCEEDED(Navigation_CreatePopup(hItem, &hWindow)))
|
||||
{
|
||||
ShowWindow(hWindow, SW_SHOWNORMAL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ID_NAVIGATION_HELP:
|
||||
SENDWAIPC(Plugin_GetWinamp(), IPC_OPEN_URL, L"https://help.winamp.com/hc/articles/8105304048660-The-Winamp-Media-Library");
|
||||
break;
|
||||
|
||||
case ID_PLUGIN_PREFERENCES:
|
||||
Navigation_OpenPreferences();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
service->Release();
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
BOOL Navigation_Initialize(void)
|
||||
{
|
||||
OmService *service;
|
||||
HWND hLibrary = Plugin_GetLibrary();
|
||||
|
||||
MLNavCtrl_BeginUpdate(hLibrary, NUF_LOCK_TOP);
|
||||
|
||||
if (SUCCEEDED(OmService::CreateInstance(&service)))
|
||||
{
|
||||
HNAVITEM hParent = NULL;
|
||||
Navigation_CreateItem(hLibrary, hParent, service);
|
||||
service->Release();
|
||||
}
|
||||
|
||||
MLNavCtrl_EndUpdate(hLibrary);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void Navigation_OnDeleteItem(HNAVITEM hItem)
|
||||
{
|
||||
if (NULL == hItem) return;
|
||||
|
||||
HWND hLibrary = Plugin_GetLibrary();
|
||||
if (NULL == hLibrary) return;
|
||||
|
||||
OmService *service;
|
||||
if (SUCCEEDED(Navigation_GetService(hLibrary, hItem, &service)))
|
||||
{
|
||||
|
||||
NAVITEM itemInfo;
|
||||
itemInfo.cbSize = sizeof(NAVITEM);
|
||||
itemInfo.hItem = hItem;
|
||||
itemInfo.mask = NIMF_PARAM;
|
||||
itemInfo.lParam = 0L;
|
||||
MLNavItem_SetInfo(hLibrary, &itemInfo);
|
||||
|
||||
service->Release(); // create
|
||||
service->Release(); // Navigation_GetService
|
||||
}
|
||||
}
|
||||
|
||||
BOOL Navigation_ProcessMessage(INT msg, INT_PTR param1, INT_PTR param2, INT_PTR param3, INT_PTR *result)
|
||||
{
|
||||
if (msg == ML_MSG_NO_CONFIG)
|
||||
{
|
||||
if (!GetModuleHandle(L"ml_online.dll"))
|
||||
{
|
||||
*result = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if (msg == ML_MSG_CONFIG)
|
||||
{
|
||||
Navigation_OpenPreferences();
|
||||
*result = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (msg < ML_MSG_TREE_BEGIN || msg > ML_MSG_TREE_END)
|
||||
return FALSE;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case ML_MSG_TREE_ONCREATEVIEW:
|
||||
{
|
||||
HWND hView;
|
||||
HNAVITEM hItem = Navigation_GetMessageItem(msg, param1);
|
||||
HRESULT hr = Navigation_CreateView(hItem, (HWND)param2, &hView);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
*result = (INT_PTR)hView;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ML_MSG_NAVIGATION_ONDESTROY:
|
||||
Navigation_OnDestroy();
|
||||
break;
|
||||
|
||||
case ML_MSG_NAVIGATION_CONTEXTMENU:
|
||||
{
|
||||
HNAVITEM hItem = Navigation_GetMessageItem(msg, param1);
|
||||
HRESULT hr = Navigation_ShowContextMenu(hItem, (HWND)param2, MAKEPOINTS(param3));
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
*result = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ML_MSG_NAVIGATION_ONDELETE:
|
||||
{
|
||||
HNAVITEM hItem = Navigation_GetMessageItem(msg, param1);
|
||||
Navigation_OnDeleteItem(hItem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HNAVITEM Navigation_FindService(UINT serviceId, OmService **serviceOut)
|
||||
{
|
||||
NAVENUMRESULT result;
|
||||
result.hItem = NULL;
|
||||
result.service = NULL;
|
||||
|
||||
result.serviceId = serviceId;
|
||||
result.pszPrefix = NAVITEM_PREFIX;
|
||||
result.cchPrefix = lstrlen(result.pszPrefix);
|
||||
|
||||
result.hLibrary = Plugin_GetLibrary();
|
||||
result.itemInfo.cbSize = sizeof(result.itemInfo);
|
||||
result.itemInfo.mask = NIMF_TEXTINVARIANT | NIMF_PARAM;
|
||||
result.itemInfo.cchInvariantMax = ARRAYSIZE(result.szBuffer);
|
||||
result.itemInfo.pszInvariant = result.szBuffer;
|
||||
|
||||
NAVCTRLENUMPARAMS param;
|
||||
param.enumProc = Navigation_ItemEnumerator;
|
||||
param.hItemStart = NULL;
|
||||
param.lParam = (LPARAM)&result;
|
||||
|
||||
if (NULL != result.hLibrary)
|
||||
MLNavCtrl_EnumItems(result.hLibrary, ¶m);
|
||||
|
||||
if (NULL != serviceOut)
|
||||
*serviceOut = result.service;
|
||||
else if (NULL != result.service)
|
||||
result.service->Release();
|
||||
|
||||
return result.hItem;
|
||||
}
|
||||
|
||||
HRESULT Navigation_ShowService(UINT serviceId, LPCWSTR pszUrl, UINT navFlags)
|
||||
{
|
||||
HWND hLibrary = Plugin_GetLibrary();
|
||||
if (NULL == hLibrary)
|
||||
return E_FAIL;
|
||||
|
||||
OmService *service;
|
||||
HNAVITEM hItem = Navigation_FindService(serviceId, &service);
|
||||
if (NULL == hItem)
|
||||
return E_FAIL;
|
||||
|
||||
OmService *activeService;
|
||||
HWND hView = Navigation_GetActiveView(&activeService);
|
||||
if (NULL == hView || activeService->GetId() != service->GetId())
|
||||
{
|
||||
hView = NULL;
|
||||
activeService = NULL;
|
||||
}
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (NULL != hView)
|
||||
{
|
||||
if (NULL == pszUrl && 0 != (NAVFLAG_FORCEACTIVE & navFlags))
|
||||
pszUrl = NAVIGATE_HOME;
|
||||
|
||||
if (NULL != pszUrl && FALSE == BrowserView_Navigate(hView, pszUrl, TRUE))
|
||||
hr = E_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NULL != pszUrl)
|
||||
hr = Navigation_SetForceUrl(serviceId, pszUrl);
|
||||
else
|
||||
Navigation_RemoveForceUrl();
|
||||
|
||||
if (SUCCEEDED(hr) && FALSE == MLNavItem_Select(hLibrary, hItem))
|
||||
{
|
||||
Navigation_RemoveForceUrl();
|
||||
hr = E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (0 != (NAVFLAG_ENSUREITEMVISIBLE & navFlags))
|
||||
MLNavItem_EnsureVisible(hLibrary, hItem);
|
||||
|
||||
if (0 != (NAVFLAG_ENSUREMLVISIBLE & navFlags))
|
||||
SENDMLIPC(hLibrary, ML_IPC_ENSURE_VISIBLE, 0L);
|
||||
}
|
||||
|
||||
service->Release();
|
||||
if (NULL != activeService)
|
||||
activeService->Release();
|
||||
|
||||
return hr;
|
||||
|
||||
}
|
||||
HNAVITEM Navigation_GetActive(OmService **serviceOut)
|
||||
{
|
||||
HWND hLibrary = Plugin_GetLibrary();
|
||||
|
||||
OmService *service;
|
||||
HNAVITEM hActive = (NULL != hLibrary) ? MLNavCtrl_GetSelection(hLibrary) : NULL;
|
||||
if (NULL == hActive || FAILED(Navigation_GetService(hLibrary, hActive, &service)))
|
||||
{
|
||||
hActive = NULL;
|
||||
service = NULL;
|
||||
}
|
||||
|
||||
if (NULL != serviceOut)
|
||||
*serviceOut = service;
|
||||
|
||||
return hActive;
|
||||
}
|
||||
|
||||
HWND Navigation_GetActiveView(OmService **serviceOut)
|
||||
{
|
||||
HWND hLibrary = Plugin_GetLibrary();
|
||||
if (NULL == hLibrary)
|
||||
{
|
||||
if (NULL != serviceOut) *serviceOut = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
HWND hView =((HWND)SENDMLIPC(hLibrary, ML_IPC_GETCURRENTVIEW, 0));
|
||||
if (NULL != hView)
|
||||
{
|
||||
WCHAR szBuffer[128] = {0};
|
||||
if (!GetClassName(hView, szBuffer, ARRAYSIZE(szBuffer)) || CSTR_EQUAL != CompareStringW(CSTR_INVARIANT, NORM_IGNORECASE, szBuffer, -1, L"Nullsoft_omBrowserView", -1))
|
||||
hView = NULL;
|
||||
}
|
||||
|
||||
OmService *service;
|
||||
HNAVITEM hActive = (NULL != hLibrary) ? MLNavCtrl_GetSelection(hLibrary) : NULL;
|
||||
if (NULL == hView || FALSE == BrowserView_GetService(hView, &service))
|
||||
{
|
||||
hView = NULL;
|
||||
service = NULL;
|
||||
}
|
||||
|
||||
if (NULL != serviceOut)
|
||||
*serviceOut = service;
|
||||
else if (NULL != service)
|
||||
service->Release();
|
||||
|
||||
return hView;
|
||||
}
|
27
Src/Plugins/Library/ml_nowplaying/navigation.h
Normal file
27
Src/Plugins/Library/ml_nowplaying/navigation.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef NULLSOFT_NOWPLAYING_PLUGIN_NAVIGATION_HEADER
|
||||
#define NULLSOFT_NOWPLAYING_PLUGIN_NAVIGATION_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
typedef LPVOID HNAVITEM;
|
||||
class OmService;
|
||||
|
||||
|
||||
BOOL Navigation_Initialize(void);
|
||||
BOOL Navigation_ProcessMessage(INT msg, INT_PTR param1, INT_PTR param2, INT_PTR param3, INT_PTR *result);
|
||||
|
||||
#define NAVFLAG_NORMAL 0x0000
|
||||
#define NAVFLAG_ENSUREITEMVISIBLE 0x0001
|
||||
#define NAVFLAG_ENSUREMLVISIBLE 0x0002
|
||||
#define NAVFLAG_FORCEACTIVE 0x0004
|
||||
|
||||
HRESULT Navigation_ShowService(UINT serviceId, LPCWSTR pszUrl, UINT navFlags);
|
||||
HNAVITEM Navigation_FindService(UINT serviceId, OmService **serviceOut);
|
||||
HNAVITEM Navigation_GetActive(OmService **serviceOut);
|
||||
HWND Navigation_GetActiveView(OmService **serviceOut);
|
||||
|
||||
#endif //NULLSOFT_NOWPLAYING_PLUGIN_NAVIGATION_HEADER
|
7
Src/Plugins/Library/ml_nowplaying/png.rc
Normal file
7
Src/Plugins/Library/ml_nowplaying/png.rc
Normal file
@ -0,0 +1,7 @@
|
||||
#include "resource.h"
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Data
|
||||
//
|
||||
IDR_SERVICE_ICON RCDATA
|
||||
".\\resources\\serviceIcon.png"
|
23
Src/Plugins/Library/ml_nowplaying/resource.h
Normal file
23
Src/Plugins/Library/ml_nowplaying/resource.h
Normal file
@ -0,0 +1,23 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by ml_nowplaying.rc
|
||||
//
|
||||
#define IDS_SERVICE_NAME 1
|
||||
#define IDR_CONTEXTMENU 101
|
||||
#define IDR_SERVICE_ICON 20000
|
||||
#define ID_NAVIGATION_OPENNEWWINDOW 40000
|
||||
#define ID_NAVIGATION_OPEN 40001
|
||||
#define ID_NAVIGATION_HELP 40005
|
||||
#define ID_PLUGIN_PREFERENCES 40006
|
||||
#define IDS_PLUGIN_NAME 65534
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 105
|
||||
#define _APS_NEXT_COMMAND_VALUE 40007
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
BIN
Src/Plugins/Library/ml_nowplaying/resources/serviceIcon.png
Normal file
BIN
Src/Plugins/Library/ml_nowplaying/resources/serviceIcon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 290 B |
171
Src/Plugins/Library/ml_nowplaying/service.cpp
Normal file
171
Src/Plugins/Library/ml_nowplaying/service.cpp
Normal file
@ -0,0 +1,171 @@
|
||||
#include "main.h"
|
||||
#include "./service.h"
|
||||
#include "./wasabi.h"
|
||||
#include "./resource.h"
|
||||
#include "../replicant/nu/Autowide.h"
|
||||
#include "../winamp/wa_ipc.h"
|
||||
#include <strsafe.h>
|
||||
|
||||
#define IS_INVALIDISPATCH(__disp) (((IDispatch *)1) == (__disp) || NULL == (__disp))
|
||||
|
||||
OmService::OmService(UINT nId)
|
||||
: ref(1), id(nId), name(NULL), url(NULL), icon(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
OmService::~OmService()
|
||||
{
|
||||
Plugin_FreeResString(name);
|
||||
Plugin_FreeString(url);
|
||||
Plugin_FreeResString(icon);
|
||||
}
|
||||
|
||||
HRESULT OmService::CreateInstance(OmService **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
*instance = NULL;
|
||||
|
||||
OmService *service = new OmService(SERVICE_ID);
|
||||
if (NULL == service) return E_OUTOFMEMORY;
|
||||
|
||||
wchar_t nowplayingurl[1024] = {0};
|
||||
lstrcpynW(nowplayingurl, AutoWide(g_config->ReadString("nowplayingurl","")), ARRAYSIZE(nowplayingurl));
|
||||
|
||||
service->SetName(MAKEINTRESOURCE(IDS_SERVICE_NAME));
|
||||
service->SetUrl((nowplayingurl[0] ? nowplayingurl : SERVICE_HOMEURL));
|
||||
service->SetIcon(MAKEINTRESOURCE(IDR_SERVICE_ICON));
|
||||
|
||||
*instance = service;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
size_t OmService::AddRef()
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&ref);
|
||||
}
|
||||
|
||||
size_t OmService::Release()
|
||||
{
|
||||
if (0 == ref)
|
||||
return ref;
|
||||
|
||||
LONG r = InterlockedDecrement((LONG*)&ref);
|
||||
if (0 == r)
|
||||
delete(this);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int OmService::QueryInterface(GUID interface_guid, void **object)
|
||||
{
|
||||
if (NULL == object) return E_POINTER;
|
||||
|
||||
if (IsEqualIID(interface_guid, IFC_OmService))
|
||||
*object = static_cast<ifc_omservice*>(this);
|
||||
else
|
||||
{
|
||||
*object = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
if (NULL == *object)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
unsigned int OmService::GetId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
HRESULT OmService::GetName(wchar_t *pszBuffer, int cchBufferMax)
|
||||
{
|
||||
return Plugin_CopyResString(pszBuffer, cchBufferMax, name);
|
||||
}
|
||||
|
||||
HRESULT OmService::GetUrl(wchar_t *pszBuffer, int cchBufferMax)
|
||||
{
|
||||
return StringCchCopyEx(pszBuffer, cchBufferMax, url, NULL, NULL, STRSAFE_IGNORE_NULLS);
|
||||
}
|
||||
|
||||
HRESULT OmService::GetIcon(wchar_t *pszBuffer, int cchBufferMax)
|
||||
{
|
||||
if (NULL != icon && IS_INTRESOURCE(icon))
|
||||
{
|
||||
WCHAR szPath[2*MAX_PATH] = {0};
|
||||
if (0 == GetModuleFileName(Plugin_GetInstance(), szPath, ARRAYSIZE(szPath)))
|
||||
return E_FAIL;
|
||||
|
||||
return StringCchPrintf(pszBuffer, cchBufferMax, L"res://%s/#%d/#%d", szPath, RT_RCDATA, icon);
|
||||
}
|
||||
|
||||
return StringCchCopyEx(pszBuffer, cchBufferMax, icon, NULL, NULL, STRSAFE_IGNORE_NULLS);
|
||||
}
|
||||
|
||||
HRESULT OmService::GetExternal(IDispatch **ppDispatch)
|
||||
{
|
||||
if (NULL == ppDispatch)
|
||||
return E_POINTER;
|
||||
|
||||
*ppDispatch = NULL;
|
||||
|
||||
HWND hWinamp = Plugin_GetWinamp();
|
||||
if (NULL == hWinamp)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
// So far we do not use JSAPI2 in nowplaying
|
||||
// // try JSAPI2 first
|
||||
// WCHAR szBuffer[64] = {0};
|
||||
// if (SUCCEEDED(StringCchPrintfW(szBuffer, ARRAYSIZE(szBuffer), L"%u", id)))
|
||||
// *ppDispatch = (IDispatch*)SENDWAIPC(hWinamp, IPC_JSAPI2_GET_DISPATCH_OBJECT, (WPARAM)szBuffer);
|
||||
|
||||
if (IS_INVALIDISPATCH(*ppDispatch))
|
||||
{ // try JSAPI1
|
||||
*ppDispatch = (IDispatch*)SENDWAIPC(hWinamp, IPC_GET_DISPATCH_OBJECT, 0);
|
||||
if (IS_INVALIDISPATCH(*ppDispatch))
|
||||
{ // Fail
|
||||
*ppDispatch = NULL;
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT OmService::SetName(LPCWSTR pszName)
|
||||
{
|
||||
Plugin_FreeResString(name);
|
||||
name = Plugin_DuplicateResString(pszName);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT OmService::SetUrl(LPCWSTR pszUrl)
|
||||
{
|
||||
Plugin_FreeString(url);
|
||||
url = Plugin_CopyString(pszUrl);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT OmService::SetIcon(LPCWSTR pszIcon)
|
||||
{
|
||||
Plugin_FreeResString(icon);
|
||||
icon = Plugin_DuplicateResString(pszIcon);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#define CBCLASS OmService
|
||||
START_DISPATCH;
|
||||
CB(ADDREF, AddRef)
|
||||
CB(RELEASE, Release)
|
||||
CB(QUERYINTERFACE, QueryInterface)
|
||||
CB(API_GETID, GetId)
|
||||
CB(API_GETNAME, GetName)
|
||||
CB(API_GETURL, GetUrl)
|
||||
CB(API_GETICON, GetIcon)
|
||||
CB(API_GETEXTERNAL, GetExternal)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
||||
|
||||
|
53
Src/Plugins/Library/ml_nowplaying/service.h
Normal file
53
Src/Plugins/Library/ml_nowplaying/service.h
Normal file
@ -0,0 +1,53 @@
|
||||
#ifndef NULLSOFT_NOWPLAYING_PLUGIN_SERVICE_HEADER
|
||||
#define NULLSOFT_NOWPLAYING_PLUGIN_SERVICE_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
#include <ifc_omservice.h>
|
||||
|
||||
#define SERVICE_ID 101
|
||||
#define SERVICE_HOMEURL L"http://client.winamp.com/nowplaying?v=5.9&icid=navigationtree"
|
||||
|
||||
class OmService : public ifc_omservice
|
||||
{
|
||||
|
||||
protected:
|
||||
OmService(UINT nId);
|
||||
~OmService();
|
||||
|
||||
public:
|
||||
static HRESULT CreateInstance(OmService **instance);
|
||||
|
||||
public:
|
||||
/* Dispatchable */
|
||||
size_t AddRef();
|
||||
size_t Release();
|
||||
int QueryInterface(GUID interface_guid, void **object);
|
||||
|
||||
/* ifc_omservice */
|
||||
unsigned int GetId();
|
||||
HRESULT GetName(wchar_t *pszBuffer, int cchBufferMax);
|
||||
HRESULT GetUrl(wchar_t *pszBuffer, int cchBufferMax);
|
||||
HRESULT GetExternal(IDispatch **ppDispatch);
|
||||
HRESULT GetIcon(wchar_t *pszBuffer, int cchBufferMax);
|
||||
|
||||
public:
|
||||
HRESULT SetName(LPCWSTR pszName);
|
||||
HRESULT SetUrl(LPCWSTR pszUrl);
|
||||
HRESULT SetIcon(LPCWSTR pszIcon);
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
|
||||
protected:
|
||||
ULONG ref;
|
||||
UINT id;
|
||||
LPWSTR name;
|
||||
LPWSTR url;
|
||||
LPWSTR icon;
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_NOWPLAYING_PLUGIN_SERVICE_HEADER
|
39
Src/Plugins/Library/ml_nowplaying/version.rc2
Normal file
39
Src/Plugins/Library/ml_nowplaying/version.rc2
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
#include "../../../Winamp/buildType.h"
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 4,0,1,0
|
||||
PRODUCTVERSION WINAMP_PRODUCTVER
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x4L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Winamp SA"
|
||||
VALUE "FileDescription", "Winamp Media Library Plug-in"
|
||||
VALUE "FileVersion", "4,0,1,0"
|
||||
VALUE "InternalName", "Nullsoft Nowplaying"
|
||||
VALUE "LegalCopyright", "Copyright <20> 2003-2023 Winamp SA"
|
||||
VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
|
||||
VALUE "OriginalFilename", "ml_nowplaying.dll"
|
||||
VALUE "ProductName", "Winamp"
|
||||
VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
82
Src/Plugins/Library/ml_nowplaying/wasabi.cpp
Normal file
82
Src/Plugins/Library/ml_nowplaying/wasabi.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
#include "main.h"
|
||||
#include "./wasabi.h"
|
||||
#include <api/service/waservicefactory.h>
|
||||
|
||||
static ULONG wasabiRef = 0;
|
||||
|
||||
api_application *WASABI_API_APP = NULL;
|
||||
api_language *WASABI_API_LNG = NULL;
|
||||
JSAPI2::api_security *AGAVE_API_JSAPI2_SECURITY = NULL;
|
||||
obj_ombrowser *browserManager = NULL;
|
||||
api_syscb *WASABI_API_SYSCB = NULL;
|
||||
ifc_omutility *omUtility = NULL;
|
||||
|
||||
HINSTANCE WASABI_API_LNG_HINST = NULL;
|
||||
HINSTANCE WASABI_API_ORIG_HINST = NULL;
|
||||
EXTERN_C winampMediaLibraryPlugin plugin;
|
||||
|
||||
void *Wasabi_QueryInterface(REFGUID interfaceGuid)
|
||||
{
|
||||
waServiceFactory *serviceFactory = plugin.service->service_getServiceByGuid(interfaceGuid);
|
||||
return (NULL != serviceFactory) ? serviceFactory->getInterface() : NULL;
|
||||
}
|
||||
|
||||
void Wasabi_ReleaseInterface(REFGUID interfaceGuid, void *pInstance)
|
||||
{
|
||||
waServiceFactory *serviceFactory = plugin.service->service_getServiceByGuid(interfaceGuid);
|
||||
if (NULL != serviceFactory) serviceFactory->releaseInterface(pInstance);
|
||||
}
|
||||
|
||||
void Wasabi_SafeRelease(Dispatchable *pDisp)
|
||||
{
|
||||
if (NULL != pDisp)
|
||||
pDisp->Release();
|
||||
}
|
||||
|
||||
BOOL WasabiApi_Initialize(HINSTANCE hInstance)
|
||||
{
|
||||
WASABI_API_APP = QueryWasabiInterface(api_application, applicationApiServiceGuid);
|
||||
WASABI_API_SYSCB = QueryWasabiInterface(api_syscb, syscbApiServiceGuid);
|
||||
WASABI_API_LNG = QueryWasabiInterface(api_language, languageApiGUID);
|
||||
AGAVE_API_JSAPI2_SECURITY = QueryWasabiInterface(JSAPI2::api_security, JSAPI2::api_securityGUID);
|
||||
OMBROWSERMNGR = QueryWasabiInterface(obj_ombrowser, OBJ_OmBrowser);
|
||||
OMUTILITY = QueryWasabiInterface(ifc_omutility, IFC_OmUtility);
|
||||
|
||||
if (NULL != WASABI_API_LNG)
|
||||
WASABI_API_START_LANG(hInstance, MlNowPlayingLangGUID);
|
||||
|
||||
WasabiApi_AddRef();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void WasabiApi_Uninitialize()
|
||||
{
|
||||
ReleaseWasabiInterface(applicationApiServiceGuid, WASABI_API_APP);
|
||||
ReleaseWasabiInterface(syscbApiServiceGuid, WASABI_API_SYSCB);
|
||||
ReleaseWasabiInterface(languageApiGUID, WASABI_API_LNG);
|
||||
ReleaseWasabiInterface(JSAPI2::api_securityGUID, AGAVE_API_JSAPI2_SECURITY);
|
||||
ReleaseWasabiInterface(OBJ_OmBrowser, OMBROWSERMNGR);
|
||||
ReleaseWasabiInterface(IFC_OmUtility, OMUTILITY);
|
||||
|
||||
WASABI_API_APP = NULL;
|
||||
WASABI_API_LNG = NULL;
|
||||
AGAVE_API_JSAPI2_SECURITY = NULL;
|
||||
}
|
||||
|
||||
ULONG WasabiApi_AddRef()
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&wasabiRef);
|
||||
}
|
||||
|
||||
ULONG WasabiApi_Release()
|
||||
{
|
||||
if (0 == wasabiRef)
|
||||
return wasabiRef;
|
||||
|
||||
LONG r = InterlockedDecrement((LONG*)&wasabiRef);
|
||||
if (0 == r)
|
||||
{
|
||||
WasabiApi_Uninitialize();
|
||||
}
|
||||
return r;
|
||||
}
|
42
Src/Plugins/Library/ml_nowplaying/wasabi.h
Normal file
42
Src/Plugins/Library/ml_nowplaying/wasabi.h
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef NULLSOFT_NOWPLAYING_PLUGIN_WASABI_HEADER
|
||||
#define NULLSOFT_NOWPLAYING_PLUGIN_WASABI_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
#include <api/application/api_application.h>
|
||||
#define WASABI_API_APP applicationApi
|
||||
|
||||
#include "../Agave/Language/api_language.h"
|
||||
|
||||
#include "../Winamp/JSAPI2_api_security.h"
|
||||
extern JSAPI2::api_security *jsapi2_securityApi;
|
||||
#define AGAVE_API_JSAPI2_SECURITY jsapi2_securityApi
|
||||
|
||||
#include <obj_ombrowser.h>
|
||||
extern obj_ombrowser *browserManager;
|
||||
#define OMBROWSERMNGR browserManager
|
||||
|
||||
#include <api/syscb/api_syscb.h>
|
||||
#define WASABI_API_SYSCB sysCallbackApi
|
||||
|
||||
#include <ifc_omutility.h>
|
||||
extern ifc_omutility *omUtility;
|
||||
#define OMUTILITY omUtility
|
||||
|
||||
BOOL WasabiApi_Initialize(HINSTANCE hInstance);
|
||||
ULONG WasabiApi_AddRef(void);
|
||||
ULONG WasabiApi_Release(void);
|
||||
|
||||
void *Wasabi_QueryInterface(REFGUID interfaceGuid);
|
||||
void Wasabi_ReleaseInterface(REFGUID interfaceGuid, void *pInstance);
|
||||
|
||||
#define QueryWasabiInterface(__interfaceType, __interfaceGuid) ((##__interfaceType*)Wasabi_QueryInterface(__interfaceGuid))
|
||||
#define ReleaseWasabiInterface(__interfaceGuid, __interfaceInstance) (Wasabi_ReleaseInterface((__interfaceGuid), (__interfaceInstance)))
|
||||
|
||||
void Wasabi_SafeRelease(Dispatchable *pDisp);
|
||||
|
||||
#endif // NULLSOFT_NOWPLAYING_PLUGIN_WASABI_HEADER
|
90
Src/Plugins/Library/ml_nowplaying/wasabiCallback.cpp
Normal file
90
Src/Plugins/Library/ml_nowplaying/wasabiCallback.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
#include "main.h"
|
||||
#include "./wasabiCallback.h"
|
||||
#include "./navigation.h"
|
||||
#include "./service.h"
|
||||
#include "../replicant/nu/Autowide.h"
|
||||
|
||||
WasabiCallback::WasabiCallback()
|
||||
: ref(1)
|
||||
{
|
||||
}
|
||||
|
||||
WasabiCallback::~WasabiCallback()
|
||||
{
|
||||
}
|
||||
|
||||
HRESULT WasabiCallback::CreateInstance(WasabiCallback **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
|
||||
*instance = new WasabiCallback();
|
||||
if (NULL == *instance) return E_OUTOFMEMORY;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
size_t WasabiCallback::AddRef()
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&ref);
|
||||
}
|
||||
|
||||
size_t WasabiCallback::Release()
|
||||
{
|
||||
if (0 == ref)
|
||||
return ref;
|
||||
|
||||
LONG r = InterlockedDecrement((LONG*)&ref);
|
||||
if (0 == r)
|
||||
delete(this);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int WasabiCallback::QueryInterface(GUID interface_guid, void **object)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
FOURCC WasabiCallback::GetEventType()
|
||||
{
|
||||
return SysCallback::BROWSER;
|
||||
}
|
||||
|
||||
int WasabiCallback::Notify(int msg, intptr_t param1, intptr_t param2)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case BrowserCallback::ONOPENURL:
|
||||
return OpenURL(reinterpret_cast<const wchar_t*>(param1), reinterpret_cast<bool *>(param2));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WasabiCallback::OpenURL(const wchar_t *url, bool *override)
|
||||
{
|
||||
WCHAR szTemplate[1024] = L"http://client.winamp.com/nowplaying";
|
||||
INT cchTemplate = ARRAYSIZE(szTemplate) - 1;
|
||||
lstrcpynW(szTemplate, AutoWide(g_config->ReadString("nowplayingurl", "http://client.winamp.com/nowplaying")), ARRAYSIZE(szTemplate));
|
||||
|
||||
if (NULL != url &&
|
||||
CSTR_EQUAL == CompareString(CSTR_INVARIANT, NORM_IGNORECASE, url, cchTemplate, szTemplate, cchTemplate))
|
||||
{
|
||||
if (SUCCEEDED(Navigation_ShowService(SERVICE_ID, url,
|
||||
NAVFLAG_FORCEACTIVE | NAVFLAG_ENSUREMLVISIBLE | NAVFLAG_ENSUREITEMVISIBLE)))
|
||||
{
|
||||
*override = true;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CBCLASS WasabiCallback
|
||||
START_DISPATCH;
|
||||
CB(ADDREF, AddRef);
|
||||
CB(RELEASE, Release);
|
||||
CB(QUERYINTERFACE, QueryInterface);
|
||||
CB(SYSCALLBACK_GETEVENTTYPE, GetEventType);
|
||||
CB(SYSCALLBACK_NOTIFY, Notify);
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
42
Src/Plugins/Library/ml_nowplaying/wasabiCallback.h
Normal file
42
Src/Plugins/Library/ml_nowplaying/wasabiCallback.h
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef NULLSOFT_NOWPLAYING_PLUGIN_WASABI_CALLBACK_HEADER
|
||||
#define NULLSOFT_NOWPLAYING_PLUGIN_WASABI_CALLBACK_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <api/syscb/callbacks/syscb.h>
|
||||
#include <api/syscb/callbacks/browsercb.h>
|
||||
|
||||
class WasabiCallback : public SysCallback
|
||||
{
|
||||
protected:
|
||||
WasabiCallback();
|
||||
~WasabiCallback();
|
||||
|
||||
public:
|
||||
static HRESULT CreateInstance(WasabiCallback **instance);
|
||||
|
||||
public:
|
||||
/*** Dispatchable ***/
|
||||
size_t AddRef();
|
||||
size_t Release();
|
||||
int QueryInterface(GUID interface_guid, void **object);
|
||||
|
||||
/*** SysCallback ***/
|
||||
FOURCC GetEventType();
|
||||
int Notify(int msg, intptr_t param1 = 0, intptr_t param2 = 0);
|
||||
|
||||
protected:
|
||||
// set *override = true to prevent the URL from being opened
|
||||
// leave it alone otherwise (in case someone else wanted to override it)
|
||||
int OpenURL(const wchar_t *url, bool *override);
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
|
||||
protected:
|
||||
ULONG ref;
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_NOWPLAYING_PLUGIN_WASABI_CALLBACK_HEADER
|
Reference in New Issue
Block a user