Archived
1
0
This repository has been archived on 2024-10-17. You can view files and clone it, but cannot push or open issues or pull requests.
winamp/Src/Plugins/Library/ml_disc/main.cpp
2024-09-24 14:54:57 +02:00

1273 lines
36 KiB
C++

#include "Main.h"
#include "ReplayGain.h"
#include "../nu/AutoChar.h"
#include "../nu/MediaLibraryInterface.h"
#include "./resource.h"
#include "./settings.h"
#include "./copyfiles.h"
#include "../winamp/wa_ipc.h"
//#include <primosdk.h>
#include <shlwapi.h>
#include <imapi.h>
#include <imapierror.h>
#include "../nu/ns_wc.h"
#include <vector>
#include <strsafe.h>
#define VERSION_MAJOR 2
#define VERSION_MINOR 0
#ifndef ARRAYSIZE
#define ARRAYSIZE(x) (sizeof(x)/sizeof(*x))
#endif
typedef struct _LISTENER
{
HWND hwnd;
UINT uMsg;
CHAR cLetter;
} LISTENER;
typedef struct _NAVITEMENUMPARAM
{
NAVITEMENUMPROC callback;
LPARAM param;
} NAVITEMENUMPARAM;
typedef enum _BTNSTATE
{
BTNSTATE_NORMAL = 0,
BTNSTATE_HILITED = 1,
BTNSTATE_PRESSED = 2,
BTNSTATE_DISABLED = 3,
} BTNSTATE;
#define ICON_SIZE_CX 14
#define ICON_SIZE_CY 14
#define NAVBUTTON_STATECHECK_DELAY 100
static int Init();
static void Quit();
HNAVITEM hniMain = NULL;
static LRESULT delay_ml_startup;
static HMLIMGLST hmlilIcons = NULL;
LARGE_INTEGER freq;
#define NAVITEM_PREFIX L"_ml_disc_"
#define NAVITEM_PREFIX_SIZE (sizeof(NAVITEM_PREFIX)/sizeof(wchar_t))
#define NCS_EX_SHOWEJECT 0x0100
C_Config *g_config, *g_view_metaconf = NULL;
HMENU g_context_menus;
prefsDlgRecW myPrefsItemCD = {0};
INT_PTR imgIndex = 0;
wchar_t randb[64] = {0};
static wchar_t cdrip[64];
static DWORD g_navStyle = NCS_FULLROWSELECT | NCS_SHOWICONS;
static DWORD riphash = 0;
static std::vector<LPARAM> driveList;
static LISTENER activeListener = { NULL, 0, };
static WNDPROC oldWinampWndProc = NULL;
api_application *WASABI_API_APP = 0;
api_stats *AGAVE_API_STATS = 0;
// wasabi based services for localisation support
api_language *WASABI_API_LNG = 0;
HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
static UINT uMsgBurnerNotify = 0;
static UINT uMsgRipperNotify = 0;
static UINT uMsgNavStyleUpdate = 0;
static UINT uMsgCopyNotify = 0;
static void CALLBACK Invoke_OnDriveManagerNotify(WORD wCode, INT_PTR param);
static void Plugin_OnMLVisible(BOOL bVisible);
void ShowHideRipBurnParent(void);
static void DriveParam_RegisterDrive(DRIVE *drive)
{
LPARAM param;
size_t index;
param = (LPARAM)drive;
if (NULL == param)
return;
index = driveList.size();
while(index--)
{
if(param == driveList[index])
return;
}
driveList.push_back(param);
}
static void DriveParam_UnregisterDrive(DRIVE *drive)
{
LPARAM param;
size_t index;
param = (LPARAM)drive;
if (NULL == param)
return;
index = driveList.size();
while(index--)
{
if(param == driveList[index])
{
driveList.erase(driveList.begin() + index);
return;
}
}
}
static BOOL DriveParam_IsValid(LPARAM param)
{
if (param > 0x0000FFFF)
{
size_t index = driveList.size();
while(index--)
{
if(param == driveList[index])
return TRUE;
}
}
return FALSE;
}
DRIVE *Plugin_GetDriveFromNavItem(HNAVITEM hItem)
{
NAVITEM item;
if (!hItem) return NULL;
item.cbSize = sizeof(NAVITEM);
item.mask = NIMF_PARAM;
item.hItem = hItem;
return (MLNavItem_GetInfo(plugin.hwndLibraryParent, &item) && DriveParam_IsValid(item.lParam)) ?
(DRIVE*)item.lParam : NULL;
}
HNAVITEM Plugin_GetNavItemFromLetter(CHAR cLetter)
{
NAVCTRLFINDPARAMS fp = {0};
wchar_t invariant[32] = {0};
if (S_OK == StringCchPrintfW(invariant, sizeof(invariant)/sizeof(wchar_t), L"%s%c", NAVITEM_PREFIX, cLetter))
{
fp.cchLength = -1;
fp.pszName = invariant;
fp.compFlags = NICF_INVARIANT;
return MLNavCtrl_FindItemByName(plugin.hwndLibraryParent, &fp);
}
return NULL;
}
static BOOL CALLBACK EnumerateNavItemsCB(HNAVITEM hItem, LPARAM param)
{
DRIVE *pDrive = Plugin_GetDriveFromNavItem(hItem);
return (pDrive) ? ((NAVITEMENUMPARAM*)param)->callback(hItem, pDrive, ((NAVITEMENUMPARAM*)param)->param) : TRUE;
}
BOOL Plugin_EnumerateNavItems(NAVITEMENUMPROC callback, LPARAM param)
{
NAVITEMENUMPARAM pluginenum;
NAVCTRLENUMPARAMS navenum;
if (!callback) return FALSE;
pluginenum.callback = callback;
pluginenum.param = param;
navenum.hItemStart = hniMain;
navenum.lParam = (LPARAM)&pluginenum;
navenum.enumProc = EnumerateNavItemsCB;
return MLNavCtrl_EnumItems(plugin.hwndLibraryParent, &navenum);
}
void Plugin_RegisterListener(HWND hwnd, UINT uMsg, CHAR cLetter)
{
activeListener.hwnd = hwnd;
activeListener.uMsg = uMsg;
activeListener.cLetter = cLetter;
}
void Plugin_UnregisterListener(HWND hwnd)
{
ZeroMemory(&activeListener, sizeof(LISTENER));
}
static BOOL CALLBACK EnumNavItems_OnUIChangeCB(HNAVITEM hItem, DRIVE *pDrive, LPARAM param)
{
if (pDrive) pDrive->textSize = 0;
return TRUE;
}
static void UpdatedNavStyles(void)
{
g_navStyle = MLNavCtrl_GetStyle(plugin.hwndLibraryParent);
if (0 != g_view_metaconf->ReadInt(TEXT("showeject"), 1)) g_navStyle |= NCS_EX_SHOWEJECT;
}
static BOOL CALLBACK EnumerateNavItemsRemoveCB(HNAVITEM hItem, DRIVE *pDrive, LPARAM param)
{
if(pDrive)
{
MLNavCtrl_DeleteItem(plugin.hwndLibraryParent,hItem);
Plugin_EnumerateNavItems(EnumerateNavItemsRemoveCB, 0);
}
return TRUE;
}
static BOOL Plugin_QueryOkToQuit()
{
CHAR szLetters[24] = {0};
INT c = DriveManager_GetDriveList(szLetters, ARRAYSIZE(szLetters));
while(c-- > 0)
{
INT msgId;
if (cdrip_isextracting(szLetters[c])) msgId = IDS_YOU_ARE_CURRENTLY_RIPPING_AUDIO_CD_MUST_CANCEL_TO_CLOSE_WINAMP;
else if (MLDisc_IsDiscCopying(szLetters[c])) msgId = IDS_YOU_ARE_CURRENTLY_COPYING_DATA_CD_MUST_CANCEL_TO_CLOSE_WINAMP;
else msgId = 0;
if (msgId)
{
wchar_t buffer[512] = {0};
StringCchPrintfW(buffer, 512, WASABI_API_LNGSTRINGW(msgId), szLetters[c]);
MessageBoxW(plugin.hwndWinampParent, buffer, WASABI_API_LNGSTRINGW(IDS_NOTIFICATION),
MB_OK | MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TOPMOST);
return FALSE;
}
}
return TRUE;
}
LRESULT CALLBACK WinampWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if(uMsgNavStyleUpdate == uMsg)
{
if(!wParam)
{
UpdatedNavStyles();
Plugin_EnumerateNavItems(EnumNavItems_OnUIChangeCB, 0);
}
else
{
Plugin_EnumerateNavItems(EnumerateNavItemsRemoveCB, 0);
ShowHideRipBurnParent();
DriveManager_Uninitialize(0);
DriveManager_Initialize(Invoke_OnDriveManagerNotify, TRUE);
Plugin_OnMLVisible((BOOL)SENDMLIPC(plugin.hwndLibraryParent, ML_IPC_IS_VISIBLE, 0));
}
}
else if (uMsgBurnerNotify == uMsg) // burner broadcast message LOWORD(wParam) = drive letter, lParam = (BOOL)bStarted. if bStarted = TRUE - burning started, otherwise burning finished
{
if (0 == HIWORD(wParam))
{
DriveManager_SetDriveMode((CHAR)LOWORD(wParam), (0 != lParam) ? DM_MODE_BURNING : DM_MODE_READY);
}
}
else if (uMsgRipperNotify == uMsg)
{
if (HIWORD(wParam)) // another instance of winamp quering
{
if (LOWORD(wParam) && cdrip_isextracting((CHAR)LOWORD(wParam))) SendNotifyMessage((HWND)lParam, uMsgRipperNotify, LOWORD(wParam), (LPARAM)TRUE);
else
{
CHAR cLetter;
cLetter = (CHAR)cdrip_isextracting(-1);
if (cLetter) SendNotifyMessage((HWND)lParam, uMsgRipperNotify, cLetter, (LPARAM)TRUE);
}
}
else
{
DriveManager_SetDriveMode((CHAR)LOWORD(wParam), (0 != lParam) ? DM_MODE_RIPPING : DM_MODE_READY);
}
}
else if (uMsgCopyNotify == uMsg)
{
if (HIWORD(wParam))
{
if (LOWORD(wParam) && MLDisc_IsDiscCopying((CHAR)LOWORD(wParam))) SendNotifyMessage((HWND)lParam, uMsgCopyNotify, LOWORD(wParam), (LPARAM)TRUE);
else
{
CHAR szLetters[24] = {0};
INT c = DriveManager_GetDriveList(szLetters, ARRAYSIZE(szLetters));
while(c-- > 0)
{
if (MLDisc_IsDiscCopying(szLetters[c]))
SendNotifyMessage((HWND)lParam, uMsgCopyNotify, szLetters[c], (LPARAM)TRUE);
}
}
}
else
{
DriveManager_SetDriveMode((CHAR)LOWORD(wParam), (0 != lParam) ? DM_MODE_COPYING : DM_MODE_READY);
}
}
else if (WM_WA_IPC == uMsg)
{
switch(lParam)
{
case IPC_SKIN_CHANGED:
case IPC_CB_RESETFONT:
UpdatedNavStyles();
Plugin_EnumerateNavItems(EnumNavItems_OnUIChangeCB, 0);
break;
case IPC_FILE_TAG_MAY_HAVE_UPDATED:
case IPC_FILE_TAG_MAY_HAVE_UPDATEDW:
if (activeListener.hwnd) SendMessageW(activeListener.hwnd, activeListener.uMsg, (WPARAM)lParam, (LPARAM)wParam);
break;
}
if(lParam == delay_ml_startup)
{
if(!wParam)
{
PostMessage(plugin.hwndWinampParent, WM_WA_IPC, 1, delay_ml_startup);
}
else if(wParam == 1)
{
// TODO: benski> temp-hack fix for now -- if (SENDMLIPC(plugin.hwndLibraryParent, ML_IPC_IS_VISIBLE, 0))
{
DriveManager_Initialize(Invoke_OnDriveManagerNotify, TRUE);
MLDisc_InitializeCopyData();
DriveManager_Resume(TRUE);
SendNotifyMessage(HWND_BROADCAST, uMsgBurnerNotify, MAKEWPARAM(0, 0xffff), (LPARAM)plugin.hwndWinampParent);
SendNotifyMessage(HWND_BROADCAST, uMsgRipperNotify, MAKEWPARAM(0, 0xffff), (LPARAM)plugin.hwndWinampParent);
SendNotifyMessage(HWND_BROADCAST, uMsgCopyNotify, MAKEWPARAM(0, 0xffff), (LPARAM)plugin.hwndWinampParent);
}
}
}
}
return (oldWinampWndProc) ? CallWindowProcW(oldWinampWndProc, hwnd, uMsg, wParam, lParam) : DefWindowProc(hwnd, uMsg, wParam, lParam);
}
static DM_UNITINFO2_PARAM unitinfo;
static char szDesc[1024];
static DWORD szTypes[64];
static void CALLBACK FreeParam(DM_NOTIFY_PARAM *phdr)
{
if (!phdr) return;
switch(phdr->opCode)
{
case DMOP_TITLE:
if (((DM_TITLE_PARAM*)phdr)->pszTitle) free(((DM_TITLE_PARAM*)phdr)->pszTitle);
break;
}
free(phdr);
}
static void RegisterIcons()
{
MLIMAGELISTCREATE mlilCreate;
MLIMAGESOURCE mlis;
MLIMAGELISTITEM mlilItem;
if (hmlilIcons) return;
mlilCreate.cx = ICON_SIZE_CX;
mlilCreate.cy = ICON_SIZE_CY;
mlilCreate.cInitial = 5;
mlilCreate.cGrow = 1;
mlilCreate.cCacheSize = 3;
mlilCreate.flags = MLILC_COLOR24;
hmlilIcons = MLImageList_Create(plugin.hwndLibraryParent, &mlilCreate);
if (!hmlilIcons) return;
ZeroMemory(&mlilItem, sizeof(MLIMAGELISTITEM));
mlilItem.cbSize = sizeof(MLIMAGELISTITEM);
mlilItem.hmlil = hmlilIcons;
mlilItem.filterUID = MLIF_FILTER1_UID;
mlilItem.pmlImgSource = &mlis;
ZeroMemory(&mlis, sizeof(MLIMAGESOURCE));
mlis.cbSize = sizeof(MLIMAGESOURCE);
mlis.type = SRC_TYPE_PNG;
mlis.hInst = plugin.hDllInstance;
mlis.lpszName = MAKEINTRESOURCEW(IDB_NAVITEM_CDROM);
MLImageList_Add(plugin.hwndLibraryParent, &mlilItem);
mlis.lpszName = MAKEINTRESOURCEW(IDB_EJECT_NORMAL);
MLImageList_Add(plugin.hwndLibraryParent, &mlilItem);
mlis.lpszName = MAKEINTRESOURCEW(IDB_EJECT_HILITED);
MLImageList_Add(plugin.hwndLibraryParent, &mlilItem);
mlis.lpszName = MAKEINTRESOURCEW(IDB_EJECT_PRESSED);
MLImageList_Add(plugin.hwndLibraryParent, &mlilItem);
mlis.lpszName = MAKEINTRESOURCEW(IDB_EJECT_DISABLED);
MLImageList_Add(plugin.hwndLibraryParent, &mlilItem);
}
static BOOL UpdateTitle(CHAR cLetter, LPCWSTR pszTitle)
{
HNAVITEM hItem;
NAVITEM item;
DRIVE *pDrive;
hItem = Plugin_GetNavItemFromLetter(cLetter);
if (!hItem) return FALSE;
pDrive = Plugin_GetDriveFromNavItem(hItem);
if (!pDrive) return FALSE;
if (S_OK != StringCchCopyW(pDrive->szTitle, sizeof(pDrive->szTitle)/sizeof(wchar_t), (pszTitle) ? pszTitle : L"")) return FALSE;
pDrive->textSize = 0;
item.cbSize = sizeof(NAVITEM);
item.mask = NIMF_TEXT;
item.hItem = hItem;
item.pszText = pDrive->szTitle;
return MLNavItem_SetInfo(plugin.hwndLibraryParent, &item);
}
static void QueryTitle(CHAR cLetter)
{
DM_TITLE_PARAM *pdtp;
pdtp = (DM_TITLE_PARAM*)calloc(4, sizeof(DM_TITLE_PARAM));
if (pdtp)
{
pdtp->header.callback = (INT_PTR)Invoke_OnDriveManagerNotify;
pdtp->header.cLetter = cLetter;
pdtp->header.uMsg = NULL;
pdtp->header.fnFree = FreeParam;
pdtp->cchTitle = 256;
pdtp->pszTitle = (wchar_t*)calloc(pdtp->cchTitle, sizeof(wchar_t));
DriveManager_QueryTitle(pdtp);
}
}
static void Drive_OnAdded(CHAR cLetter)
{
wchar_t szInvariant[32] = {0};
DRIVE *pDrive;
NAVINSERTSTRUCT nis = {0};
wchar_t szDriveType[32] = {0}, szDriveCap[64] = {0};
pDrive = (DRIVE*)calloc(1, sizeof(DRIVE));
if (!pDrive) return;
StringCchPrintfW(szInvariant, sizeof(szInvariant)/sizeof(wchar_t), L"%s%c", NAVITEM_PREFIX, cLetter);
pDrive->cLetter = cLetter;
pDrive->cMode = DriveManager_GetDriveMode(cLetter);
WASABI_API_LNGSTRINGW_BUF(IDS_CD, szDriveType, sizeof(szDriveType)/sizeof(wchar_t));
WASABI_API_LNGSTRINGW_BUF(IDS_DRIVE_CAP, szDriveCap, sizeof(szDriveCap)/sizeof(wchar_t));
StringCchPrintfW(pDrive->szTitle, sizeof(pDrive->szTitle)/sizeof(wchar_t), L"%s %s (%C:)", szDriveType, szDriveCap, (WCHAR)cLetter);
if (NULL == hmlilIcons) RegisterIcons();
ZeroMemory(&nis, sizeof(NAVINSERTSTRUCT));
nis.hParent = hniMain;
nis.item.cbSize = sizeof(NAVITEM);
nis.item.pszText = pDrive->szTitle;
nis.item.pszInvariant = szInvariant;
nis.item.mask = NIMF_TEXT | NIMF_TEXTINVARIANT | NIMF_PARAM | NIMF_STYLE;
nis.item.style = NIS_CUSTOMDRAW | NIS_WANTSETCURSOR | NIS_WANTHITTEST;
nis.item.styleMask = nis.item.style;
nis.item.lParam = (LPARAM)pDrive;
if (NULL != MLNavCtrl_InsertItem(plugin.hwndLibraryParent, &nis))
{
DriveParam_RegisterDrive(pDrive);
}
}
static void Drive_OnChanged(CHAR cLetter)
{
QueryTitle(cLetter);
}
static void Drive_OnRemoved(CHAR cLetter)
{
HNAVITEM hItem;
hItem = Plugin_GetNavItemFromLetter(cLetter);
if (hItem) MLNavCtrl_DeleteItem(plugin.hwndLibraryParent, hItem);
if (riphash && (0xFF & (riphash >> 24)) == (UCHAR)cLetter) riphash = 0;
}
static void Drive_OnModeChanged(CHAR cLetter, CHAR cMode)
{
HNAVITEM hItem;
DRIVE *pDrive;
hItem = Plugin_GetNavItemFromLetter(cLetter);
if (!hItem) return;
pDrive = Plugin_GetDriveFromNavItem(hItem);
if (pDrive)
{
NAVITEMINAVLIDATE inv;
pDrive->cMode = cMode;
inv.fErase = FALSE;
inv.hItem = hItem;
inv.prc = NULL;
MLNavItem_Invalidate(plugin.hwndLibraryParent, &inv);
}
}
static void Medium_OnAdded(CHAR cLetter)
{
if (riphash && (0xFF & (riphash >> 24)) == (UCHAR)cLetter) riphash = 0;
QueryTitle(cLetter);
}
static void Medium_OnRemoved(CHAR cLetter)
{
if (riphash && (0xFF & (riphash >> 24)) == (UCHAR)cLetter) riphash = 0;
QueryTitle(cLetter);
}
static void OnDriveMangerOpCompleted(DM_NOTIFY_PARAM *phdr)
{
switch(phdr->opCode)
{
case DMOP_TITLE:
if (S_OK == phdr->result) UpdateTitle(phdr->cLetter, ((DM_TITLE_PARAM*)phdr)->pszTitle);
break;
}
}
static void CALLBACK OnDriveManagerNotify(ULONG_PTR param)
{
WORD code;
CHAR cLetter;
code = LOWORD(param);
cLetter = (CHAR)(0xFF & HIWORD(param));
switch(code)
{
case DMW_DRIVEADDED: Drive_OnAdded(cLetter); break;
case DMW_DRIVEREMOVED: Drive_OnRemoved(cLetter); break;
case DMW_DRIVECHANGED: Drive_OnChanged(cLetter); break;
case DMW_MEDIUMARRIVED: Medium_OnAdded(cLetter); break;
case DMW_MEDIUMREMOVED: Medium_OnRemoved(cLetter); break;
case DMW_MODECHANGED: Drive_OnModeChanged(cLetter, ((CHAR)(HIWORD(param)>>8))); break;
}
if (activeListener.hwnd && (0 == activeListener.cLetter || cLetter == activeListener.cLetter))
PostMessageW(activeListener.hwnd, activeListener.uMsg, (WPARAM)code, (LPARAM)HIWORD(param));
}
static void CALLBACK Invoke_OnDriveManagerNotify(WORD wCode, INT_PTR param)
{
switch(wCode)
{
case DMW_DRIVEADDED:
case DMW_DRIVEREMOVED:
case DMW_DRIVECHANGED:
case DMW_MEDIUMARRIVED:
case DMW_MEDIUMREMOVED:
case DMW_MODECHANGED:
if (GetCurrentThreadId() != GetWindowThreadProcessId(plugin.hwndLibraryParent, NULL))
{
HANDLE htWA = (WASABI_API_APP) ? WASABI_API_APP->main_getMainThreadHandle() : NULL;
if (htWA)
{
QueueUserAPC(OnDriveManagerNotify, htWA, MAKELONG(wCode, (WORD)(param)));
CloseHandle(htWA);
}
}
else OnDriveManagerNotify(MAKELONG(wCode, (WORD)(param)));
break;
case DMW_OPCOMPLETED: OnDriveMangerOpCompleted((DM_NOTIFY_PARAM*)param); break;
}
}
void ShowHideRipBurnParent(void)
{
BOOL bVal;
if (S_OK == Settings_GetBool(C_GLOBAL, GF_SHOWPARENT, &bVal) && bVal)
{
if(!hniMain)
{
NAVINSERTSTRUCT nis;
ZeroMemory(&nis, sizeof(NAVITEM));
nis.item.cbSize = sizeof(NAVITEM);
nis.item.pszText = WASABI_API_LNGSTRINGW_BUF(IDS_RIP_AND_BURN, randb,64);
nis.item.pszInvariant = NAVITEM_PREFIX L"main";
nis.item.mask = NIMF_TEXT | NIMF_STYLE | NIMF_TEXTINVARIANT | NIMF_PARAM;
nis.item.style = NIS_HASCHILDREN;
nis.item.styleMask = nis.item.style;
nis.item.lParam = 0L;
hniMain = MLNavCtrl_InsertItem(plugin.hwndLibraryParent, &nis);
}
}
else
{
if(hniMain)
{
MLNavCtrl_DeleteItem(plugin.hwndLibraryParent,hniMain);
}
hniMain = NULL;
}
}
int Init()
{
QueryPerformanceFrequency(&freq);
// get the Application service
waServiceFactory *sf = plugin.service->service_getServiceByGuid(applicationApiServiceGuid);
if (sf) WASABI_API_APP = (api_application *)sf->getInterface();
// loader so that we can get the localisation service api for use
sf = plugin.service->service_getServiceByGuid(languageApiGUID);
if (sf) WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());
sf = plugin.service->service_getServiceByGuid(AnonymousStatsGUID);
if (sf) AGAVE_API_STATS = reinterpret_cast<api_stats*>(sf->getInterface());
// need to have this initialised before we try to do anything with localisation features
WASABI_API_START_LANG(plugin.hDllInstance,MlDiscLangGUID);
mediaLibrary.library = plugin.hwndLibraryParent;
mediaLibrary.winamp = plugin.hwndWinampParent;
mediaLibrary.instance = plugin.hDllInstance;
static wchar_t szDescription[256];
StringCchPrintf(szDescription, ARRAYSIZE(szDescription),
WASABI_API_LNGSTRINGW(IDS_NULLSOFT_RIP_AND_BURN), VERSION_MAJOR, VERSION_MINOR);
plugin.description = (char*)szDescription;
// add to Winamp preferences
myPrefsItemCD.dlgID = IDD_PREFSCDRIPFR;
myPrefsItemCD.name = WASABI_API_LNGSTRINGW_BUF(IDS_CD_RIPPING,cdrip,64);
myPrefsItemCD.proc = (void*)CDRipPrefsProc;
myPrefsItemCD.hInst = WASABI_API_LNG_HINST;
myPrefsItemCD.where = 6; // media library
SENDWAIPC(plugin.hwndWinampParent, IPC_ADD_PREFS_DLGW, (WPARAM)&myPrefsItemCD);
wchar_t szIniFile[MAX_PATH],
*INI_DIR = (wchar_t*)SENDWAIPC(plugin.hwndWinampParent, IPC_GETINIDIRECTORYW, 0);
PathCombine(szIniFile, INI_DIR, TEXT("Plugins\\gen_ml.ini"));
g_config = new C_Config(szIniFile);
PathCombine(szIniFile, INI_DIR, TEXT("Plugins\\ml\\cdrom.vmd"));
g_view_metaconf = new C_Config(szIniFile);
g_context_menus = WASABI_API_LOADMENU(IDR_CONTEXTMENUS);
oldWinampWndProc = (WNDPROC)(LONG_PTR)SetWindowLongPtrW(plugin.hwndWinampParent, GWLP_WNDPROC, (LONG)(LONG_PTR)WinampWndProc);
if (!uMsgBurnerNotify) uMsgBurnerNotify = RegisterWindowMessageA("WABURNER_BROADCAST_MSG");
if (!uMsgRipperNotify) uMsgRipperNotify = RegisterWindowMessageA("WARIPPER_BROADCAST_MSG");
if (!uMsgCopyNotify) uMsgCopyNotify = RegisterWindowMessageA("WACOPY_BROADCAST_MSG");
if (!uMsgNavStyleUpdate) uMsgNavStyleUpdate = RegisterWindowMessageW(L"ripburn_nav_update");
UpdatedNavStyles();
ShowHideRipBurnParent();
delay_ml_startup = SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&"ml_disc_delay", IPC_REGISTER_WINAMP_IPCMESSAGE);
PostMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, delay_ml_startup);
return ML_INIT_SUCCESS;
}
void Quit()
{
DriveManager_Uninitialize(4000); // allow to wait for 4 sec.
MLDisc_ReleaseCopyData();
delete(g_view_metaconf);
g_view_metaconf = 0;
delete(g_config);
g_config = NULL;
if (rgThread)
{
QueueUserAPC(QuitThread, rgThread, 0);
WaitForSingleObject(rgThread, INFINITE);
CloseHandle(rgThread);
rgThread = 0;
}
waServiceFactory *sf = plugin.service->service_getServiceByGuid(AnonymousStatsGUID);
if (sf) sf->releaseInterface(AGAVE_API_STATS);
}
int getFileInfo(const char *filename, const char *metadata, char *dest, int len)
{
dest[0] = 0;
extendedFileInfoStruct efis = { filename, metadata, dest, len, };
return (int)(INT_PTR)SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM) & efis, IPC_GET_EXTENDED_FILE_INFO); //will return 1 if wa2 supports this IPC call
}
int getFileInfoW(const wchar_t *filename, const wchar_t *metadata, wchar_t *dest, int len)
{
if (dest && len)
dest[0] = 0;
extendedFileInfoStructW efis = { filename, metadata, dest, len, };
return (int)(INT_PTR)SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&efis, IPC_GET_EXTENDED_FILE_INFOW); //will return 1 if wa2 supports this IPC call
}
void Plugin_ShowRippingPreferences(void)
{
SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&myPrefsItemCD, IPC_OPENPREFSTOPAGE);
}
BOOL Plugin_IsExtractScheduled(CHAR cLetter)
{
BOOL result;
if (riphash && (0xFF & (riphash >> 24)) == (UCHAR)cLetter)
{
DWORD mediumSN;
char devname[] = "X:\\";
devname[0] = cLetter;
result = (GetVolumeInformationA(devname, NULL, 0, &mediumSN, NULL, NULL, NULL, 0) && (0x00FFFFFF & riphash) == mediumSN);
riphash = 0;
}
else result = FALSE;
return result;
}
static int Root_OnContextMenu(HNAVITEM hItem, HWND hHost, POINTS pts)
{
HMENU hMenu = GetSubMenu(g_context_menus, 7);
if (!hMenu) return 0;
POINT pt;
POINTSTOPOINT(pt, pts);
if (-1 == pt.x || -1 == pt.y)
{
NAVITEMGETRECT itemRect;
itemRect.fItem = FALSE;
itemRect.hItem = hItem;
if (MLNavItem_GetRect(plugin.hwndLibraryParent, &itemRect))
{
MapWindowPoints(hHost, HWND_DESKTOP, (POINT*)&itemRect.rc, 2);
pt.x = itemRect.rc.left + 2;
pt.y = itemRect.rc.top + 2;
}
}
int r = Menu_TrackPopup(plugin.hwndLibraryParent, hMenu,
TPM_RETURNCMD | TPM_RIGHTBUTTON | TPM_LEFTBUTTON | TPM_NONOTIFY,
pt.x, pt.y, hHost, NULL);
switch (r)
{
case ID_NAVIGATION_PREFERENCES: Plugin_ShowRippingPreferences(); return 1;
case ID_NAVIGATION_HELP: SENDWAIPC(plugin.hwndWinampParent, IPC_OPEN_URL, L"https://help.winamp.com/hc/articles/8111574760468-CD-Ripping-with-Winamp"); return 1;
break;
}
return 0;
}
static int Plugin_OnContextMenu(HNAVITEM hItem, HWND hHost, POINTS pts, CHAR cLetter)
{
HMENU hMenu = GetSubMenu(g_context_menus, 2);
if (!hMenu) return 0;
MENUITEMINFO mii = { sizeof(MENUITEMINFO), };
mii.fMask = MIIM_STATE;
if (GetMenuItemInfo(hMenu, ID_CDROMMENU_EJECTCD, FALSE, &mii))
{
mii.fState &= ~(MFS_ENABLED | MFS_DISABLED);
mii.fState |= ((DM_MODE_READY == DriveManager_GetDriveMode(cLetter)) ? MFS_ENABLED : MFS_DISABLED);
SetMenuItemInfo(hMenu, ID_CDROMMENU_EJECTCD, FALSE, &mii);
}
POINT pt;
POINTSTOPOINT(pt, pts);
if (-1 == pt.x || -1 == pt.y)
{
NAVITEMGETRECT itemRect;
itemRect.fItem = FALSE;
itemRect.hItem = hItem;
if (MLNavItem_GetRect(plugin.hwndLibraryParent, &itemRect))
{
MapWindowPoints(hHost, HWND_DESKTOP, (POINT*)&itemRect.rc, 2);
pt.x = itemRect.rc.left + 2;
pt.y = itemRect.rc.top + 2;
}
}
int r = Menu_TrackPopup(plugin.hwndLibraryParent, hMenu,
TPM_RETURNCMD | TPM_RIGHTBUTTON | TPM_LEFTBUTTON | TPM_NONOTIFY,
pt.x, pt.y, hHost, NULL);
switch (r)
{
case ID_CDROMMENU_EXTRACT_CONFIGURE: Plugin_ShowRippingPreferences(); return 1;
case ID_CDROMMENU_EXTRACT_HELP: SENDWAIPC(plugin.hwndWinampParent, IPC_OPEN_URL, L"https://help.winamp.com/hc/articles/8111574760468-CD-Ripping-with-Winamp"); return 1;
case ID_CDROMMENU_PLAYALL:
case ID_CDROMMENU_ENQUEUEALL:
{
int enq = r == ID_CDROMMENU_ENQUEUEALL;
itemRecordList obj = {0, };
saveCDToItemRecordList(cLetter, &obj, NULL);
mlSendToWinampStruct p;
p.type = ML_TYPE_CDTRACKS;
p.enqueue = enq | 2;
p.data = &obj;
SENDMLIPC(plugin.hwndLibraryParent, ML_IPC_SENDTOWINAMP, (WPARAM)&p);
freeRecordList(&obj);
}
break;
case ID_CDROMMENU_EXTRACT_EXTRACTALL:
riphash = 0;
if (hItem)
{
if (hItem == MLNavCtrl_GetSelection(plugin.hwndLibraryParent))
{
HWND hwnd = (HWND)SENDMLIPC(plugin.hwndLibraryParent, ML_IPC_GETCURRENTVIEW, 0);
if (hwnd && SendMessageW(hwnd, WM_EXTRACTDISC, cLetter, 0)) break;
}
char devname[] = "X:\\";
devname[0] = cLetter;
if (!GetVolumeInformationA(devname, NULL, 0, &riphash, NULL, NULL, NULL, 0)) riphash = 0;
if (riphash) riphash = ((0x00FFFFFF & riphash) | (cLetter << 24));
MLNavItem_Select(plugin.hwndLibraryParent, hItem);
}
break;
case ID_CDROMMENU_EJECTCD:
{
CHAR cMode;
cMode = DriveManager_GetDriveMode(cLetter);
if (DM_MODE_READY != cMode)
{
wchar_t title[32] = {0};
MessageBox(plugin.hwndLibraryParent,
WASABI_API_LNGSTRINGW((DM_MODE_RIPPING == cMode) ? IDS_ERROR_CD_RIP_IN_PROGRESS : IDS_ERROR_CD_BURN_IN_PROGRESS),
WASABI_API_LNGSTRINGW_BUF(IDS_CD_EJECT,title,32), 0);
return FALSE;
}
else DriveManager_Eject(cLetter, DM_EJECT_REMOVE);
}
break;
}
Sleep(100);
MSG msg;
while (PeekMessageW(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)); //eat return
return 0;
}
static DWORD resumeTick = 0; // this is cheating
static void Plugin_OnMLVisible(BOOL bVisible)
{
if (bVisible)
{
DriveManager_Resume(TRUE);
resumeTick = GetTickCount();
SendNotifyMessage(HWND_BROADCAST, uMsgBurnerNotify, MAKEWPARAM(0, 0xffff), (LPARAM)plugin.hwndWinampParent);
SendNotifyMessage(HWND_BROADCAST, uMsgRipperNotify, MAKEWPARAM(0, 0xffff), (LPARAM)plugin.hwndWinampParent);
SendNotifyMessage(HWND_BROADCAST, uMsgCopyNotify, MAKEWPARAM(0, 0xffff), (LPARAM)plugin.hwndWinampParent);
return;
}
else DriveManager_Suspend();
}
static HWND Plugin_OnViewCreate(HNAVITEM hItem, HWND hwndParent)
{
if (hItem == hniMain)
{
return WASABI_API_CREATEDIALOGW(IDD_VIEW_RIPBURN, hwndParent, view_ripburnDialogProc);
}
else
{
DRIVE *pDrive = Plugin_GetDriveFromNavItem(hItem);
if (pDrive) return CreateContainerWindow(hwndParent, pDrive->cLetter, ((GetTickCount() - resumeTick) > 100));
resumeTick = 0;
}
return NULL;
}
static BOOL Plugin_OnNavItemDelete(HNAVITEM hItem)
{
DRIVE *pDrive = Plugin_GetDriveFromNavItem(hItem);
if (!pDrive) return FALSE;
DriveParam_UnregisterDrive(pDrive);
free(pDrive);
return TRUE;
}
static BOOL Plugin_OnNavItemClick(HNAVITEM hItem, UINT nAction, HWND hwndParent)
{
return FALSE;
}
static INT Plugin_OnNavCustomDraw(HNAVITEM hItem, NAVITEMDRAW *pnicd, LPARAM lParam)
{
static INT indent = 0;
DRIVE *pDrive;
if (FALSE == DriveParam_IsValid(lParam))
return FALSE;
pDrive = (DRIVE*)lParam;
if (0 == indent) indent = MLNavCtrl_GetIndent(plugin.hwndLibraryParent);
switch(pnicd->drawStage)
{
case NIDS_PREPAINT:
if (pnicd->prc->bottom > 0 && pnicd->prc->bottom > pnicd->prc->top)
{
HIMAGELIST himl;
INT realIndex, l, t, r;
MLIMAGELISTREALINDEX mlilRealIndex;
himl = MLImageList_GetRealList(plugin.hwndLibraryParent, hmlilIcons);
mlilRealIndex.cbSize = sizeof(MLIMAGELISTREALINDEX);
mlilRealIndex.hmlil = hmlilIcons;
mlilRealIndex.rgbBk = GetBkColor(pnicd->hdc);
mlilRealIndex.rgbFg = GetTextColor(pnicd->hdc);
t = pnicd->prc->top + (pnicd->prc->bottom - pnicd->prc->top - ICON_SIZE_CY)/2;
l = pnicd->prc->left + (indent*pnicd->iLevel) + 3;
r = pnicd->prc->right;
mlilRealIndex.mlilIndex = 0;
realIndex = ((NCS_SHOWICONS & g_navStyle) && himl && l < pnicd->prc->right) ?
MLImageList_GetRealIndex(plugin.hwndLibraryParent, &mlilRealIndex) : -1;
if (-1 != realIndex) // draw icon
{
if (ImageList_Draw(himl, realIndex, pnicd->hdc, l, t, ILD_NORMAL))
{
ExcludeClipRect(pnicd->hdc, l, t, l + ICON_SIZE_CX, t + ICON_SIZE_CY);
l += (ICON_SIZE_CX + 5);
}
}
pDrive->bEjectVisible = FALSE;
mlilRealIndex.mlilIndex = 1 + ((DM_MODE_READY == pDrive->cMode) ? pDrive->nBtnState : BTNSTATE_DISABLED);
realIndex = ((NCS_EX_SHOWEJECT & g_navStyle) && himl && (r - l) > (24 + 6 + ICON_SIZE_CX)) ?
MLImageList_GetRealIndex(plugin.hwndLibraryParent, &mlilRealIndex) : -1;
if (-1 != realIndex)
{
if (ImageList_Draw(himl, realIndex, pnicd->hdc, r - (ICON_SIZE_CX + 2), t, ILD_NORMAL))
{
r -= (ICON_SIZE_CX + 2);
ExcludeClipRect(pnicd->hdc, r, t, r + ICON_SIZE_CX, t + ICON_SIZE_CY);
r -= 4;
pDrive->bEjectVisible = TRUE;
}
}
if (*pDrive->szTitle && l < r)
{
RECT rt;
INT textH, textW;
COLORREF rgbOld(0), rgbBkOld(0);
if (!pDrive->textSize || (pDrive->textOrigWidth > r-l-3 && pDrive->itemWidth > (pnicd->prc->right - pnicd->prc->left)) ||
(LOWORD(pDrive->textSize) != pDrive->textOrigWidth && pDrive->itemWidth < (pnicd->prc->right - pnicd->prc->left)))
{
NAVITEM item;
item.cbSize = sizeof(NAVITEM);
item.mask = NIMF_TEXT;
item.hItem = hItem;
item.cchTextMax = sizeof(pDrive->szTitle)/sizeof(wchar_t);
item.pszText = pDrive->szTitle;
MLNavItem_GetInfo(plugin.hwndLibraryParent, &item);
{
if (pDrive->szTitle != item.pszText)
{
StringCchCopyW(pDrive->szTitle, sizeof(pDrive->szTitle)/sizeof(wchar_t), item.pszText);
}
if (!pDrive->textSize)
{
SetRect(&rt, 0, 0, 1, 1);
DrawTextW(pnicd->hdc, pDrive->szTitle, -1, &rt, DT_SINGLELINE | DT_CALCRECT);
pDrive->textOrigWidth = rt.right - rt.left;
}
SetRect(&rt, 0, 0, r - l - 3, 1);
textH = DrawTextW(pnicd->hdc, pDrive->szTitle, -1, &rt, DT_SINGLELINE|DT_CALCRECT|DT_END_ELLIPSIS|DT_MODIFYSTRING);
textW = rt.right - rt.left;
pDrive->textSize = (DWORD)MAKELONG(textW, textH);
}
}
else
{
textW = LOWORD(pDrive->textSize);
textH = HIWORD(pDrive->textSize);
}
if (0 == (NCS_FULLROWSELECT & g_navStyle) && ((NIS_SELECTED | NIS_DROPHILITED) & pnicd->itemState))
{
rgbOld = SetTextColor(pnicd->hdc, pnicd->clrText);
rgbBkOld = SetBkColor(pnicd->hdc, pnicd->clrTextBk);
}
if (r > (l + textW + 7)) r = l + textW + 7;
SetRect(&rt, l, pnicd->prc->top, r, pnicd->prc->bottom);
t = pnicd->prc->top + (pnicd->prc->bottom - pnicd->prc->top - textH)/2;
ExtTextOutW(pnicd->hdc, rt.left + 2, t, ETO_CLIPPED | ETO_OPAQUE, &rt, pDrive->szTitle, lstrlenW(pDrive->szTitle), 0);
if (0 == (NCS_FULLROWSELECT & g_navStyle) && (NIS_FOCUSED & pnicd->itemState) &&
0 == (0x1 /*UISF_HIDEFOCUS*/ & (INT)SendMessageW(MLNavCtrl_GetHWND(plugin.hwndLibraryParent), 0x129 /*WM_QUERYUISTATE*/, 0, 0L)))
{
DrawFocusRect(pnicd->hdc, &rt);
}
ExcludeClipRect(pnicd->hdc, rt.left, rt.top, rt.right, rt.bottom);
if (0 == (NCS_FULLROWSELECT & g_navStyle) && ((NIS_SELECTED | NIS_DROPHILITED) & pnicd->itemState))
{
if (rgbOld != pnicd->clrText) SetTextColor(pnicd->hdc, rgbOld);
if (rgbBkOld != pnicd->clrTextBk) SetBkColor(pnicd->hdc, rgbBkOld);
}
}
pDrive->itemWidth = (WORD)(pnicd->prc->right - pnicd->prc->left);
if (NCS_FULLROWSELECT & g_navStyle)
{
ExtTextOutW(pnicd->hdc, 0, 0, ETO_OPAQUE, pnicd->prc, L"", 0, 0);
return NICDRF_SKIPDEFAULT;
}
else ExcludeClipRect(pnicd->hdc, pnicd->prc->left, pnicd->prc->top, pnicd->prc->right, pnicd->prc->bottom);
}
break;
case NIDS_POSTPAINT:
break;
}
return NICDRF_DODEFAULT;
}
static HNAVITEM hItemActive = NULL;
static BOOL GetEjectBtnRect(HNAVITEM hItem, RECT *prc)
{
NAVITEMGETRECT navRect;
navRect.fItem = FALSE;
navRect.hItem = hItem;
if (!hItem || !prc || !MLNavItem_GetRect(plugin.hwndLibraryParent, &navRect)) return FALSE;
navRect.rc.right -= 2;
navRect.rc.left = navRect.rc.right - ICON_SIZE_CX;
navRect.rc.top += (navRect.rc.bottom - navRect.rc.top - ICON_SIZE_CY)/2;
navRect.rc.bottom = navRect.rc.top + ICON_SIZE_CY;
CopyRect(prc, &navRect.rc);
return TRUE;
}
static INT_PTR Plugin_OnNavHitTest(HNAVITEM hItem, NAVHITTEST *pnavHitTest, LPARAM lParam)
{
DRIVE *pDrive;
if (FALSE == DriveParam_IsValid(lParam))
return FALSE;
pDrive = (DRIVE*)lParam;
if ((NAVHT_ONITEMRIGHT | NAVHT_ONITEM) & pnavHitTest->flags)
{
RECT rb;
if (pDrive->bEjectVisible && GetEjectBtnRect(hItem, &rb) &&
pnavHitTest->pt.x >= rb.left && pnavHitTest->pt.x <= rb.right &&
pnavHitTest->pt.y >= rb.top && pnavHitTest->pt.y <= rb.bottom)
{
pnavHitTest->flags = NAVHT_NOWHERE;
pnavHitTest->hItem = NULL;
}
}
return 1;
}
static void CALLBACK NavButton_TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
DRIVE *pDrive;
POINT pt;
RECT rb;
pDrive = (hItemActive) ? Plugin_GetDriveFromNavItem(hItemActive) : NULL;
if (!pDrive || (BYTE)BTNSTATE_NORMAL == pDrive->nBtnState || !pDrive->bEjectVisible || !GetEjectBtnRect(hItemActive, &rb))
{
KillTimer(NULL, idEvent);
return;
}
GetCursorPos(&pt);
MapWindowPoints(HWND_DESKTOP, MLNavCtrl_GetHWND(plugin.hwndLibraryParent), &pt, 1);
if (pt.x < rb.left || pt.x > rb.right || pt.y < rb.top || pt.y > rb.bottom)
{
NAVITEMINAVLIDATE inv;
KillTimer(NULL, idEvent);
inv.fErase = FALSE;
inv.hItem = hItemActive;
inv.prc = &rb;
hItemActive = NULL;
pDrive->nBtnState = BTNSTATE_NORMAL;
MLNavItem_Invalidate(plugin.hwndLibraryParent, &inv);
}
}
static INT_PTR Plugin_OnNavSetCursor(HNAVITEM hItem, LPARAM lParam)
{
POINT pt;
DRIVE *pDrive;
BYTE state;
RECT rb;
if (FALSE == DriveParam_IsValid(lParam))
return FALSE;
pDrive = (DRIVE*)lParam;
if (DM_MODE_READY != pDrive->cMode || !pDrive->bEjectVisible || !GetEjectBtnRect(hItem, &rb)) return -1;
GetCursorPos(&pt);
MapWindowPoints(HWND_DESKTOP, MLNavCtrl_GetHWND(plugin.hwndLibraryParent), &pt, 1);
if (pt.x >= rb.left && pt.x <= rb.right && pt.y >= rb.top && pt.y <= rb.bottom)
{
state = (BYTE)((0x8000 & GetAsyncKeyState( GetSystemMetrics(SM_SWAPBUTTON) ? VK_RBUTTON : VK_LBUTTON)) ?
BTNSTATE_PRESSED : BTNSTATE_HILITED);
}
else state = BTNSTATE_NORMAL;
if (pDrive->nBtnState != state)
{
NAVITEMINAVLIDATE inv;
if ((BYTE)BTNSTATE_PRESSED == pDrive->nBtnState && BTNSTATE_HILITED == state)
{
DriveManager_Eject(pDrive->cLetter, DM_EJECT_CHANGE);
}
if (pDrive->timerId)
{
KillTimer(NULL, pDrive->timerId);
pDrive->timerId = 0;
}
if (hItemActive)
{
DRIVE *pDriveOld = Plugin_GetDriveFromNavItem(hItemActive);
if (pDriveOld)
{
RECT rb2;
if (pDriveOld->timerId)
{
KillTimer(NULL, pDriveOld->timerId);
pDriveOld->timerId = NULL;
}
if ((BYTE)BTNSTATE_NORMAL != pDriveOld->nBtnState && GetEjectBtnRect(hItemActive, &rb2))
{
pDriveOld->nBtnState = BTNSTATE_NORMAL;
inv.fErase = FALSE;
inv.hItem = hItemActive;
inv.prc = &rb2;
MLNavItem_Invalidate(plugin.hwndLibraryParent, &inv);
}
hItemActive = NULL;
}
}
if (BTNSTATE_NORMAL != state)
{
hItemActive = hItem;
pDrive->timerId = SetTimer(NULL, 0, NAVBUTTON_STATECHECK_DELAY, NavButton_TimerProc);
}
pDrive->nBtnState = state;
inv.fErase = FALSE;
inv.hItem = hItem;
inv.prc = &rb;
MLNavItem_Invalidate(plugin.hwndLibraryParent, &inv);
}
return -1;
}
static BOOL Plugin_OnConfig(void)
{
SendMessageW(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&myPrefsItemCD, IPC_OPENPREFSTOPAGE);
return TRUE;
}
static INT_PTR pluginMessageProc(int msg, INT_PTR param1, INT_PTR param2, INT_PTR param3)
{
HNAVITEM hItem;
if (msg >= ML_MSG_TREE_BEGIN && msg <= ML_MSG_TREE_END)
{
hItem = (msg < ML_MSG_NAVIGATION_FIRST) ? MLNavCtrl_FindItemById(plugin.hwndLibraryParent, param1) : (HNAVITEM)param1;
if (!hItem) return 0;
} else hItem = NULL;
switch (msg)
{
case ML_MSG_TREE_ONCREATEVIEW: return (INT_PTR)Plugin_OnViewCreate(hItem, (HWND)param2);
case ML_MSG_NAVIGATION_ONDELETE: return (INT_PTR)Plugin_OnNavItemDelete(hItem);
case ML_MSG_NAVIGATION_ONCUSTOMDRAW: return (INT_PTR)Plugin_OnNavCustomDraw(hItem, (NAVITEMDRAW*)param2, (LPARAM)param3);
case ML_MSG_NAVIGATION_ONHITTEST: return (INT_PTR)Plugin_OnNavHitTest(hItem, (NAVHITTEST*)param2, (LPARAM)param3);
case ML_MSG_NAVIGATION_ONSETCURSOR: return (INT_PTR)Plugin_OnNavSetCursor(hItem, (LPARAM)param3);
case ML_MSG_NAVIGATION_CONTEXTMENU:
{
DRIVE *pDrive;
if (hniMain && (hItem == hniMain))
return Root_OnContextMenu(hItem, (HWND)param2, MAKEPOINTS(param3));
//Plugin Item
pDrive = Plugin_GetDriveFromNavItem(hItem);
if (pDrive)
return Plugin_OnContextMenu(hItem, (HWND)param2, MAKEPOINTS(param3), pDrive->cLetter);
return 0;
}
case ML_MSG_TREE_ONCLICK: return (INT_PTR)Plugin_OnNavItemClick(hItem, (UINT)param2, (HWND)param3);
case ML_MSG_CONFIG: return (INT_PTR)Plugin_OnConfig();
case ML_MSG_MLVISIBLE: Plugin_OnMLVisible((BOOL)param1); break;
case ML_MSG_NOTOKTOQUIT: if (!Plugin_QueryOkToQuit()) { return TRUE; } break;
}
return 0;
}
/////////////////////////////////////////////////////////////////////////////////
extern "C" winampMediaLibraryPlugin plugin =
{
MLHDR_VER,
"nullsoft(ml_disc.dll)",
Init,
Quit,
pluginMessageProc,
0,
0,
0,
};
extern "C" __declspec(dllexport) winampMediaLibraryPlugin *winampGetMediaLibraryPlugin()
{
return &plugin;
}