diff options
Diffstat (limited to 'Src/Plugins/Library/ml_disc/main.cpp')
-rw-r--r-- | Src/Plugins/Library/ml_disc/main.cpp | 1273 |
1 files changed, 1273 insertions, 0 deletions
diff --git a/Src/Plugins/Library/ml_disc/main.cpp b/Src/Plugins/Library/ml_disc/main.cpp new file mode 100644 index 00000000..6f39f2f3 --- /dev/null +++ b/Src/Plugins/Library/ml_disc/main.cpp @@ -0,0 +1,1273 @@ +#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; +}
\ No newline at end of file |