519 lines
16 KiB
C++
519 lines
16 KiB
C++
|
//#define PLUGIN_NAME //"Nullsoft Global Hotkeys"
|
||
|
#define PLUGIN_VERSION L"1.97"
|
||
|
|
||
|
// do this so we can get WM_APPCOMMAND support (needed in 1.6+)
|
||
|
// (have to targetting xp sp1+ so we get the specific play & pause messages
|
||
|
// though it'll work fine with win2k+ as those messages will never appear)
|
||
|
//////#define _WIN32_WINNT 0x0501
|
||
|
#include "gen_hotkeys.h"
|
||
|
#include "ConfigDlg.h"
|
||
|
#include "HotKey.h"
|
||
|
#include "WACommands.h"
|
||
|
#include <api/service/waServiceFactory.h>
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
// Globals
|
||
|
///////////////////////////////////////////////////////////
|
||
|
|
||
|
// The global plugin instance
|
||
|
winampGeneralPurposePlugin psPlugin =
|
||
|
{
|
||
|
GPPHDR_VER_U,
|
||
|
"nullsoft(gen_hotkeys.dll)",
|
||
|
pluginInit,
|
||
|
pluginConfig,
|
||
|
hotkeysClear
|
||
|
};
|
||
|
// Winamp's window procdure
|
||
|
WNDPROC lpWndProcOld = NULL;
|
||
|
static int winampIsUnicode=false;
|
||
|
static int appcommand=false;
|
||
|
// hotkeys
|
||
|
HOTKEY *g_hotkeys = NULL;
|
||
|
DWORD g_dwHotkeys = 0;
|
||
|
// mutex to prevent two gen_hotkeys
|
||
|
HANDLE g_hMutex = NULL;
|
||
|
LPARAM uShellHook = NULL;
|
||
|
|
||
|
// wasabi based services for localisation support
|
||
|
api_service *WASABI_API_SVC = 0;
|
||
|
api_application *WASABI_API_APP = NULL;
|
||
|
api_language *WASABI_API_LNG = 0;
|
||
|
HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
|
||
|
|
||
|
static prefsDlgRecW g_prefsItem = {0};
|
||
|
static wchar_t g_titlestr[128];
|
||
|
wchar_t *g_iniFile = 0;
|
||
|
|
||
|
// don't forget to set DEFHKDS_NUM if you change this
|
||
|
HOTKEY_DATA g_defhkds[] = {
|
||
|
{MAKEWORD(VK_INSERT, HOTKEYF_ALT | HOTKEYF_CONTROL | HOTKEYF_EXT), -1, L"ghkdc play"},
|
||
|
{MAKEWORD(VK_HOME, HOTKEYF_ALT | HOTKEYF_CONTROL | HOTKEYF_EXT), -1, L"ghkdc pause"},
|
||
|
{MAKEWORD(VK_END, HOTKEYF_ALT | HOTKEYF_CONTROL | HOTKEYF_EXT), -1, L"ghkdc stop"},
|
||
|
{MAKEWORD(VK_PRIOR, HOTKEYF_ALT | HOTKEYF_CONTROL | HOTKEYF_EXT), -1, L"ghkdc prev"},
|
||
|
{MAKEWORD(VK_NEXT, HOTKEYF_ALT | HOTKEYF_CONTROL | HOTKEYF_EXT), -1, L"ghkdc next"},
|
||
|
{MAKEWORD(VK_UP, HOTKEYF_ALT | HOTKEYF_CONTROL | HOTKEYF_EXT), -1, L"ghkdc vup"},
|
||
|
{MAKEWORD(VK_DOWN, HOTKEYF_ALT | HOTKEYF_CONTROL | HOTKEYF_EXT), -1, L"ghkdc vdown"},
|
||
|
{MAKEWORD(VK_RIGHT, HOTKEYF_ALT | HOTKEYF_CONTROL | HOTKEYF_EXT), -1, L"ghkdc forward"},
|
||
|
{MAKEWORD(VK_LEFT, HOTKEYF_ALT | HOTKEYF_CONTROL | HOTKEYF_EXT), -1, L"ghkdc rewind"},
|
||
|
{MAKEWORD('J', HOTKEYF_ALT | HOTKEYF_CONTROL | HOTKEYF_EXT), -1, L"ghkdc jump"},
|
||
|
{MAKEWORD('L', HOTKEYF_ALT | HOTKEYF_CONTROL | HOTKEYF_EXT), -1, L"ghkdc file"},
|
||
|
//multimedia keyboard stuff
|
||
|
{2226, -1, L"ghkdc stop"},
|
||
|
{2227, -1, L"ghkdc play/pause"},
|
||
|
{2225, -1, L"ghkdc prev"},
|
||
|
{2224, -1, L"ghkdc next"},
|
||
|
};
|
||
|
|
||
|
#define TIMER_ID 0x8855
|
||
|
|
||
|
static int m_genhotkeys_add_ipc;
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
// DLL entry function
|
||
|
///////////////////////////////////////////////////////////
|
||
|
|
||
|
#ifndef _DEBUG
|
||
|
BOOL WINAPI _DllMainCRTStartup(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
|
||
|
{
|
||
|
DisableThreadLibraryCalls(hInst);
|
||
|
return TRUE;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
// Plugin functions
|
||
|
///////////////////////////////////////////////////////////
|
||
|
|
||
|
int pluginInit()
|
||
|
{
|
||
|
RegisterShellHookWindow(psPlugin.hwndParent);
|
||
|
uShellHook = RegisterWindowMessage(TEXT("SHELLHOOK"));
|
||
|
|
||
|
g_iniFile = (wchar_t*)SendMessage(psPlugin.hwndParent, WM_WA_IPC, 0, IPC_GETINIFILEW);
|
||
|
|
||
|
// loader so that we can get the localisation service api for use
|
||
|
WASABI_API_SVC = (api_service*)SendMessage(psPlugin.hwndParent, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
|
||
|
if (WASABI_API_SVC == (api_service*)1 ||
|
||
|
NULL == WASABI_API_SVC)
|
||
|
{
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(applicationApiServiceGuid);
|
||
|
if (sf) WASABI_API_APP = reinterpret_cast<api_application*>(sf->getInterface());
|
||
|
|
||
|
sf = WASABI_API_SVC->service_getServiceByGuid(languageApiGUID);
|
||
|
if (sf) WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());
|
||
|
|
||
|
// need to have this initialised before we try to do anything with localisation features
|
||
|
WASABI_API_START_LANG(psPlugin.hDllInstance,GenHotkeysLangGUID);
|
||
|
|
||
|
m_genhotkeys_add_ipc = (int)SendMessage( psPlugin.hwndParent, WM_WA_IPC, (WPARAM) &"GenHotkeysAdd", IPC_REGISTER_WINAMP_IPCMESSAGE);
|
||
|
|
||
|
static wchar_t szDescription[256];
|
||
|
StringCchPrintfW(szDescription, ARRAYSIZE(szDescription),
|
||
|
WASABI_API_LNGSTRINGW(IDS_NULLSOFT_GLOBAL_HOTKEYS), PLUGIN_VERSION);
|
||
|
psPlugin.description = (char*)szDescription;
|
||
|
|
||
|
appcommand = GetPrivateProfileIntW(L"gen_hotkeys", L"appcommand", 0, g_iniFile);
|
||
|
|
||
|
// Save Winamp's window procedure
|
||
|
winampIsUnicode = IsWindowUnicode(psPlugin.hwndParent);
|
||
|
lpWndProcOld = (WNDPROC)(LONG_PTR)GetWindowLongPtr(psPlugin.hwndParent, GWLP_WNDPROC);
|
||
|
if (winampIsUnicode)
|
||
|
SetWindowLongPtrW(psPlugin.hwndParent, GWLP_WNDPROC, (LONGX86)(LONG_PTR)WndProc);
|
||
|
else
|
||
|
SetWindowLongPtrA(psPlugin.hwndParent, GWLP_WNDPROC, (LONGX86)(LONG_PTR)WndProc);
|
||
|
|
||
|
InitCommands();
|
||
|
|
||
|
SetTimer(psPlugin.hwndParent, TIMER_ID, 10, NULL); //call hotkeysInit() when all plugins are loaded
|
||
|
|
||
|
//register prefs screen
|
||
|
g_prefsItem.dlgID = IDD_CONFIG;
|
||
|
g_prefsItem.name = WASABI_API_LNGSTRINGW_BUF(IDS_GHK_TITLE_STR,g_titlestr,128);
|
||
|
g_prefsItem.proc = ConfigProc;
|
||
|
g_prefsItem.hInst = WASABI_API_LNG_HINST;
|
||
|
// delay the adding of this
|
||
|
// for some reason when changing a lang pack it can cause the WM_DESTROY of ConfigProc
|
||
|
// to be called which completely messes up the ghk list and so can wipe it :(
|
||
|
SendMessage(psPlugin.hwndParent, WM_WA_IPC, (WPARAM) &g_prefsItem, IPC_ADD_PREFS_DLGW);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int hotkeysLoad(HOTKEY_DATA *hkds, DWORD num, int do_register, int verbose /*=1*/)
|
||
|
{
|
||
|
unsigned int uFailed = 0;
|
||
|
|
||
|
delete [] g_hotkeys;
|
||
|
g_hotkeys = NULL;
|
||
|
|
||
|
if (num)
|
||
|
{
|
||
|
g_hotkeys = new HOTKEY[num];
|
||
|
memset(g_hotkeys, 0, num * sizeof(HOTKEY));
|
||
|
}
|
||
|
if (!g_hotkeys)
|
||
|
{
|
||
|
g_dwHotkeys = 0;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
g_dwHotkeys = num;
|
||
|
|
||
|
wchar_t moreStr[64] = {0};
|
||
|
WASABI_API_LNGSTRINGW_BUF(IDS_GHK_HOTKEY_REG_FAILED_MORE,moreStr,64);
|
||
|
size_t bufLen = 256 + wcslen(moreStr) + 1;
|
||
|
wchar_t* szFailed = (wchar_t*)malloc(bufLen*sizeof(wchar_t));
|
||
|
WASABI_API_LNGSTRINGW_BUF(IDS_GHK_HOTKEY_REG_FAILED,szFailed,bufLen);
|
||
|
DWORD dwLeft = 256 - lstrlenW(szFailed);
|
||
|
DWORD dwFailedWithNoMsg = 0;
|
||
|
|
||
|
for (DWORD i = 0; i < num; i++)
|
||
|
{
|
||
|
g_hotkeys[i].hkd = hkds[i];
|
||
|
|
||
|
if (g_hotkeys[i].hkd.iCommand < 0)
|
||
|
// action not loaded yet for this hotkey
|
||
|
continue;
|
||
|
|
||
|
if (do_register && RegisterHotkey(g_hotkeys + i))
|
||
|
{
|
||
|
if (verbose && dwLeft)
|
||
|
{
|
||
|
wchar_t szTemp[1024] = {0};
|
||
|
bool unicode = 0;
|
||
|
char* name = GetCommandName(g_hotkeys[i].hkd.iCommand, &unicode);
|
||
|
StringCchPrintfW(szTemp, 1024, (unicode?L"\n\t%s":L"\n\t%S"), name);
|
||
|
DWORD dwLen = lstrlenW(szTemp);
|
||
|
if (dwLen < dwLeft)
|
||
|
{
|
||
|
StringCchCatW(szFailed, bufLen, szTemp);
|
||
|
dwLeft -= dwLen;
|
||
|
}
|
||
|
else
|
||
|
dwFailedWithNoMsg++;
|
||
|
}
|
||
|
|
||
|
g_hotkeys[i].failed = TRUE;
|
||
|
uFailed++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (verbose && uFailed)
|
||
|
{
|
||
|
if (dwFailedWithNoMsg)
|
||
|
StringCchCatW(szFailed, bufLen, moreStr);
|
||
|
HWND parent = (HWND)SendMessage(psPlugin.hwndParent, WM_WA_IPC, 0, IPC_GETDIALOGBOXPARENT);
|
||
|
if (parent == 0 || parent == (HWND)1)
|
||
|
parent=psPlugin.hwndParent;
|
||
|
|
||
|
MessageBoxW(parent, szFailed, g_titlestr, MB_OK | MB_ICONSTOP | MB_TOPMOST);
|
||
|
}
|
||
|
free(szFailed);
|
||
|
|
||
|
return uFailed;
|
||
|
}
|
||
|
|
||
|
static volatile LONG initted=0;
|
||
|
void hotkeysInit()
|
||
|
{
|
||
|
if (initted)
|
||
|
return;
|
||
|
initted=1;
|
||
|
|
||
|
int enabled = GetPrivateProfileIntW(L"gen_hotkeys", L"enabled", 0, g_iniFile);
|
||
|
|
||
|
// base the mutex on the current winamp install
|
||
|
// (makes it work better with mutliple winamp installs otherwise the older
|
||
|
// "Winamp - gen_hotkeys.dll ^&*#@" mutex prevents different hotkeys from
|
||
|
// being initialised between the different installs without going to prefs)
|
||
|
char mutexStr[MAX_PATH] = {0}, ghkFilename[MAX_PATH] = {0};
|
||
|
GetModuleFileName(psPlugin.hDllInstance, ghkFilename, MAX_PATH);
|
||
|
StringCchPrintf(mutexStr, MAX_PATH, "Winamp - %s ^&*#@", ghkFilename);
|
||
|
g_hMutex = CreateMutex(0, TRUE, mutexStr);
|
||
|
if (GetLastError() == ERROR_ALREADY_EXISTS)
|
||
|
enabled = 0;
|
||
|
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < DEFHKDS_NUM; i++)
|
||
|
{
|
||
|
g_defhkds[i].iCommand = GetCommandIdx(g_defhkds[i].szCommand);
|
||
|
g_defhkds[i].szCommand = 0;
|
||
|
}
|
||
|
|
||
|
int l = GetPrivateProfileIntW(L"gen_hotkeys", L"nbkeys", -1, g_iniFile);
|
||
|
int ver = GetPrivateProfileIntW(L"gen_hotkeys", L"version", 1, g_iniFile);
|
||
|
if (l != -1)
|
||
|
{
|
||
|
if (ver == 2)
|
||
|
{
|
||
|
HOTKEY_DATA *hkds = new HOTKEY_DATA[l]; // TODO: could alloca this
|
||
|
if (hkds)
|
||
|
{
|
||
|
for (i = 0; i < l; i++)
|
||
|
{
|
||
|
wchar_t tmp[1024] = {0}, action[1024] = {0};
|
||
|
StringCchPrintfW(tmp, 1024, L"action%d", i);
|
||
|
GetPrivateProfileStringW(L"gen_hotkeys", tmp, L"", action, 1024, g_iniFile);
|
||
|
StringCchPrintfW(tmp, 1024, L"hotkey%d", i);
|
||
|
int hotkey = GetPrivateProfileIntW(L"gen_hotkeys", tmp, 0, g_iniFile);
|
||
|
|
||
|
hkds[i].dwHotKey = hotkey;
|
||
|
|
||
|
hkds[i].iCommand = GetCommandIdx(action);
|
||
|
if (hkds[i].iCommand >= 0)
|
||
|
hkds[i].szCommand = NULL;
|
||
|
else
|
||
|
hkds[i].szCommand = _wcsdup(action);
|
||
|
}
|
||
|
|
||
|
hotkeysLoad(hkds, l, enabled, 0);
|
||
|
delete [] hkds;
|
||
|
}
|
||
|
}
|
||
|
// legacy support
|
||
|
else if (ver == 1)
|
||
|
{
|
||
|
HOTKEY_DATA *hkds = new HOTKEY_DATA[l]; // TODO: could alloca this
|
||
|
if (hkds)
|
||
|
{
|
||
|
int nb = 0;
|
||
|
for (i = 0;i < l;i++)
|
||
|
{
|
||
|
wchar_t tmp[512] = {0};
|
||
|
StringCchPrintfW(tmp, 512, L"msg%d", i);
|
||
|
unsigned int msg = GetPrivateProfileIntW(L"gen_hotkeys", tmp, 0, g_iniFile);
|
||
|
if (msg)
|
||
|
{
|
||
|
StringCchPrintfW(tmp, 512, L"wparam%d", i);
|
||
|
WPARAM wparam = GetPrivateProfileIntW(L"gen_hotkeys", tmp, 0, g_iniFile);
|
||
|
StringCchPrintfW(tmp, 512, L"lparam%d", i);
|
||
|
LPARAM lparam = GetPrivateProfileIntW(L"gen_hotkeys", tmp, 0, g_iniFile);
|
||
|
for (int j = 0;WACommands[j].name;j++)
|
||
|
{
|
||
|
if (WACommands[j].uMsg == msg && WACommands[j].wParam == wparam && WACommands[j].lParam == lparam)
|
||
|
{
|
||
|
StringCchPrintfW(tmp, 512, L"hotkey%d", i);
|
||
|
int hotkey = GetPrivateProfileIntW(L"gen_hotkeys", tmp, 0, g_iniFile);
|
||
|
hkds[nb].dwHotKey = hotkey;
|
||
|
hkds[nb].iCommand = j;
|
||
|
hkds[nb].szCommand = NULL;
|
||
|
nb++;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
hotkeysLoad(hkds, nb, enabled, 0);
|
||
|
delete [] hkds;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// load defaults
|
||
|
hotkeysLoad(g_defhkds, DEFHKDS_NUM, enabled, 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void writePrivateProfileInt(wchar_t *section, int val)
|
||
|
{
|
||
|
wchar_t s[32] = {0};
|
||
|
StringCchPrintfW(s, 32, L"%d", val);
|
||
|
WritePrivateProfileStringW(L"gen_hotkeys", section, s, g_iniFile);
|
||
|
}
|
||
|
|
||
|
void hotkeysSave(HOTKEY_DATA *hkds, DWORD num)
|
||
|
{
|
||
|
int enabled = GetPrivateProfileIntW(L"gen_hotkeys", L"enabled", 0, g_iniFile);
|
||
|
appcommand = GetPrivateProfileIntW(L"gen_hotkeys", L"appcommand", 0, g_iniFile);
|
||
|
WritePrivateProfileStringW(L"gen_hotkeys", NULL, NULL, g_iniFile);
|
||
|
writePrivateProfileInt(L"nbkeys", num);
|
||
|
writePrivateProfileInt(L"version", 2);
|
||
|
writePrivateProfileInt(L"enabled", enabled);
|
||
|
writePrivateProfileInt(L"appcommand", appcommand);
|
||
|
if (!hkds || !num)
|
||
|
{
|
||
|
return ;
|
||
|
}
|
||
|
for (size_t i = 0; i < num; i++)
|
||
|
{
|
||
|
wchar_t tmp[1024] = {0};
|
||
|
StringCchPrintfW(tmp, 1024, L"action%d", i);
|
||
|
if (hkds[i].iCommand >= 0)
|
||
|
WritePrivateProfileStringW(L"gen_hotkeys", tmp, GetCommandId(hkds[i].iCommand), g_iniFile);
|
||
|
else if (hkds[i].szCommand)
|
||
|
WritePrivateProfileStringW(L"gen_hotkeys", tmp, hkds[i].szCommand, g_iniFile);
|
||
|
StringCchPrintfW(tmp, 1024, L"hotkey%d", i);
|
||
|
writePrivateProfileInt(tmp, hkds[i].dwHotKey);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void pluginConfig()
|
||
|
{
|
||
|
SendMessage(psPlugin.hwndParent, WM_WA_IPC, (WPARAM) &g_prefsItem, IPC_OPENPREFSTOPAGE);
|
||
|
}
|
||
|
|
||
|
void hotkeysClear()
|
||
|
{
|
||
|
DeregisterShellHookWindow(psPlugin.hwndParent);
|
||
|
|
||
|
if (!g_hotkeys)
|
||
|
return;
|
||
|
|
||
|
// Unregister all of the hot keys, and delete all of our unique hot key identifiers
|
||
|
for (DWORD i = 0; i < g_dwHotkeys; i++)
|
||
|
{
|
||
|
UnregisterHotkey(g_hotkeys + i);
|
||
|
}
|
||
|
delete [] g_hotkeys;
|
||
|
g_hotkeys = NULL;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
// Plugin export function
|
||
|
///////////////////////////////////////////////////////////
|
||
|
|
||
|
extern "C" __declspec(dllexport) winampGeneralPurposePlugin * winampGetGeneralPurposePlugin() { return &psPlugin; }
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
// DLL Windows message handling procedure
|
||
|
///////////////////////////////////////////////////////////
|
||
|
|
||
|
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
if(message == uShellHook && appcommand && wParam == HSHELL_APPCOMMAND)
|
||
|
{
|
||
|
// WM_APPCOMMAND info:: http://msdn2.microsoft.com/en-us/library/ms646275.aspx
|
||
|
int cmd = GET_APPCOMMAND_LPARAM(lParam);
|
||
|
switch (cmd)
|
||
|
{
|
||
|
case APPCOMMAND_MEDIA_PLAY_PAUSE:
|
||
|
{
|
||
|
int playing = (int)SendMessage(psPlugin.hwndParent, WM_WA_IPC, 0, IPC_ISPLAYING);
|
||
|
SendMessage(hwnd, WM_COMMAND, MAKEWPARAM((playing ? WINAMP_BUTTON3 : WINAMP_BUTTON2),0), 0);
|
||
|
}
|
||
|
break;
|
||
|
case APPCOMMAND_MEDIA_NEXTTRACK:
|
||
|
SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(WINAMP_BUTTON5,0), 0);
|
||
|
return TRUE;
|
||
|
case APPCOMMAND_MEDIA_PREVIOUSTRACK:
|
||
|
SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(WINAMP_BUTTON1,0), 0);
|
||
|
return TRUE;
|
||
|
case APPCOMMAND_MEDIA_STOP:
|
||
|
SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(WINAMP_BUTTON4,0), 0);
|
||
|
return TRUE;
|
||
|
case APPCOMMAND_VOLUME_DOWN:
|
||
|
SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(WINAMP_VOLUMEDOWN,0), 0);
|
||
|
return TRUE;
|
||
|
case APPCOMMAND_VOLUME_UP:
|
||
|
SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(WINAMP_VOLUMEUP,0), 0);
|
||
|
return TRUE;
|
||
|
/*case APPCOMMAND_VOLUME_MUTE:
|
||
|
return TRUE;*/
|
||
|
|
||
|
// info on play/pause (xp sp1+) commands:: http://msdn2.microsoft.com/en-us/library/bb417078.aspx
|
||
|
case APPCOMMAND_MEDIA_PLAY:
|
||
|
{
|
||
|
int playing = (int)SendMessage(psPlugin.hwndParent, WM_WA_IPC, 0, IPC_ISPLAYING);
|
||
|
// play if not currently playing/are stopped
|
||
|
if(!playing) SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(WINAMP_BUTTON2,0), 0);
|
||
|
// if paused then start playing again
|
||
|
else if(playing == 3) SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(WINAMP_BUTTON3,0), 0);
|
||
|
// otherwise do nothing if playing already (playing == 1)
|
||
|
}
|
||
|
return TRUE;
|
||
|
case APPCOMMAND_MEDIA_PAUSE:
|
||
|
{
|
||
|
int playing = (int)SendMessage(psPlugin.hwndParent, WM_WA_IPC, 0, IPC_ISPLAYING);
|
||
|
// if playing then we pause
|
||
|
if(playing == 1) SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(WINAMP_BUTTON3,0), 0);
|
||
|
// otherwise do nothing if already stopped or paused (playing == 0 || playing == 3)
|
||
|
}
|
||
|
return TRUE;
|
||
|
case APPCOMMAND_MEDIA_FAST_FORWARD:
|
||
|
SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(WINAMP_FFWD5S,0), 0);
|
||
|
return TRUE;
|
||
|
case APPCOMMAND_MEDIA_REWIND:
|
||
|
SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(WINAMP_REW5S,0), 0);
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
switch (message)
|
||
|
{
|
||
|
case WM_TIMER:
|
||
|
if (wParam == TIMER_ID)
|
||
|
{
|
||
|
KillTimer(hwnd, TIMER_ID);
|
||
|
hotkeysInit();
|
||
|
return 0;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_HOTKEY:
|
||
|
if (g_hotkeys)
|
||
|
{
|
||
|
for (unsigned int i = 0; i < g_dwHotkeys; i++)
|
||
|
{
|
||
|
if (g_hotkeys[i].atom == wParam)
|
||
|
{
|
||
|
DoCommand(g_hotkeys[i].hkd.iCommand);
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_WA_IPC:
|
||
|
if (lParam == m_genhotkeys_add_ipc && m_genhotkeys_add_ipc > 65536)
|
||
|
{
|
||
|
int cmd = AddCommand((genHotkeysAddStruct *) wParam);
|
||
|
if (cmd > 0)
|
||
|
{
|
||
|
for (unsigned int i = 0; i < g_dwHotkeys; i++)
|
||
|
{
|
||
|
if (g_hotkeys[i].hkd.iCommand < 0
|
||
|
&& g_hotkeys[i].hkd.szCommand
|
||
|
&& !lstrcmpiW(g_hotkeys[i].hkd.szCommand, GetCommandId(cmd)))
|
||
|
{
|
||
|
g_hotkeys[i].hkd.iCommand = cmd;
|
||
|
free(g_hotkeys[i].hkd.szCommand);
|
||
|
g_hotkeys[i].hkd.szCommand = NULL;
|
||
|
int enabled = GetPrivateProfileIntW(L"gen_hotkeys", L"enabled", 0, g_iniFile);
|
||
|
if (enabled) RegisterHotkey(&g_hotkeys[i]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return cmd;
|
||
|
}
|
||
|
|
||
|
// handles the weird inc/dec current rating (since it's locked to 0-5
|
||
|
// we can just wrap around and correct the real value passed on to the api)
|
||
|
else if(lParam == IPC_SETRATING && (wParam == -1 || wParam == 6))
|
||
|
{
|
||
|
LRESULT curRating = SendMessage(hwnd, WM_WA_IPC,
|
||
|
SendMessage(hwnd, WM_WA_IPC, 0, IPC_GETLISTPOS),
|
||
|
IPC_GETRATING);
|
||
|
if(wParam == 6) // increment
|
||
|
{
|
||
|
wParam = curRating+1;
|
||
|
}
|
||
|
else // decrement
|
||
|
{
|
||
|
wParam = curRating-1;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// If we don't know how to handle this message, let WinAMP do it for us
|
||
|
if (winampIsUnicode)
|
||
|
return CallWindowProcW(lpWndProcOld, hwnd, message, wParam, lParam);
|
||
|
else
|
||
|
return CallWindowProcA(lpWndProcOld, hwnd, message, wParam, lParam);
|
||
|
}
|