diff options
Diffstat (limited to 'Src/Plugins/General/gen_hotkeys')
22 files changed, 2871 insertions, 0 deletions
diff --git a/Src/Plugins/General/gen_hotkeys/Configdlg.cpp b/Src/Plugins/General/gen_hotkeys/Configdlg.cpp new file mode 100644 index 00000000..d0572efe --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/Configdlg.cpp @@ -0,0 +1,471 @@ +#include "ConfigDlg.h" +#include "gen_hotkeys.h" +#include "accelBlock.h" + +#define ListView_InsertColumnW(hwnd, iCol, pcol) \ + (int)SNDMSG((hwnd), LVM_INSERTCOLUMNW, (WPARAM)(int)(iCol), (LPARAM)(const LV_COLUMNW *)(pcol)) + +#define ListView_InsertItemW(hwnd, pitem) \ + (int)SNDMSG((hwnd), LVM_INSERTITEMW, 0, (LPARAM)(const LV_ITEMW *)(pitem)) + +#define ListView_SetItemTextW(hwndLV, i, iSubItem_, pszText_) \ +{ LV_ITEMW _macro_lvi;\ + _macro_lvi.iSubItem = (iSubItem_);\ + _macro_lvi.pszText = (pszText_);\ + SNDMSG((hwndLV), LVM_SETITEMTEXTW, (WPARAM)(i), (LPARAM)(LV_ITEMW *)&_macro_lvi);\ +} + +#define ListView_SetItemW(hwnd, pitem) \ + (BOOL)SNDMSG((hwnd), LVM_SETITEMW, 0, (LPARAM)(LV_ITEMW *)(pitem)) + +void SetListItem(HWND hwHKList, HWND hwHK, HOTKEY_DATA *hk_data, int idx = -1, int failed = 0); + +static AcceleratorBlocker *pAccelBlock = NULL; +static bool changed = false; + +static int setCheckedStuff(HWND hwndDlg) +{ + int checked = SendMessage(GetDlgItem(hwndDlg, IDC_ENABLED), BM_GETCHECK, 0, 0) == BST_CHECKED; + EnableWindow(GetDlgItem(hwndDlg,IDC_HKLIST),checked); + EnableWindow(GetDlgItem(hwndDlg,IDC_COMBO),checked); + EnableWindow(GetDlgItem(hwndDlg,IDC_HOTKEY),checked); + EnableWindow(GetDlgItem(hwndDlg,IDC_ADD),checked); + if (!checked) + { + EnableWindow(GetDlgItem(hwndDlg,IDC_SAVE),0); + EnableWindow(GetDlgItem(hwndDlg,IDC_REMOVE),0); + } + EnableWindow(GetDlgItem(hwndDlg,IDC_DEFAULT),checked); + return checked; +} + +int ResizeComboBoxDropDown(HWND hwndDlg, UINT id, const char* str, int width){ + SIZE size = {0}; + HWND control = GetDlgItem(hwndDlg, id); + HDC hdc = GetDC(control); + // get and select parent dialog's font so that it'll calculate things correctly + HFONT font = (HFONT)SendMessage(hwndDlg,WM_GETFONT,0,0), oldfont = (HFONT)SelectObject(hdc,font); + GetTextExtentPoint32(hdc, str, lstrlen(str)+1, &size); + + int ret = width; + if(size.cx > width) + { + SendDlgItemMessageW(hwndDlg, id, CB_SETDROPPEDWIDTH, size.cx, 0); + ret = size.cx; + } + + SelectObject(hdc, oldfont); + ReleaseDC(control, hdc); + return ret; +} + +int ResizeComboBoxDropDownW(HWND hwndDlg, UINT id, const wchar_t *str, int width){ + SIZE size = {0}; + HWND control = GetDlgItem(hwndDlg, id); + HDC hdc = GetDC(control); + // get and select parent dialog's font so that it'll calculate things correctly + HFONT font = (HFONT)SendMessage(hwndDlg,WM_GETFONT,0,0), oldfont = (HFONT)SelectObject(hdc,font); + GetTextExtentPoint32W(hdc, str, (int)wcslen(str)+1, &size); + + int ret = width; + if(size.cx > width) + { + SendDlgItemMessageW(hwndDlg, id, CB_SETDROPPEDWIDTH, size.cx, 0); + ret = size.cx; + } + + SelectObject(hdc, oldfont); + ReleaseDC(control, hdc); + return ret; +} + +BOOL CALLBACK ConfigProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + HWND hwHKList = GetDlgItem(hwndDlg, IDC_HKLIST); + HWND hwCombo = GetDlgItem(hwndDlg, IDC_COMBO); + HWND hwHK = GetDlgItem(hwndDlg, IDC_HOTKEY); + + switch (uMsg) + { + case WM_INITDIALOG: + { + int colwidth1 = -1, colwidth2 = -1; + if (hwHKList && hwHK) + { + RECT r; + + SendMessage(hwHKList, WM_SETREDRAW, FALSE, 0); + ListView_SetExtendedListViewStyle(hwHKList, LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP); + + GetClientRect(hwHKList, &r); + + colwidth2 = GetPrivateProfileIntW(L"gen_hotkeys", L"col2", -1, g_iniFile); + LVCOLUMNW lc = {LVCF_TEXT | LVCF_WIDTH, 0, + (colwidth2==-1?((r.right / 2) - GetSystemMetrics(SM_CYHSCROLL)):colwidth2), + WASABI_API_LNGSTRINGW(IDS_GHK_HOTKEY_COLUMN), 0, 0 + }; + + ListView_InsertColumnW(hwHKList, 0, &lc); + + lc.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; + colwidth1 = GetPrivateProfileIntW(L"gen_hotkeys", L"col1", -1, g_iniFile); + lc.cx = (colwidth1==-1?(r.right - lc.cx - GetSystemMetrics(SM_CYHSCROLL)):colwidth1); + lc.pszText = WASABI_API_LNGSTRINGW(IDS_GHK_ACTION_COLUMN); + lc.iSubItem = 1; + + ListView_InsertColumnW(hwHKList, 0, &lc); + } + + changed = false; + SubclassEditBox(hwHK); + if (NULL != hwHK && NULL == pAccelBlock) + pAccelBlock = new AcceleratorBlocker(hwHK); + + HBITMAP hBitmap = LoadBitmap(psPlugin.hDllInstance, MAKEINTRESOURCE(IDB_LVSTATE)); + + HIMAGELIST hImageList = ImageList_Create(14, 14, ILC_COLOR8|ILC_MASK, 1, 0); + ImageList_AddMasked(hImageList, hBitmap, RGB(252, 254, 252)); + ListView_SetImageList(hwHKList, hImageList, LVSIL_STATE); + DeleteObject(hBitmap); + + ListView_SetItemCount(hwHKList, g_dwHotkeys); + + // We don't want our hot keys while in the config + for (size_t i = 0; i < g_dwHotkeys; i++) + { + SetLastError(0); + UnregisterHotkey(g_hotkeys + i); + SetListItem(hwHKList, hwHK, &g_hotkeys[i].hkd, -1, g_hotkeys[i].failed); + } + hotkeysClear(); + + if(colwidth1==-1) + ListView_SetColumnWidth(hwHKList, 0, LVSCW_AUTOSIZE); + if(colwidth2==-1) + ListView_SetColumnWidth(hwHKList, 1, LVSCW_AUTOSIZE); + + // clear + SendMessage(hwHK, wmHKCtlSet, 0, 0); + + ListView_SetItemState(hwHKList, -1, 0, LVIS_SELECTED); + + SendMessage(hwHKList, WM_SETREDRAW, TRUE, 0); + + int width = 0; + for (size_t i = 0; i < GetCommandsNum(); i++) + { + bool unicode = 0; + char *cmdname = GetCommandName((unsigned int)i, &unicode); + if (*cmdname) + { + LRESULT pos; + if (unicode) + { + pos = SendMessageW(hwCombo, CB_ADDSTRING, 0, (LPARAM) cmdname); + width = ResizeComboBoxDropDownW(hwndDlg, IDC_COMBO, (wchar_t*)cmdname, width); + } + else + { + pos = SendMessageA(hwCombo, CB_ADDSTRING, 0, (LPARAM) cmdname); + width = ResizeComboBoxDropDown(hwndDlg, IDC_COMBO, cmdname, width); + } + SendMessage(hwCombo, CB_SETITEMDATA, pos, i); + } + } + + // Set the enabled checkbox + CheckDlgButton(hwndDlg,IDC_ENABLED,GetPrivateProfileIntW(L"gen_hotkeys", L"enabled", 0, g_iniFile)); + CheckDlgButton(hwndDlg,IDC_ENABLED_WM_APPCOMMAND,GetPrivateProfileIntW(L"gen_hotkeys", L"appcommand", 0, g_iniFile)); + setCheckedStuff(hwndDlg); + + if (NULL != WASABI_API_APP) + WASABI_API_APP->DirectMouseWheel_EnableConvertToMouseWheel(hwHKList, TRUE); + + break; + } + + case WM_COMMAND: + { + // we don't want accelerator keys working when the hotkey window is focused + // that could be a problem if someone wants to bind Alt+D for example... + if (GetFocus() == hwHK) + break; + + switch (LOWORD(wParam)) + { + case IDC_ADD: + { + HOTKEY_DATA hkd; + DWORD dwHotKey = (unsigned long)SendMessage(hwHK, wmHKCtlGet, 0, 0); + UINT iCommand = (unsigned int)SendMessage(hwCombo, CB_GETITEMDATA, SendMessage(hwCombo, CB_GETCURSEL, 0, 0), 0); + + if (!dwHotKey || iCommand == CB_ERR) + break; + + hkd.dwHotKey = dwHotKey; + hkd.iCommand = iCommand; + + changed = true; + SetListItem(hwHKList, hwHK, &hkd); + break; + } + + case IDC_REMOVE: + { + int i = ListView_GetNextItem(hwHKList, -1, LVNI_SELECTED); + while (i != -1) + { + LVITEM lvi = {LVIF_PARAM, i}; + ListView_GetItem(hwHKList, &lvi); + HOTKEY_DATA *hkd = (HOTKEY_DATA *) lvi.lParam; + delete hkd; + + changed = true; + ListView_DeleteItem(hwHKList, i); + i = ListView_GetNextItem(hwHKList, -1, LVNI_SELECTED); + } + EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), 0); + break; + } + + case IDC_SAVE: + { + if (ListView_GetSelectedCount(hwHKList) != 1) + break; + + int iSel = ListView_GetNextItem(hwHKList, -1, LVNI_SELECTED); + + LVITEMW lvi = {LVIF_PARAM, iSel}; + ListView_GetItem(hwHKList, &lvi); + HOTKEY_DATA *hkd = (HOTKEY_DATA *) lvi.lParam; + if (hkd) + { + DWORD dwHotKey = (unsigned long)SendMessage(hwHK, wmHKCtlGet, 0, 0); + UINT iCommand = (unsigned int)SendMessage(hwCombo, CB_GETITEMDATA, SendMessage(hwCombo, CB_GETCURSEL, 0, 0), 0); + + if (!dwHotKey || iCommand == CB_ERR) + break; + + hkd->dwHotKey = dwHotKey; + hkd->iCommand = iCommand; + + changed = true; + SetListItem(hwHKList, hwHK, hkd, iSel); + } + break; + } + + case IDC_ENABLED: + if (setCheckedStuff(hwndDlg)) + { + DWORD dwSelected = ListView_GetSelectedCount(hwHKList); + EnableWindow(GetDlgItem(hwndDlg, IDC_SAVE), dwSelected == 1); + EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), dwSelected); + changed = true; + } + break; + + case IDC_DEFAULT: + { + DWORD i; + SendMessage(hwndDlg, WM_SETREDRAW, FALSE, 0); + + DWORD dwCount = (DWORD)ListView_GetItemCount(hwHKList); + if (dwCount) + { + for (i = 0; i < dwCount; i++) + { + LVITEM lvi = {LVIF_PARAM,(int)i}; + ListView_GetItem(hwHKList, &lvi); + HOTKEY_DATA *hkd = (HOTKEY_DATA *) lvi.lParam; + delete hkd; + } + } + + changed = true; + ListView_DeleteAllItems(hwHKList); + + for (i = 0; i < DEFHKDS_NUM; i++) + { + SetListItem(hwHKList, hwHK, g_defhkds + i); + } + + // restore the size of the columns on a reset as well + ListView_SetColumnWidth(hwHKList, 0, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwHKList, 1, LVSCW_AUTOSIZE); + + ListView_SetItemState(hwHKList, -1, 0, LVIS_SELECTED); + SendMessage(hwndDlg, WM_SETREDRAW, TRUE, 0); + InvalidateRect(hwndDlg, 0, 0); + break; + } + } + break; + } + + case WM_NOTIFY: + { + LPNMHDR nmhdr = (LPNMHDR) lParam; + if (nmhdr && nmhdr->idFrom == IDC_HKLIST) + { + if (nmhdr->code == LVN_ITEMCHANGED) + { + LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam; + DWORD dwSelected = ListView_GetSelectedCount(hwHKList); + EnableWindow(GetDlgItem(hwndDlg, IDC_SAVE), dwSelected == 1); + EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), dwSelected); + + SendMessage(hwHK, wmHKCtlSet, 0, 0); + SendMessage(hwCombo, CB_SETCURSEL, -1, 0); + + if (dwSelected == 1 && (pnmv->uNewState & LVIS_SELECTED)) + { + HOTKEY_DATA *hkd = (HOTKEY_DATA *) pnmv->lParam; + if (hkd) + { + SendMessage(hwHK, wmHKCtlSet, hkd->dwHotKey, 0); + bool unicode = 0; + char *cmd = GetCommandName(hkd->iCommand, &unicode); + if (*cmd) + { + if(unicode) SendMessageW(hwCombo, CB_SELECTSTRING, -1, (LPARAM) cmd); + else SendMessageA(hwCombo, CB_SELECTSTRING, -1, (LPARAM) cmd); + } + } + } + } + else if(nmhdr->code == LVN_KEYDOWN) + { + LPNMLVKEYDOWN pnmv = (LPNMLVKEYDOWN) lParam; + if(pnmv->wVKey == VK_DELETE) + { + changed = true; + SendMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(IDC_REMOVE,0),0); + } + else if(pnmv->wVKey == 'A' && GetAsyncKeyState(VK_CONTROL)) + { + for(int i = 0; i < ListView_GetItemCount(hwHKList); i++) + { + ListView_SetItemState(hwHKList,i,LVIS_SELECTED,LVIS_SELECTED); + } + } + } + } + } + break; + + case WM_DESTROY: + { + int checked = (SendMessage(GetDlgItem(hwndDlg, IDC_ENABLED), BM_GETCHECK, 0, 0) == BST_CHECKED); + writePrivateProfileInt(L"enabled", checked); + writePrivateProfileInt(L"appcommand", + (SendMessage(GetDlgItem(hwndDlg, IDC_ENABLED_WM_APPCOMMAND), BM_GETCHECK, 0, 0) == BST_CHECKED)); + hotkeysClear(); + + int iCount = ListView_GetItemCount(hwHKList); + HOTKEY_DATA *hkds = NULL; + if (iCount) + { + hkds = new HOTKEY_DATA[iCount]; // TODO: could alloca this + memset(hkds, 0, iCount * sizeof(HOTKEY_DATA)); + } + if (hkds || !iCount) + { + for (size_t i = 0; i < (unsigned int)iCount; i++) + { + LVITEM lvi = {LVIF_PARAM, (int)i}; + ListView_GetItem(hwHKList, &lvi); + HOTKEY_DATA *hkd = (HOTKEY_DATA *) lvi.lParam; + if (hkd) + { + hkds[i] = *hkd; + delete hkd; + } + } + + hotkeysLoad(hkds, iCount, checked); + if (changed) hotkeysSave(hkds, iCount); + delete [] hkds; + } + writePrivateProfileInt(L"col1", ListView_GetColumnWidth(hwHKList,0)); + writePrivateProfileInt(L"col2", ListView_GetColumnWidth(hwHKList,1)); + RegisterShellHookWindow(psPlugin.hwndParent); + if (NULL != pAccelBlock && hwHK == pAccelBlock->GetHwnd()) + { + delete(pAccelBlock); + pAccelBlock = NULL; + } + + if (NULL != WASABI_API_APP) + WASABI_API_APP->DirectMouseWheel_EnableConvertToMouseWheel(hwHKList, FALSE); + } + break; + } + return FALSE; +} + +// idx = -1 for insertion +void SetListItem(HWND hwHKList, HWND hwHK, HOTKEY_DATA *hk_data, int idx, int failed) +{ + wchar_t szHK[1024] = {L""}; + + SendMessage(hwHK, wmHKCtlSet, hk_data->dwHotKey, 0); + GetWindowTextW(hwHK, szHK, sizeof(szHK)); + + HOTKEY_DATA *hk_data_allocated = 0; + + if (idx < 0) + hk_data_allocated = new HOTKEY_DATA; + + if (idx >= 0 || hk_data_allocated) + { + if (idx < 0) + *hk_data_allocated = *hk_data; + + int pos = ListView_GetItemCount(hwHKList); + + if (idx >= 0) + pos = idx; + + // Add item to the list + bool unicode = 0; + LVITEM lvi = { + LVIF_PARAM | LVIF_TEXT | LVIF_STATE, + pos, + 0, + LVIS_SELECTED | INDEXTOSTATEIMAGEMASK(failed ? (UINT)1 : 0) | LVIS_FOCUSED, + LVIS_SELECTED | LVIS_STATEIMAGEMASK | LVIS_FOCUSED, + GetCommandName(hk_data->iCommand, &unicode), + 0, + 0, + (LPARAM) hk_data_allocated + }; + + char tmp[1024] = {0}; + + if (!lvi.pszText || !*lvi.pszText) + { + if (hk_data->szCommand) + { + StringCchPrintf(tmp, 1024, "[%s]", hk_data->szCommand); + lvi.pszText = tmp; + } + } + if (!lvi.pszText || !*lvi.pszText) + lvi.pszText = WASABI_API_LNGSTRING(IDS_GHK_ACTION_NOT_FOUND); + + if (idx >= 0) + { + lvi.mask ^= LVIF_PARAM; + if(unicode) ListView_SetItemW(hwHKList, &lvi); + else ListView_SetItem(hwHKList, &lvi); + } + else + { + ListView_SetItemState(hwHKList, -1, 0, LVIS_SELECTED | LVIS_FOCUSED); + if(unicode) ListView_InsertItemW(hwHKList, &lvi); + else ListView_InsertItem(hwHKList, &lvi); + } + ListView_SetItemTextW(hwHKList, pos, 1, szHK); + } +}
\ No newline at end of file diff --git a/Src/Plugins/General/gen_hotkeys/Configdlg.h b/Src/Plugins/General/gen_hotkeys/Configdlg.h new file mode 100644 index 00000000..a6fc772a --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/Configdlg.h @@ -0,0 +1,9 @@ +#ifndef __CONFIG_DIALOG_H__ +#define __CONFIG_DIALOG_H__ + +#include <windows.h> +#include "resource.h" + +BOOL CALLBACK ConfigProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam); + +#endif
\ No newline at end of file diff --git a/Src/Plugins/General/gen_hotkeys/HOTKEY.CPP b/Src/Plugins/General/gen_hotkeys/HOTKEY.CPP new file mode 100644 index 00000000..ad6144dc --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/HOTKEY.CPP @@ -0,0 +1,56 @@ +// HotKey.cpp: implementation of the CHotKey class. +// +////////////////////////////////////////////////////////////////////// + +#include "gen_hotkeys.h" +#include "HotKey.h" + +////////////////////////////////////////////////////////////////////// +// Registration / Unregstration +////////////////////////////////////////////////////////////////////// + +int RegisterHotkey(HOTKEY *hk) +{ + if (!hk) return 1; + + wchar_t atomName[1024] = {0}; + bool unicode = 0; + char* name = GetCommandName(hk->hkd.iCommand, &unicode); + StringCchPrintfW(atomName, 1024, (unicode?L"%s %X %X %X":L"%hs %X %X %X"), name, hk->hkd.dwHotKey, hk->hkd.iCommand, GetTickCount()); + hk->atom = GlobalAddAtomW(atomName); + if (!hk->atom) + return 1; + + return !RegisterHotKey(psPlugin.hwndParent, hk->atom, GetModKeys(hk->hkd.dwHotKey), LOBYTE(hk->hkd.dwHotKey)); +} + +void UnregisterHotkey(HOTKEY *hk) +{ + if (!hk || !hk->atom) + return; + + UnregisterHotKey(psPlugin.hwndParent, hk->atom); + GlobalDeleteAtom(hk->atom); + hk->atom = NULL; +} + +////////////////////////////////////////////////////////////////////// +// Set / Get +////////////////////////////////////////////////////////////////////// + +UINT GetModKeys(DWORD dwHotKey) +{ + UINT result = 0; + WORD wHotKey = HIBYTE(dwHotKey); + + if (wHotKey & HOTKEYF_ALT) + result |= MOD_ALT; + if (wHotKey & HOTKEYF_CONTROL) + result |= MOD_CONTROL; + if (wHotKey & HOTKEYF_WIN) + result |= MOD_WIN; + if (wHotKey & HOTKEYF_SHIFT) + result |= MOD_SHIFT; + + return result; +}
\ No newline at end of file diff --git a/Src/Plugins/General/gen_hotkeys/HOTKEY.H b/Src/Plugins/General/gen_hotkeys/HOTKEY.H new file mode 100644 index 00000000..88919dae --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/HOTKEY.H @@ -0,0 +1,32 @@ +// HotKey.h: interface for the CHotKey class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_HOTKEY_H__82523B98_0E49_4B2A_8206_A4262D29C3C8__INCLUDED_) +#define AFX_HOTKEY_H__82523B98_0E49_4B2A_8206_A4262D29C3C8__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "gen_hotkeys.h" + +struct HOTKEY_DATA +{ + DWORD dwHotKey; + int iCommand; + wchar_t *szCommand; +}; + +struct HOTKEY +{ + HOTKEY_DATA hkd; + ATOM atom; + BOOL failed; +}; + +int RegisterHotkey(HOTKEY *hk); +void UnregisterHotkey(HOTKEY *hk); +UINT GetModKeys(DWORD dwHotKey); + +#endif // !defined(AFX_HOTKEY_H__82523B98_0E49_4B2A_8206_A4262D29C3C8__INCLUDED_)
\ No newline at end of file diff --git a/Src/Plugins/General/gen_hotkeys/HotKeyCtl.cpp b/Src/Plugins/General/gen_hotkeys/HotKeyCtl.cpp new file mode 100644 index 00000000..61e1ea28 --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/HotKeyCtl.cpp @@ -0,0 +1,293 @@ +#include "HotKeyCtl.h" +#include "gen_hotkeys.h" + +struct HKWND_DATA +{ + WNDPROC lpfnEditWndProc; + DWORD dwScanCode; + WORD wMod; + DWORD dwHotKey; +}; + +LRESULT CALLBACK HotKeyWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + +#if(_WIN32_WINNT < 0x0500) +#define VK_BROWSER_BACK 0xA6 +#define VK_BROWSER_FORWARD 0xA7 +#define VK_BROWSER_REFRESH 0xA8 +#define VK_BROWSER_STOP 0xA9 +#define VK_BROWSER_SEARCH 0xAA +#define VK_BROWSER_FAVORITES 0xAB +#define VK_BROWSER_HOME 0xAC + +#define VK_VOLUME_MUTE 0xAD +#define VK_VOLUME_DOWN 0xAE +#define VK_VOLUME_UP 0xAF +#define VK_MEDIA_NEXT_TRACK 0xB0 +#define VK_MEDIA_PREV_TRACK 0xB1 +#define VK_MEDIA_STOP 0xB2 +#define VK_MEDIA_PLAY_PAUSE 0xB3 +#define VK_LAUNCH_MAIL 0xB4 +#define VK_LAUNCH_MEDIA_SELECT 0xB5 +#define VK_LAUNCH_APP1 0xB6 +#define VK_LAUNCH_APP2 0xB7 +#endif + +#ifndef VK_SLEEP +#define VK_SLEEP 0x5F +#endif + +UINT wmHKCtlSet; +UINT wmHKCtlGet; + +int SubclassEditBox(HWND hwEdit) +{ + if (!IsWindow(hwEdit)) + return 0; + + if (!wmHKCtlSet) + wmHKCtlSet = RegisterWindowMessage("gen_hotkeys HotKeyCTL set"); + + if (!wmHKCtlGet) + wmHKCtlGet = RegisterWindowMessage("gen_hotkeys HotKeyCTL get"); + + HKWND_DATA *hkwnd_data = new HKWND_DATA; + if (!hkwnd_data) + return 0; + + memset(hkwnd_data, 0, sizeof(HKWND_DATA)); + + hkwnd_data->lpfnEditWndProc = (WNDPROC)(LONG_PTR)SetWindowLongPtrW(hwEdit, GWLP_WNDPROC, (LONGX86)(LONG_PTR)HotKeyWndProc); + + SetWindowLongPtr(hwEdit, GWLP_USERDATA, (LONGX86)(LONG_PTR) hkwnd_data); + + return 1; +} + +void HotKeySetText(HWND hwHK, HKWND_DATA *hkwnd_data) +{ + if (!IsWindow(hwHK) || !hkwnd_data) + return; + + wchar_t szKeyName[1024] = L""; + wchar_t *p = szKeyName; + DWORD dwSize = sizeof(szKeyName); + DWORD dwLen = 0; + WORD wMod; + + if (hkwnd_data->dwHotKey) + wMod = HIBYTE(hkwnd_data->dwHotKey); + else + wMod = hkwnd_data->wMod; + + if(wMod & HOTKEYF_WIN) { + // GetKeyNameText gives us Left/Right Windows but RegisterHotKey doesn't seperate the two + //GetKeyNameText(MAKELPARAM(0, MapVirtualKey(VK_LWIN, 0)) | (1 << 24), p, dwSize); + // so we use just "Winkey" to avoid confusion + WASABI_API_LNGSTRINGW_BUF(IDS_GHK_WINKEY_STR,p,dwSize); + dwLen = lstrlenW(szKeyName); + StringCchCatW(p, dwSize, L" + "); + dwSize -= dwLen + 3; + p = szKeyName + dwLen + 3; + } + if(wMod & HOTKEYF_CONTROL) { + GetKeyNameTextW(MAKELONG(0, MapVirtualKey(VK_CONTROL, 0)), p, dwSize); + dwLen = lstrlenW(szKeyName); + StringCchCatW(p, dwSize, L" + "); + dwSize -= dwLen + 3; + p = szKeyName + dwLen + 3; + } + if(wMod & HOTKEYF_SHIFT) { + GetKeyNameTextW(MAKELONG(0, MapVirtualKey(VK_SHIFT, 0)), p, dwSize); + dwLen = lstrlenW(szKeyName); + StringCchCatW(p, dwSize, L" + "); + dwSize -= dwLen + 3; + p = szKeyName + dwLen + 3; + } + if(wMod & HOTKEYF_ALT) { + GetKeyNameTextW(MAKELONG(0, MapVirtualKey(VK_MENU, 0)), p, dwSize); + dwLen = lstrlenW(szKeyName); + StringCchCatW(p, dwSize, L" + "); + dwSize -= dwLen + 3; + p = szKeyName + dwLen + 3; + } + + if(hkwnd_data->dwHotKey) + { + switch (LOBYTE(hkwnd_data->dwHotKey)) + { + case VK_BROWSER_BACK: + WASABI_API_LNGSTRINGW_BUF(IDS_BROWSER_BACK,p,dwSize); + break; + case VK_BROWSER_FORWARD: + WASABI_API_LNGSTRINGW_BUF(IDS_BROWSER_FORWARD,p,dwSize); + break; + case VK_BROWSER_REFRESH: + WASABI_API_LNGSTRINGW_BUF(IDS_BROWSER_REFRESH,p,dwSize); + break; + case VK_BROWSER_STOP: + WASABI_API_LNGSTRINGW_BUF(IDS_BROWSER_STOP,p,dwSize); + break; + case VK_BROWSER_SEARCH: + WASABI_API_LNGSTRINGW_BUF(IDS_BROWSER_SEARCH,p,dwSize); + break; + case VK_BROWSER_FAVORITES: + WASABI_API_LNGSTRINGW_BUF(IDS_BROWSER_FAVOURITES,p,dwSize); + break; + case VK_BROWSER_HOME: + WASABI_API_LNGSTRINGW_BUF(IDS_BROWSER_HOME,p,dwSize); + break; + case VK_VOLUME_MUTE: + WASABI_API_LNGSTRINGW_BUF(IDS_VOLUME_MUTE,p,dwSize); + break; + case VK_VOLUME_DOWN: + WASABI_API_LNGSTRINGW_BUF(IDS_VOLUME_DOWN,p,dwSize); + break; + case VK_VOLUME_UP: + WASABI_API_LNGSTRINGW_BUF(IDS_VOLUME_UP,p,dwSize); + break; + case VK_MEDIA_NEXT_TRACK: + WASABI_API_LNGSTRINGW_BUF(IDS_NEXT_TRACK,p,dwSize); + break; + case VK_MEDIA_PREV_TRACK: + WASABI_API_LNGSTRINGW_BUF(IDS_PREVIOUS_TRACK,p,dwSize); + break; + case VK_MEDIA_STOP: + WASABI_API_LNGSTRINGW_BUF(IDS_STOP,p,dwSize); + break; + case VK_MEDIA_PLAY_PAUSE: + WASABI_API_LNGSTRINGW_BUF(IDS_PLAY_PAUSE,p,dwSize); + break; + case VK_LAUNCH_MAIL: + WASABI_API_LNGSTRINGW_BUF(IDS_LAUNCH_MAIL,p,dwSize); + break; + case VK_LAUNCH_MEDIA_SELECT: + WASABI_API_LNGSTRINGW_BUF(IDS_LAUNCH_MEDIA_SELECT,p,dwSize); + break; + case VK_LAUNCH_APP1: + WASABI_API_LNGSTRINGW_BUF(IDS_LAUCH_APP1,p,dwSize); + break; + case VK_LAUNCH_APP2: + WASABI_API_LNGSTRINGW_BUF(IDS_LAUCH_APP2,p,dwSize); + break; + case VK_SLEEP: + WASABI_API_LNGSTRINGW_BUF(IDS_SLEEP,p,dwSize); + break; + case VK_PAUSE: + WASABI_API_LNGSTRINGW_BUF(IDS_PAUSE,p,dwSize); + break; + default: + GetKeyNameTextW(hkwnd_data->dwScanCode, p, dwSize); + if (!*p) + StringCchPrintfW(p, 1024, L"0x%X", hkwnd_data->dwScanCode); + break; + } + } + else + szKeyName[dwLen] = 0; + + SetWindowTextW(hwHK, szKeyName); + + SendMessageW(hwHK, EM_SETSEL, lstrlenW(szKeyName), lstrlenW(szKeyName)); +} + +LRESULT CALLBACK HotKeyWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + HKWND_DATA *hkwnd_data = (HKWND_DATA *)(LONG_PTR)GetWindowLongPtr(hwnd, GWLP_USERDATA); + HKWND_DATA hkwnd_data_local; + + if (uMsg == wmHKCtlSet) + { + int extflag = 0; + if (HIBYTE(wParam) & HOTKEYF_EXT) + extflag = (1 << 24); + + hkwnd_data->dwHotKey = (unsigned long)wParam; + hkwnd_data->dwScanCode = MAKELPARAM(0, MapVirtualKey(LOBYTE(wParam), 0)) | extflag; + //hkwnd_data->wMod = HIBYTE(wParam); + HotKeySetText(hwnd, hkwnd_data); + return 0; + } + else if (uMsg == wmHKCtlGet) + { + return hkwnd_data->dwHotKey; + } + + switch (uMsg) + { + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + { + hkwnd_data->dwHotKey = 0; + + switch (wParam) + { + case VK_SHIFT: + hkwnd_data->wMod |= HOTKEYF_SHIFT; + break; + case VK_CONTROL: + hkwnd_data->wMod |= HOTKEYF_CONTROL; + break; + case VK_MENU: + hkwnd_data->wMod |= HOTKEYF_ALT; + break; + case VK_LWIN: + case VK_RWIN: + hkwnd_data->wMod |= HOTKEYF_WIN; + break; + default: + hkwnd_data->dwScanCode = (unsigned long)lParam; + if (lParam & (1 << 24)) // extended bit + hkwnd_data->wMod |= HOTKEYF_EXT; + else + hkwnd_data->wMod &= ~HOTKEYF_EXT; + hkwnd_data->dwHotKey = MAKEWORD(wParam, hkwnd_data->wMod); + break; + } + + HotKeySetText(hwnd, hkwnd_data); + return 1; + } + + case WM_KEYUP: + case WM_SYSKEYUP: + { + switch (wParam) + { + case VK_SHIFT: + hkwnd_data->wMod &= ~HOTKEYF_SHIFT; + break; + case VK_CONTROL: + hkwnd_data->wMod &= ~HOTKEYF_CONTROL; + break; + case VK_MENU: + hkwnd_data->wMod &= ~HOTKEYF_ALT; + break; + case VK_LWIN: + case VK_RWIN: + hkwnd_data->wMod &= ~HOTKEYF_WIN; + break; + } + + HotKeySetText(hwnd, hkwnd_data); + return 1; + } + + case WM_CHAR: + case WM_PASTE: + return 0; + + case WM_DESTROY: + if (hkwnd_data) + { + SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR) hkwnd_data->lpfnEditWndProc); + SetWindowLongPtr(hwnd, GWLP_USERDATA, 0); + hkwnd_data_local = *hkwnd_data; + delete hkwnd_data; + hkwnd_data = &hkwnd_data_local; + } + break; + } + + return CallWindowProc(hkwnd_data->lpfnEditWndProc, hwnd, uMsg, wParam, lParam); +}
\ No newline at end of file diff --git a/Src/Plugins/General/gen_hotkeys/HotKeyCtl.h b/Src/Plugins/General/gen_hotkeys/HotKeyCtl.h new file mode 100644 index 00000000..237aabba --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/HotKeyCtl.h @@ -0,0 +1,13 @@ +#ifndef ____HOTKEY_CTL___H____ +#define ____HOTKEY_CTL___H____ + +#include <windows.h> + +#define HOTKEYF_WIN 0x10 + +int SubclassEditBox(HWND hwEdit); + +extern UINT wmHKCtlSet; +extern UINT wmHKCtlGet; + +#endif//____HOTKEY_CTL___H____
\ No newline at end of file diff --git a/Src/Plugins/General/gen_hotkeys/RESOURCE.H b/Src/Plugins/General/gen_hotkeys/RESOURCE.H new file mode 100644 index 00000000..0cfe5975 --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/RESOURCE.H @@ -0,0 +1,116 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by gen_hotkeys.rc +// +#define IDS_GHK_TITLE_STR 0 +#define IDS_GHK_HOTKEY_REG_FAILED 1 +#define IDC_CANCEL 2 +#define IDS_GHK_HOTKEY_REG_FAILED_MORE 2 +#define IDS_GHK_ABOUT_TEXT 3 +#define IDS_GHK_HOTKEY_COLUMN 4 +#define IDS_GHK_ACTION_COLUMN 5 +#define IDS_GHK_ACTION_NOT_FOUND 6 +#define IDS_GHK_WINKEY_STR 7 +#define IDS_BROWSER_BACK 8 +#define IDS_BROWSER_FORWARD 9 +#define IDS_BROWSER_REFRESH 10 +#define IDS_BROWSER_STOP 11 +#define IDS_BROWSER_SEARCH 12 +#define IDS_BROWSER_FAVOURITES 13 +#define IDS_BROWSER_HOME 14 +#define IDS_VOLUME_MUTE 15 +#define IDS_VOLUME_DOWN 16 +#define IDS_VOLUME_UP 17 +#define IDS_NEXT_TRACK 18 +#define IDS_PREVIOUS_TRACK 19 +#define IDS_STOP 20 +#define IDS_PLAY_PAUSE 21 +#define IDS_LAUNCH_MAIL 22 +#define IDS_LAUNCH_MEDIA_SELECT 23 +#define IDS_LAUCH_APP1 24 +#define IDS_LAUCH_APP2 25 +#define IDS_SLEEP 26 +#define IDS_PLAYBACK__PLAY 32 +#define IDS_PLAYBACK__PAUSE 33 +#define IDS_PLAYBACK__STOP 34 +#define IDS_PLAYBACK__PREVIOUS_IN_PLAYLIST 35 +#define IDS_PLAYBACK__NEXT_IN_PLAYLIST 36 +#define IDS_PLAYBACK__VOLUME_UP 37 +#define IDS_PLAYBACK__VOLUME_DOWN 38 +#define IDS_PLAYBACK__FORWARD 39 +#define IDS_PLAYBACK__REWIND 40 +#define IDS_PLAYBACK__REPEAT_ON 41 +#define IDS_PLAYBACK__REPEAT_OFF 42 +#define IDS_UI__TOGGLE_EQ 43 +#define IDS_UI__TOGGLE_PLAYLIST 44 +#define IDS_UI__TOGGLE_AOT 45 +#define IDS_UI__ABOUT 46 +#define IDS_PLAYBACK__JUMP_TO_BOX 47 +#define IDS_PLAYBACK__OPEN_FILE_DIALOG 48 +#define IDS_PLAYBACK__OPEN_LOC_DIALOG 49 +#define IDS_PLAYBACK__OPEN_FOLDER_DIALOG 50 +#define IDS_GENERAL__QUIT 51 +#define IDS_UI__PREFERENCES 52 +#define IDS_GENERAL__COPY_TITLE 53 +#define IDS_GENERAL__COPY_FILE_PATH 54 +#define IDS_PLAYBACK__PLAY_PAUSE 55 +#define IDS_PLAYBACK__TOGGLE_REPEAT 56 +#define IDS_PLAYBACK__TOGGLE_SHUFFLE 57 +#define IDS_UI__TOGGLE_WINSHADE 58 +#define IDS_UI__TOGGLE_PLAYLIST_WINSHADE 59 +#define IDS_UI__TOGGLE_DOUBLESIZE 60 +#define IDS_UI__TOGGLE_MAIN_WINDOW 61 +#define IDS_UI__TOGGLE_MINIBROWSER 62 +#define IDS_VIS__PREFERENCES 63 +#define IDS_VIS__PLUGIN_PREFERENCES 64 +#define IDS_VIS_TOGGLE_VIS_ON_OFF 65 +#define IDS_UI__SELECT_SKIN 66 +#define IDS_PLAYBACK__STOP_WITH_FADEOUT 67 +#define IDS_PLAYBACK__STOP_AFTER_CURRENT 68 +#define IDS_PLAYBACK__START_OF_LIST 69 +#define IDS_PLAYBACK__END_OF_LIST 70 +#define IDS_UI__BRING_TO_FRONT_OR_HIDE 71 +#define IDS_RATING__5_STARS 72 +#define IDS_RATING__4_STARS 73 +#define IDS_RATING__3_STARS 74 +#define IDS_RATING__2_STARS 75 +#define IDS_RATING__1_STAR 76 +#define IDS_RATING__NO_RATING 77 +#define IDS_GENERAL__COPY_TITLEW 78 +#define IDS_GENERAL__COPY_FILE_PATHW 79 +#define IDS_RATING__INC 80 +#define IDS_RATING__DEC 81 +#define IDS_PAUSE 82 +#define IDS_VIS_NEXT_PRESET 83 +#define IDS_VIS_PREV_PRESET 84 +#define IDS_VIS_RAND_PRESET 85 +#define IDS_VIS_FULL_SCREEN 86 +#define IDS_VIS_CONFIG 87 +#define IDS_PLAYBACK__MANUAL_ADVANCE 87 +#define IDS_VIS_MENU 88 +#define IDS_GENERAL_FFOD 89 +#define IDS_PLAYBACK_EDIT_ID3 90 +#define IDD_CONFIG 101 +#define IDB_LOGO 103 +#define IDB_LVSTATE 104 +#define IDC_ENABLED 1006 +#define IDC_ENABLED_WM_APPCOMMAND 1007 +#define IDC_HOTKEY 1012 +#define IDC_HKLIST 1017 +#define IDC_COMBO 1018 +#define IDC_SAVE 1019 +#define IDC_ADD 1020 +#define IDC_REMOVE 1021 +#define IDC_DEFAULT 1022 +#define IDS_NULLSOFT_GLOBAL_HOTKEYS 65534 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 91 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1024 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Src/Plugins/General/gen_hotkeys/WINAMP.H b/Src/Plugins/General/gen_hotkeys/WINAMP.H new file mode 100644 index 00000000..2ebafaf6 --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/WINAMP.H @@ -0,0 +1,38 @@ +#ifndef _WAFE_H_ +#define _WAFE_H_ + +#define IPC_FF_FIRST 2000 +#define IPC_FF_NOTIFYHOTKEY IPC_FF_FIRST + 6 // data = const char * to hotkey description + +#define WINAMP_OPTIONS_EQ 40036 // toggles the EQ window +#define WINAMP_OPTIONS_PLEDIT 40040 // toggles the playlist window +#define WINAMP_VOLUMEUP 40058 // turns the volume up a little +#define WINAMP_VOLUMEDOWN 40059 // turns the volume down a little +#define WINAMP_FFWD5S 40060 // fast forwards 5 seconds +#define WINAMP_REW5S 40061 // rewinds 5 seconds + +// the following are the five main control buttons, with optionally shift +// or control pressed +// (for the exact functions of each, just try it out) +#define WINAMP_BUTTON1 40044 +#define WINAMP_BUTTON2 40045 +#define WINAMP_BUTTON3 40046 +#define WINAMP_BUTTON4 40047 +#define WINAMP_BUTTON5 40048 +#define WINAMP_BUTTON1_SHIFT 40144 +#define WINAMP_BUTTON2_SHIFT 40145 +#define WINAMP_BUTTON3_SHIFT 40146 +#define WINAMP_BUTTON4_SHIFT 40147 +#define WINAMP_BUTTON5_SHIFT 40148 +#define WINAMP_BUTTON1_CTRL 40154 +#define WINAMP_BUTTON2_CTRL 40155 +#define WINAMP_BUTTON3_CTRL 40156 +#define WINAMP_BUTTON4_CTRL 40157 +#define WINAMP_BUTTON5_CTRL 40158 + +#define WINAMP_FILE_PLAY 40029 // pops up the load file(s) box +#define WINAMP_OPTIONS_PREFS 40012 // pops up the preferences +#define WINAMP_OPTIONS_AOT 40019 // toggles always on top +#define WINAMP_HELP_ABOUT 40041 // pops up the about box :) + +#endif
\ No newline at end of file diff --git a/Src/Plugins/General/gen_hotkeys/Wacommands.cpp b/Src/Plugins/General/gen_hotkeys/Wacommands.cpp new file mode 100644 index 00000000..7acc71fc --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/Wacommands.cpp @@ -0,0 +1,366 @@ +#include "WACommands.h" +#include "gen_hotkeys.h" +#include "../nu/AutoWide.h" + +typedef struct { + UINT strId; + genHotkeysAddStruct ghk; +} genHotkeysAddStructLocalised; + +genHotkeysAddStructLocalised WADefCommands[] = { + {IDS_PLAYBACK__PLAY,{0, 0, WM_COMMAND, WINAMP_BUTTON2, 0, "ghkdc play"}}, + {IDS_PLAYBACK__PAUSE,{0, 0, WM_COMMAND, WINAMP_BUTTON3, 0, "ghkdc pause"}}, + {IDS_PLAYBACK__STOP,{0, 0, WM_COMMAND, WINAMP_BUTTON4, 0, "ghkdc stop"}}, + {IDS_PLAYBACK__PREVIOUS_IN_PLAYLIST,{0, 0, WM_COMMAND, WINAMP_BUTTON1, 0, "ghkdc prev"}}, + {IDS_PLAYBACK__NEXT_IN_PLAYLIST,{0, 0, WM_COMMAND, WINAMP_BUTTON5, 0, "ghkdc next"}}, + {IDS_PLAYBACK__VOLUME_UP,{0, 0, WM_COMMAND, WINAMP_VOLUMEUP, 0, "ghkdc vup"}}, + {IDS_PLAYBACK__VOLUME_DOWN,{0, 0, WM_COMMAND, WINAMP_VOLUMEDOWN, 0, "ghkdc vdown"}}, + {IDS_PLAYBACK__FORWARD,{0, 0, WM_COMMAND, WINAMP_FFWD5S, 0, "ghkdc forward"}}, + {IDS_PLAYBACK__REWIND,{0, 0, WM_COMMAND, WINAMP_REW5S, 0, "ghkdc rewind"}}, + {IDS_PLAYBACK__REPEAT_ON,{0, 0, WM_WA_IPC, 1, IPC_SET_REPEAT, "ghkdc repeat on"}}, + {IDS_PLAYBACK__REPEAT_OFF,{0, 0, WM_WA_IPC, 0, IPC_SET_REPEAT, "ghkdc repeat off"}}, + {IDS_UI__TOGGLE_EQ,{0, 0, WM_COMMAND, WINAMP_OPTIONS_EQ, 0, "ghkdc t eq"}}, + {IDS_UI__TOGGLE_PLAYLIST,{0, 0, WM_COMMAND, WINAMP_OPTIONS_PLEDIT, 0, "ghkdc t pl"}}, + {IDS_UI__TOGGLE_AOT,{0, 0, WM_COMMAND, WINAMP_OPTIONS_AOT, 0, "ghkdc t aot"}}, + {IDS_UI__ABOUT,{0, HKF_BRING_TO_FRONT, WM_COMMAND, WINAMP_HELP_ABOUT, 0, "ghkdc about"}}, + {IDS_PLAYBACK__JUMP_TO_BOX,{0, HKF_BRING_TO_FRONT, WM_COMMAND, 40194, 0, "ghkdc jump"}}, + {IDS_PLAYBACK__OPEN_FILE_DIALOG,{0, HKF_BRING_TO_FRONT|HKF_WPARAM_HWND, WM_WA_IPC, 0, IPC_OPENFILEBOX, "ghkdc file"}}, + {IDS_PLAYBACK__OPEN_LOC_DIALOG,{0, HKF_BRING_TO_FRONT, WM_COMMAND, WINAMP_BUTTON2_CTRL, 0, "ghkdc url"}}, + {IDS_PLAYBACK__OPEN_FOLDER_DIALOG,{0, HKF_BRING_TO_FRONT|HKF_WPARAM_HWND, WM_WA_IPC, 0, IPC_OPENDIRBOX, "ghkdc dir"}}, + {IDS_GENERAL__QUIT,{0, 0, WM_CLOSE, 0, 0, "ghkdc quit"}}, + {IDS_UI__PREFERENCES,{0, HKF_BRING_TO_FRONT, WM_WA_IPC, (WPARAM)(-1), IPC_OPENPREFSTOPAGE, "ghkdc prefs"}}, + {IDS_GENERAL__COPY_TITLE,{0, HKF_COPY_RET|HKF_PLPOS_WPARAM, WM_WA_IPC, 0, IPC_GETPLAYLISTTITLE, "ghkdc copy"}}, + {IDS_GENERAL__COPY_FILE_PATH,{0, HKF_COPY_RET|HKF_WPARAM_PLPOS, WM_WA_IPC, 0, IPC_GETPLAYLISTFILE, "ghkdc copy path"}}, + {IDS_PLAYBACK__PLAY_PAUSE,{0, HKF_ISPLAYING_WL, WM_COMMAND, WINAMP_BUTTON3, WINAMP_BUTTON2, "ghkdc play/pause"}}, + {IDS_PLAYBACK__TOGGLE_REPEAT,{0, 0, WM_COMMAND, 40022, 0, "ghkdc t repeaat"}}, + {IDS_PLAYBACK__TOGGLE_SHUFFLE,{0, 0, WM_COMMAND, 40023, 0, "ghkdc t shuffle"}}, + {IDS_UI__TOGGLE_WINSHADE,{0, 0, WM_COMMAND, 40064, 0, "ghkdc ws"}}, + {IDS_UI__TOGGLE_PLAYLIST_WINSHADE,{0, 0, WM_COMMAND, 40266, 0, "ghkdc pl ws"}}, + {IDS_UI__TOGGLE_DOUBLESIZE,{0, 0, WM_COMMAND, 40165, 0, "ghkdc ds"}}, + {IDS_UI__TOGGLE_MAIN_WINDOW,{0, 0, WM_COMMAND, 40258, 0, "ghkdc t main"}}, + // removed due to it not being in current winamp builds now {IDS_UI__TOGGLE_MINIBROWSER,{0, 0, WM_COMMAND, 40298, 0, "ghkdc t mb"}}, + {IDS_VIS__PREFERENCES,{0, HKF_BRING_TO_FRONT, WM_COMMAND, 40191, 0, "ghkdc vis prefs"}}, + {IDS_VIS_TOGGLE_VIS_ON_OFF,{0, 0, WM_COMMAND, 40192, 0, "ghkdc t vis"}}, + // added in 1.91 based on user feedback (ID_VIS_* options) and also from finding the correct menu id to use + {IDS_VIS__PLUGIN_PREFERENCES,{0, HKF_BRING_TO_FRONT, WM_COMMAND, 40221, 0, "ghkdc prefs vis"}}, + {IDS_VIS_NEXT_PRESET,{0, 0, WM_COMMAND, ID_VIS_NEXT, 0, "ghkdc vis next"}}, + {IDS_VIS_PREV_PRESET,{0, 0, WM_COMMAND, ID_VIS_PREV, 0, "ghkdc vis prev"}}, + {IDS_VIS_RAND_PRESET,{0, 0, WM_COMMAND, ID_VIS_RANDOM, 0, "ghkdc vis rand"}}, + {IDS_VIS_FULL_SCREEN,{0, 0, WM_COMMAND, ID_VIS_FS, 0, "ghkdc vis fs"}}, + {IDS_UI__SELECT_SKIN,{0, HKF_BRING_TO_FRONT, WM_COMMAND, 40219, 0, "ghkdc skin"}}, + {IDS_PLAYBACK__STOP_WITH_FADEOUT,{0, 0, WM_COMMAND, WINAMP_BUTTON4_SHIFT, 0, "ghkdc stop fade"}}, + {IDS_PLAYBACK__STOP_AFTER_CURRENT,{0, 0, WM_COMMAND, WINAMP_BUTTON4_CTRL, 0, "ghkdc stop ac"}}, + {IDS_PLAYBACK__START_OF_LIST,{0, 0, WM_COMMAND, WINAMP_BUTTON1_CTRL, 0, "ghkdc sol"}}, + {IDS_PLAYBACK__END_OF_LIST,{0, 0, WM_COMMAND, WINAMP_BUTTON5_CTRL, 0, "ghkdc eol"}}, + {IDS_UI__BRING_TO_FRONT_OR_HIDE,{0, HKF_SHOWHIDE, WM_SHOWWINDOW, 0, 0, "ghkdc show/hide"}}, + {IDS_RATING__5_STARS,{0, 0, WM_WA_IPC, 5, IPC_SETRATING, "ghkdc rating 5"}}, + {IDS_RATING__4_STARS,{0, 0, WM_WA_IPC, 4, IPC_SETRATING, "ghkdc rating 4"}}, + {IDS_RATING__3_STARS,{0, 0, WM_WA_IPC, 3, IPC_SETRATING, "ghkdc rating 3"}}, + {IDS_RATING__2_STARS,{0, 0, WM_WA_IPC, 2, IPC_SETRATING, "ghkdc rating 2"}}, + {IDS_RATING__1_STAR,{0, 0, WM_WA_IPC, 1, IPC_SETRATING, "ghkdc rating 1"}}, + {IDS_RATING__NO_RATING,{0, 0, WM_WA_IPC, 0, IPC_SETRATING, "ghkdc rating 0"}}, + // added in 1.4+ so that we can deal with unicode strings on 5.3x+ Winamp versions + {IDS_GENERAL__COPY_TITLEW,{0, HKF_COPYW_RET|HKF_PLPOS_WPARAM, WM_WA_IPC, 0, IPC_GETPLAYLISTTITLEW, "ghkdc copyw"}}, + {IDS_GENERAL__COPY_FILE_PATHW,{0, HKF_COPYW_RET|HKF_WPARAM_PLPOS, WM_WA_IPC, 0, IPC_GETPLAYLISTFILEW, "ghkdc copy pathw"}}, + // added in 1.6+ for neorth + {IDS_RATING__INC,{0, 0, WM_WA_IPC, 6, IPC_SETRATING, "ghkdc inc rating"}}, + {IDS_RATING__DEC,{0, 0, WM_WA_IPC, (WPARAM)(-1), IPC_SETRATING, "ghkdc dec rating"}}, + // added in 1.91 for kzuse + {IDS_PLAYBACK__MANUAL_ADVANCE,{0, 0, WM_COMMAND, 40395, 0, "ghkdc man adv"}}, + // added in 1.92 as killing of separate gen_find_on_disk.dll to be native + {IDS_GENERAL_FFOD,{0, 0, WM_COMMAND, 40468, 0, "FFOD_Cur"}}, + {IDS_PLAYBACK_EDIT_ID3,{0, 0, WM_COMMAND, 40188, 0, "VCFI"}}, +}; + +static unsigned int WACommandsNum; +static unsigned int WACommandsAllocated; +WACommand *WACommands=0; + +inline unsigned int GetCommandsNum() +{ + return WACommandsNum; +} + +static bool ReallocateCommands() +{ + if (WACommandsNum < WACommandsAllocated) + return true; + + WACommand *newCommands = new WACommand[ WACommandsNum * 2 + 16]; + if (newCommands) + memcpy(newCommands, WACommands, WACommandsAllocated*sizeof(WACommand)); + + WACommandsAllocated = WACommandsNum * 2 + 16; + delete [] WACommands; + WACommands = newCommands; + if (!WACommands) + { + WACommandsAllocated = 0; + return false; + } + return true; +} + +void InitCommands() +{ + int l = sizeof(WADefCommands) / sizeof(WADefCommands[0]); + while (l--) + { + wchar_t rateBuf[1024] = {0}; + wchar_t* rateStr = rateBuf; + WADefCommands[l].ghk.name = (char*)WASABI_API_LNGSTRINGW_BUF(WADefCommands[l].strId, rateBuf, 1024); + switch(WADefCommands[l].strId) + { + // for the rating entries force any asterisks to a unicode star + case IDS_RATING__1_STAR: + case IDS_RATING__2_STARS: + case IDS_RATING__3_STARS: + case IDS_RATING__4_STARS: + case IDS_RATING__5_STARS: + while(rateStr && *rateStr) + { + if(*rateStr == L'*') *rateStr = L'\u2605'; + rateStr=CharNextW(rateStr); + } + break; + } + WADefCommands[l].ghk.flags |= HKF_UNICODE_NAME; + AddCommand(&WADefCommands[l].ghk); + } +} + +int AddCommand(genHotkeysAddStruct *ghas) +{ + unsigned int idx = WACommandsNum; + if (!ghas) + return -1; + + // legacy support + if (!ghas->id) + ghas->id = ghas->name; + + if (WACommands) + { + unsigned int l = WACommandsNum; + while (l--) + { + if (!lstrcmpiW(WACommands[l].id, AutoWide(ghas->id))) + { + WACommands[l].bEnabled = !(ghas->flags & HKF_DISABLED); + char *name = 0; + if(!(ghas->flags & HKF_UNICODE_NAME)) + name = (char *) malloc(lstrlen(ghas->name) + 1); + else + name = (char *) malloc((lstrlenW((wchar_t*)ghas->name) + 1) * sizeof(wchar_t)); + if (name) + { + free(WACommands[l].name); + WACommands[l].name = name; + } + WACommands[l].dwFlags = (ghas->flags & 0x7FFFFFFF); + WACommands[l].uMsg = ghas->uMsg; + WACommands[l].wParam = ghas->wParam; + WACommands[l].lParam = ghas->lParam; + WACommands[l].wnd = ghas->wnd; + return l; + } + } + } + WACommandsNum++; + if (!ReallocateCommands()) + { + WACommandsNum--; + return -2; + } + + if(!(ghas->flags & HKF_UNICODE_NAME)) + WACommands[idx].name = _strdup(ghas->name); + else + WACommands[idx].name = (char*)_wcsdup((wchar_t*)ghas->name); + + if (!WACommands[idx].name) + { + WACommandsNum--; + return -1; + } + + WACommands[idx].id = AutoWideDup(ghas->id); + if (!WACommands[idx].id) + { + free(WACommands[idx].name); + WACommandsNum--; + return -1; + } + WACommands[idx].dwFlags = (ghas->flags & 0x7FFFFFFF); + WACommands[idx].uMsg = ghas->uMsg; + WACommands[idx].wParam = ghas->wParam; + WACommands[idx].lParam = ghas->lParam; + WACommands[idx].bEnabled = !(ghas->flags & HKF_DISABLED); + WACommands[idx].wnd = ghas->wnd; + return idx; +} + +inline char *GetCommandName(unsigned int i, bool *unicode) +{ + if (i < WACommandsNum) + { + if(unicode) *unicode = !!(WACommands[i].dwFlags & HKF_UNICODE_NAME); + return WACommands[i].name; + } + return ""; +} + +inline wchar_t *GetCommandId(unsigned int i) +{ + if (i < WACommandsNum) + return WACommands[i].id; + return L""; +} + +int GetCommandIdx(wchar_t *id) +{ + if (WACommands) + { + unsigned int l = WACommandsNum; + while (l--) + { + if (!lstrcmpiW(WACommands[l].id, id)) + { + return l; + } + } + } + return -1; +} + +int HandleByScript(unsigned int i) +{ + if (i >= WACommandsNum) return 0; + if (SendMessage(psPlugin.hwndParent, WM_WA_IPC, (WPARAM)WACommands[i].name, IPC_FF_NOTIFYHOTKEY)) return 0; + return 1; +} + +int DoCommand(unsigned int i) +{ + if (i >= WACommandsNum) + return 0; + + if (!WACommands[i].bEnabled) + return 0; + + if (HandleByScript(i)) return 1; + + WPARAM wParam = WACommands[i].wParam; + LPARAM lParam = WACommands[i].lParam; + + /*if (WACommands[i].dwFlags & HKF_CUSTOM_FUNC) + { + if (WACommands[i].uMsg) + { + pfnWAC pfn = (pfnWAC) WACommands[i].uMsg; + pfn(); + } + + return 0; + }*/ + + if (WACommands[i].dwFlags & HKF_SHOWHIDE) + { + DWORD dwThisProcId, dwProcId; + GetWindowThreadProcessId(psPlugin.hwndParent, &dwThisProcId); + GetWindowThreadProcessId(GetForegroundWindow(), &dwProcId); + if (IsWindowVisible(psPlugin.hwndParent) && dwProcId == dwThisProcId) + ShowWindow(psPlugin.hwndParent, SW_MINIMIZE); + else + { + ShowWindow(psPlugin.hwndParent, SW_SHOWNORMAL); + SetForegroundWindow(psPlugin.hwndParent); + } + } + + HWND hwnddest=WACommands[i].wnd ? WACommands[i].wnd : psPlugin.hwndParent; + + if (WACommands[i].dwFlags & HKF_BRING_TO_FRONT) + { + SetForegroundWindow(psPlugin.hwndParent); + } + if (WACommands[i].dwFlags & HKF_WPARAM_HWND) + { + wParam = (WPARAM) psPlugin.hwndParent; + } + if (WACommands[i].dwFlags & HKF_WPARAM_PLPOS) + { + wParam = (WPARAM) SendMessage(psPlugin.hwndParent, WM_WA_IPC, 0, IPC_GETLISTPOS); + } + if (WACommands[i].dwFlags & HKF_WPARAM_ISPLAYING_WL) + { + if (SendMessage(psPlugin.hwndParent, WM_WA_IPC, 0, IPC_ISPLAYING)) + wParam = WACommands[i].wParam; // Pause + else + wParam = WACommands[i].lParam; // Play + + lParam = 0; + } + + LRESULT lResult = SendMessage(hwnddest, WACommands[i].uMsg, wParam, lParam); + + if (WACommands[i].dwFlags & HKF_COPY && lResult) + { + char *szTitle = (char *) lResult; + + if (!OpenClipboard(psPlugin.hwndParent)) + return 0; + EmptyClipboard(); + + int bufLen = lstrlen(szTitle) + 1; + HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, bufLen); + if (!hglbCopy) + { + CloseClipboard(); + return 0; + } + + char *szClipboardTitle = (char *) GlobalLock(hglbCopy); + if (!szClipboardTitle) + { + CloseClipboard(); + return 0; + } + lstrcpyn(szClipboardTitle, szTitle, bufLen); + GlobalUnlock(hglbCopy); + + SetClipboardData(CF_TEXT, hglbCopy); + + CloseClipboard(); + } + + if (WACommands[i].dwFlags & HKF_COPYW && lResult) + { + wchar_t *szTitle = (wchar_t *) lResult; + + if (!OpenClipboard(psPlugin.hwndParent)) + return 0; + EmptyClipboard(); + + int bufLen = (lstrlenW(szTitle) + 1) * sizeof(wchar_t); + HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, bufLen); + if (!hglbCopy) + { + CloseClipboard(); + return 0; + } + + wchar_t *szClipboardTitle = (wchar_t *) GlobalLock(hglbCopy); + if (!szClipboardTitle) + { + CloseClipboard(); + return 0; + } + lstrcpynW(szClipboardTitle, szTitle, bufLen); + GlobalUnlock(hglbCopy); + + SetClipboardData(CF_UNICODETEXT, hglbCopy); + CloseClipboard(); + } + return (int)lResult; +}
\ No newline at end of file diff --git a/Src/Plugins/General/gen_hotkeys/Wacommands.h b/Src/Plugins/General/gen_hotkeys/Wacommands.h new file mode 100644 index 00000000..0ae832ff --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/Wacommands.h @@ -0,0 +1,50 @@ +#ifndef ___WINAMP_COMMANDS___H___ +#define ___WINAMP_COMMANDS___H___ + +#include "../winamp/wa_ipc.h" +#include "wa_hotkeys.h" + +// calls SetForegroundWindow before sending the message +#define HKF_BRING_TO_FRONT 0x1 +// sets wParam with Winamp's window handle +#define HKF_WPARAM_HWND 0x2 +// copies returned text to the clipboard (CF_TEXT) +#define HKF_COPY_RET 0x4 +// sets wParam with current pledit position +#define HKF_WPARAM_PLPOS 0x8 +// sets wParam to genHotkeysAddStruct's wParam if playing, lParam if not +// uses IPC_ISPLAYING to check if playing +#define HKF_WPARAM_ISPLAYING_WL 0x10 +// brings Winamp to front or minimizes Winamp if already at front +#define HKF_SHOWHIDE 0x20 +#define HKF_CUSTOM_FUNC 0x40 +// copies returned text to the clipboard (CF_UNICODETEXT) +#define HKF_COPYW_RET 0x80 +#define HKF_UNICODE_NAME 0x100 +// set this when the 'name' is passed as a unicode string + +typedef void (*pfnWAC)(); + +struct WACommand +{ + wchar_t *id; + char *name; + DWORD dwFlags; + UINT uMsg; + WPARAM wParam; + LPARAM lParam; + BOOL bEnabled; + HWND wnd; +}; + +extern WACommand *WACommands; + +extern inline unsigned int GetCommandsNum(); +void InitCommands(); +int AddCommand(genHotkeysAddStruct *ghas); +extern inline char *GetCommandName(unsigned int i, bool *unicode); +extern inline wchar_t *GetCommandId(unsigned int i); +int GetCommandIdx(wchar_t *id); +int DoCommand(unsigned int i); + +#endif
\ No newline at end of file diff --git a/Src/Plugins/General/gen_hotkeys/accelBlock.cpp b/Src/Plugins/General/gen_hotkeys/accelBlock.cpp new file mode 100644 index 00000000..e98245d7 --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/accelBlock.cpp @@ -0,0 +1,47 @@ +#include "gen_hotkeys.h" +#include "api__gen_hotkeys.h" +#include "./accelBlock.h" + +static BOOL RegisterMessageProcessor(ifc_messageprocessor *processor, BOOL bRegister) +{ + if (NULL == WASABI_API_APP) + return FALSE; + + if (bRegister) + WASABI_API_APP->app_addMessageProcessor(processor); + else + WASABI_API_APP->app_removeMessageProcessor(processor); + + return TRUE; +} + +AcceleratorBlocker::AcceleratorBlocker(HWND hwndToBlock) : hwnd(hwndToBlock) +{ + RegisterMessageProcessor(this, TRUE); +} +AcceleratorBlocker::~AcceleratorBlocker() +{ + RegisterMessageProcessor(this, FALSE); +} + +bool AcceleratorBlocker::ProcessMessage(MSG *pMsg) +{ + if (pMsg->hwnd != hwnd) + return false; + + switch(pMsg->message) + { + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + TranslateMessage(pMsg); + DispatchMessageW(pMsg); + return true; + } + return false; +} + + +#define CBCLASS AcceleratorBlocker +START_DISPATCH; +CB(IFC_MESSAGEPROCESSOR_PROCESS_MESSAGE, ProcessMessage) +END_DISPATCH;
\ No newline at end of file diff --git a/Src/Plugins/General/gen_hotkeys/accelBlock.h b/Src/Plugins/General/gen_hotkeys/accelBlock.h new file mode 100644 index 00000000..f0d5e792 --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/accelBlock.h @@ -0,0 +1,24 @@ +#ifndef NULLSOFT_WINAMP_ACCELERATOR_BLOCKER_HEADER +#define NULLSOFT_WINAMP_ACCELERATOR_BLOCKER_HEADER + +#include <wtypes.h> +#include <api\application\ifc_messageprocessor.h> + +class AcceleratorBlocker : public ifc_messageprocessor +{ +public: + AcceleratorBlocker(HWND hwndToBlock); + ~AcceleratorBlocker(); + +public: + bool ProcessMessage(MSG *pMsg); + HWND GetHwnd() { return hwnd; } +protected: + RECVS_DISPATCH; + +protected: + HWND hwnd; + +}; + +#endif// NULLSOFT_WINAMP_ACCELERATOR_BLOCKER_HEADER
\ No newline at end of file diff --git a/Src/Plugins/General/gen_hotkeys/api__gen_hotkeys.h b/Src/Plugins/General/gen_hotkeys/api__gen_hotkeys.h new file mode 100644 index 00000000..823353fd --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/api__gen_hotkeys.h @@ -0,0 +1,10 @@ +#ifndef NULLSOFT_GEN_HOTKEYS_API_H +#define NULLSOFT_GEN_HOTKEYS_API_H + +#include "api/service/api_service.h" +#include "../Agave/Language/api_language.h" + +#include <api/application/api_application.h> +#define WASABI_API_APP applicationApi + +#endif // !NULLSOFT_GEN_HOTKEYS_API_H
\ No newline at end of file diff --git a/Src/Plugins/General/gen_hotkeys/gen_hotkeys.cpp b/Src/Plugins/General/gen_hotkeys/gen_hotkeys.cpp new file mode 100644 index 00000000..f5e496ad --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/gen_hotkeys.cpp @@ -0,0 +1,519 @@ +//#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); +}
\ No newline at end of file diff --git a/Src/Plugins/General/gen_hotkeys/gen_hotkeys.h b/Src/Plugins/General/gen_hotkeys/gen_hotkeys.h new file mode 100644 index 00000000..4cfb390c --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/gen_hotkeys.h @@ -0,0 +1,56 @@ +#ifndef ___HOTAMP3_H___ +#define ___HOTAMP3_H___ + +#include <windows.h> +#include <commctrl.h> +#include "winamp.h" +#include "wa_hotkeys.h" +#include "resource.h" +#include "hotkey.h" +#include "WACommands.h" +#include "HotKeyCtl.h" +#include "../winamp/gen.h" +#include "api__gen_hotkeys.h" +#include <strsafe.h> + +/////////////////////////////////////////////////////////// +// Hot keys initializer function +/////////////////////////////////////////////////////////// +void hotkeysInit(); +int hotkeysLoad(HOTKEY_DATA *hkds, DWORD num, int do_register, int verbose=1); +void hotkeysSave(HOTKEY_DATA *hkds, DWORD num); +void hotkeysClear(); + +/////////////////////////////////////////////////////////// +// Plugin function headers +/////////////////////////////////////////////////////////// +int pluginInit(); +void pluginConfig(); +void pluginQuit(); + +/////////////////////////////////////////////////////////// +// DLL Windows message handling procedure header +/////////////////////////////////////////////////////////// +LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +/////////////////////////////////////////////////////////// +// Globals +/////////////////////////////////////////////////////////// +extern winampGeneralPurposePlugin psPlugin; +extern HOTKEY *g_hotkeys; +extern DWORD g_dwHotkeys; +extern wchar_t *g_iniFile; +extern HOTKEY_DATA g_defhkds[]; +#define DEFHKDS_NUM 15 + +void writePrivateProfileInt(wchar_t *section, int val); + +#ifndef LONGX86 +#ifdef _WIN64 + #define LONGX86 LONG_PTR +#else /*_WIN64*/ + #define LONGX86 LONG +#endif /*_WIN64*/ +#endif // LONGX86 + +#endif
\ No newline at end of file diff --git a/Src/Plugins/General/gen_hotkeys/gen_hotkeys.rc b/Src/Plugins/General/gen_hotkeys/gen_hotkeys.rc new file mode 100644 index 00000000..6187bdd1 --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/gen_hotkeys.rc @@ -0,0 +1,217 @@ +// 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 + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_LVSTATE BITMAP "x.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_CONFIG DIALOGEX 0, 0, 273, 246 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + GROUPBOX "Global Hotkeys",IDC_STATIC,0,0,272,246 + LTEXT "Global Hotkeys are keyboard shortcuts that you can use from within any running\napplication.",IDC_STATIC,6,11,260,17 + CONTROL "Enable default &multimedia key support (you can customize them below)\n(Will process media related WM_APPCOMMAND messages - see MSDN)",IDC_ENABLED_WM_APPCOMMAND, + "Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,6,32,259,17 + CONTROL "&Enabled",IDC_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,54,42,10 + PUSHBUTTON "Restore &defaults",IDC_DEFAULT,189,53,76,13 + CONTROL "List1",IDC_HKLIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,6,70,259,137 + LTEXT "Ac&tion",IDC_STATIC,6,213,24,9,SS_CENTERIMAGE + COMBOBOX IDC_COMBO,34,211,231,154,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "&Hotkey",IDC_STATIC,6,229,24,9 + EDITTEXT IDC_HOTKEY,34,227,147,13,ES_AUTOHSCROLL + PUSHBUTTON "&Add",IDC_ADD,182,227,23,13 + PUSHBUTTON "&Set",IDC_SAVE,208,227,20,13 + PUSHBUTTON "&Remove",IDC_REMOVE,230,227,35,13 +END + + +#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 + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_NULLSOFT_GLOBAL_HOTKEYS "Nullsoft Global Hotkeys v%s" + 65535 "{250FAA3C-20CD-49db-A932-67B1C0191B0E}" +END + +STRINGTABLE +BEGIN + IDS_GHK_TITLE_STR "Global Hotkeys" + IDS_GHK_HOTKEY_REG_FAILED + "Hotkey registration failed as another program has already registered the following hotkey(s):\t\t\n" + IDS_GHK_HOTKEY_REG_FAILED_MORE "\n\tMore..." + IDS_GHK_HOTKEY_COLUMN "Hotkey" + IDS_GHK_ACTION_COLUMN "Action" + IDS_GHK_ACTION_NOT_FOUND "(action not found)" + IDS_GHK_WINKEY_STR "Winkey" + IDS_BROWSER_BACK "Browser Back" + IDS_BROWSER_FORWARD "Browser Forward" + IDS_BROWSER_REFRESH "Browser Refresh" + IDS_BROWSER_STOP "Browser Stop" + IDS_BROWSER_SEARCH "Browser Search" + IDS_BROWSER_FAVOURITES "Browser Favorites" + IDS_BROWSER_HOME "Browser Home" + IDS_VOLUME_MUTE "Volume Mute" +END + +STRINGTABLE +BEGIN + IDS_VOLUME_DOWN "Volume Down" + IDS_VOLUME_UP "Volume Up" + IDS_NEXT_TRACK "Next Track" + IDS_PREVIOUS_TRACK "Previous Track" + IDS_STOP "Stop" + IDS_PLAY_PAUSE "Play/Pause" + IDS_LAUNCH_MAIL "Launch Mail" + IDS_LAUNCH_MEDIA_SELECT "Launch Media Select" + IDS_LAUCH_APP1 "Launch App1" + IDS_LAUCH_APP2 "Launch App2" + IDS_SLEEP "Sleep" +END + +STRINGTABLE +BEGIN + IDS_PLAYBACK__PLAY "Playback: Play" + IDS_PLAYBACK__PAUSE "Playback: Pause" + IDS_PLAYBACK__STOP "Playback: Stop" + IDS_PLAYBACK__PREVIOUS_IN_PLAYLIST "Playback: Previous in playlist" + IDS_PLAYBACK__NEXT_IN_PLAYLIST "Playback: Next in playlist" + IDS_PLAYBACK__VOLUME_UP "Playback: Volume up" + IDS_PLAYBACK__VOLUME_DOWN "Playback: Volume down" + IDS_PLAYBACK__FORWARD "Playback: Forward" + IDS_PLAYBACK__REWIND "Playback: Rewind" + IDS_PLAYBACK__REPEAT_ON "Playback: Repeat on" + IDS_PLAYBACK__REPEAT_OFF "Playback: Repeat off" + IDS_UI__TOGGLE_EQ "UI: Toggle EQ" + IDS_UI__TOGGLE_PLAYLIST "UI: Toggle playlist" + IDS_UI__TOGGLE_AOT "UI: Toggle always on top" + IDS_UI__ABOUT "UI: About" + IDS_PLAYBACK__JUMP_TO_BOX "Playback: Jump to box" +END + +STRINGTABLE +BEGIN + IDS_PLAYBACK__OPEN_FILE_DIALOG "Playback: Open file dialog" + IDS_PLAYBACK__OPEN_LOC_DIALOG "Playback: Open location dialog" + IDS_PLAYBACK__OPEN_FOLDER_DIALOG "Playback: Open folder dialog" + IDS_GENERAL__QUIT "General: Quit" + IDS_UI__PREFERENCES "UI: Preferences" + IDS_GENERAL__COPY_TITLE "General: Copy title" + IDS_GENERAL__COPY_FILE_PATH "General: Copy file path" + IDS_PLAYBACK__PLAY_PAUSE "Playback: Play/Pause" + IDS_PLAYBACK__TOGGLE_REPEAT "Playback: Toggle repeat" + IDS_PLAYBACK__TOGGLE_SHUFFLE "Playback: Toggle shuffle" + IDS_UI__TOGGLE_WINSHADE "UI: Toggle windowshade" + IDS_UI__TOGGLE_PLAYLIST_WINSHADE "UI: Toggle playlist windowshade" + IDS_UI__TOGGLE_DOUBLESIZE "UI: Toggle doublesize" + IDS_UI__TOGGLE_MAIN_WINDOW "UI: Toggle main window" + IDS_UI__TOGGLE_MINIBROWSER "UI: Toggle main minibrowser" + IDS_VIS__PREFERENCES "Visualization: Preferences" +END + +STRINGTABLE +BEGIN + IDS_VIS__PLUGIN_PREFERENCES "Visualization: Plug-in preferences" + IDS_VIS_TOGGLE_VIS_ON_OFF "Visualization: Toggle on/off" + IDS_UI__SELECT_SKIN "UI: Select skin" + IDS_PLAYBACK__STOP_WITH_FADEOUT "Playback: Stop with fadeout" + IDS_PLAYBACK__STOP_AFTER_CURRENT "Playback: Stop after current" + IDS_PLAYBACK__START_OF_LIST "Playback: Start of list" + IDS_PLAYBACK__END_OF_LIST "Playback: End of list" + IDS_UI__BRING_TO_FRONT_OR_HIDE "UI: Bring to front/hide Winamp" + IDS_RATING__5_STARS "Rate current item: *****" + IDS_RATING__4_STARS "Rate current item: ****" + IDS_RATING__3_STARS "Rate current item: ***" + IDS_RATING__2_STARS "Rate current item: **" + IDS_RATING__1_STAR "Rate current item: *" + IDS_RATING__NO_RATING "Rate current item: No rating" + IDS_GENERAL__COPY_TITLEW "General: Copy title (Unicode)" + IDS_GENERAL__COPY_FILE_PATHW "General: Copy file path (Unicode)" +END + +STRINGTABLE +BEGIN + IDS_RATING__INC "Rating: Increase rating of current item" + IDS_RATING__DEC "Rating: Decrease rating of current item" + IDS_PAUSE "Pause" + IDS_VIS_NEXT_PRESET "Visualization: Next preset" + IDS_VIS_PREV_PRESET "Visualization: Previous preset" + IDS_VIS_RAND_PRESET "Visualization: Random preset" + IDS_VIS_FULL_SCREEN "Visualization: Toggle fullscreen" + IDS_PLAYBACK__MANUAL_ADVANCE "Playback: Toggle manual advance" + IDS_GENERAL_FFOD "General: Explore current item folder" + IDS_PLAYBACK_EDIT_ID3 "Playback: View current file information" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#include "version.rc2" + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Src/Plugins/General/gen_hotkeys/gen_hotkeys.sln b/Src/Plugins/General/gen_hotkeys/gen_hotkeys.sln new file mode 100644 index 00000000..25d787a7 --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/gen_hotkeys.sln @@ -0,0 +1,29 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29424.173 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gen_hotkeys", "gen_hotkeys.vcxproj", "{A0E56406-B1C9-4FC8-9589-A640D71A7364}" +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 + {A0E56406-B1C9-4FC8-9589-A640D71A7364}.Debug|Win32.ActiveCfg = Debug|Win32 + {A0E56406-B1C9-4FC8-9589-A640D71A7364}.Debug|Win32.Build.0 = Debug|Win32 + {A0E56406-B1C9-4FC8-9589-A640D71A7364}.Debug|x64.ActiveCfg = Debug|x64 + {A0E56406-B1C9-4FC8-9589-A640D71A7364}.Release|Win32.ActiveCfg = Release|Win32 + {A0E56406-B1C9-4FC8-9589-A640D71A7364}.Release|Win32.Build.0 = Release|Win32 + {A0E56406-B1C9-4FC8-9589-A640D71A7364}.Release|x64.ActiveCfg = Release|x64 + {A0E56406-B1C9-4FC8-9589-A640D71A7364}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {AF3A8D23-4DD8-4A09-BD21-7A59EDA47D7C} + EndGlobalSection +EndGlobal diff --git a/Src/Plugins/General/gen_hotkeys/gen_hotkeys.vcxproj b/Src/Plugins/General/gen_hotkeys/gen_hotkeys.vcxproj new file mode 100644 index 00000000..f8d7bc1c --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/gen_hotkeys.vcxproj @@ -0,0 +1,316 @@ +<?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>{A0E56406-B1C9-4FC8-9589-A640D71A7364}</ProjectGuid> + <RootNamespace>gen_hotkeys</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)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </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" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </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> + <EmbedManifest>true</EmbedManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir> + <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Label="Vcpkg"> + <VcpkgEnabled>false</VcpkgEnabled> + </PropertyGroup> + <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <VcpkgConfiguration>Debug</VcpkgConfiguration> + <VcpkgTriplet> + </VcpkgTriplet> + </PropertyGroup> + <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <VcpkgConfiguration>Debug</VcpkgConfiguration> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>.;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN32;_DEBUG;_WINDOWS;_USRDLL;HOTAMP3_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> + <ObjectFileName>$(IntDir)</ObjectFileName> + <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <BufferSecurityCheck>true</BufferSecurityCheck> + <FunctionLevelLinking>true</FunctionLevelLinking> + </ClCompile> + <ResourceCompile> + <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <Culture>0x0409</Culture> + </ResourceCompile> + <Link> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> + <TargetMachine>MachineX86</TargetMachine> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <SubSystem>Windows</SubSystem> + <MapFileName>$(IntDir)$(TargetName).map</MapFileName> + </Link> + <PostBuildEvent> + <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ +xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command> + <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>.;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN64;_DEBUG;_WINDOWS;_USRDLL;HOTAMP3_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> + <ObjectFileName>$(IntDir)</ObjectFileName> + <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <BufferSecurityCheck>true</BufferSecurityCheck> + <FunctionLevelLinking>true</FunctionLevelLinking> + </ClCompile> + <ResourceCompile> + <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <Culture>0x0409</Culture> + </ResourceCompile> + <Link> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <SubSystem>Windows</SubSystem> + <MapFileName>$(IntDir)$(TargetName).map</MapFileName> + </Link> + <PostBuildEvent> + <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ +xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command> + <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>MinSpace</Optimization> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <FavorSizeOrSpeed>Size</FavorSizeOrSpeed> + <AdditionalIncludeDirectories>.;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN32;NDEBUG;_WINDOWS;_USRDLL;HOTAMP3_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> + <ObjectFileName>$(IntDir)</ObjectFileName> + <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>None</DebugInformationFormat> + <FunctionLevelLinking>true</FunctionLevelLinking> + </ClCompile> + <ResourceCompile> + <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <Culture>0x0409</Culture> + </ResourceCompile> + <Link> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>false</GenerateDebugInformation> + <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> + <MapFileName>$(IntDir)$(TargetName).map</MapFileName> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> + <TargetMachine>MachineX86</TargetMachine> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <SubSystem>Windows</SubSystem> + </Link> + <PostBuildEvent> + <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command> + <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <Optimization>MinSpace</Optimization> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <FavorSizeOrSpeed>Size</FavorSizeOrSpeed> + <AdditionalIncludeDirectories>.;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN64;NDEBUG;_WINDOWS;_USRDLL;HOTAMP3_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> + <ObjectFileName>$(IntDir)</ObjectFileName> + <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>None</DebugInformationFormat> + <FunctionLevelLinking>true</FunctionLevelLinking> + </ClCompile> + <ResourceCompile> + <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <Culture>0x0409</Culture> + </ResourceCompile> + <Link> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>false</GenerateDebugInformation> + <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> + <MapFileName>$(IntDir)$(TargetName).map</MapFileName> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <SubSystem>Windows</SubSystem> + </Link> + <PostBuildEvent> + <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command> + <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="accelBlock.cpp" /> + <ClCompile Include="ConfigDlg.cpp"> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;HOTAMP3_EXPORTS</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;HOTAMP3_EXPORTS</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;HOTAMP3_EXPORTS</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN64;NDEBUG;_WINDOWS;_MBCS;_USRDLL;HOTAMP3_EXPORTS</PreprocessorDefinitions> + </ClCompile> + <ClCompile Include="gen_hotkeys.cpp"> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;HOTAMP3_EXPORTS</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;HOTAMP3_EXPORTS</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;HOTAMP3_EXPORTS</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN64;NDEBUG;_WINDOWS;_MBCS;_USRDLL;HOTAMP3_EXPORTS</PreprocessorDefinitions> + </ClCompile> + <ClCompile Include="HotKey.cpp"> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;HOTAMP3_EXPORTS</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;HOTAMP3_EXPORTS</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;HOTAMP3_EXPORTS</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN64;NDEBUG;_WINDOWS;_MBCS;_USRDLL;HOTAMP3_EXPORTS</PreprocessorDefinitions> + </ClCompile> + <ClCompile Include="HotKeyCtl.cpp"> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;HOTAMP3_EXPORTS</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;HOTAMP3_EXPORTS</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;HOTAMP3_EXPORTS</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN64;NDEBUG;_WINDOWS;_MBCS;_USRDLL;HOTAMP3_EXPORTS</PreprocessorDefinitions> + </ClCompile> + <ClCompile Include="WACommands.cpp"> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;HOTAMP3_EXPORTS</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;HOTAMP3_EXPORTS</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;HOTAMP3_EXPORTS</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN64;NDEBUG;_WINDOWS;_MBCS;_USRDLL;HOTAMP3_EXPORTS</PreprocessorDefinitions> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="accelBlock.h" /> + <ClInclude Include="api__gen_hotkeys.h" /> + <ClInclude Include="ConfigDlg.h" /> + <ClInclude Include="gen_hotkeys.h" /> + <ClInclude Include="HotKey.h" /> + <ClInclude Include="HotKeyCtl.h" /> + <ClInclude Include="resource.h" /> + <ClInclude Include="WACommands.h" /> + <ClInclude Include="wa_hotkeys.h" /> + <ClInclude Include="winamp.h" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="gen_hotkeys.rc" /> + </ItemGroup> + <ItemGroup> + <Image Include="x.bmp" /> + </ItemGroup> + <ItemGroup> + <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>
\ No newline at end of file diff --git a/Src/Plugins/General/gen_hotkeys/gen_hotkeys.vcxproj.filters b/Src/Plugins/General/gen_hotkeys/gen_hotkeys.vcxproj.filters new file mode 100644 index 00000000..515b3109 --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/gen_hotkeys.vcxproj.filters @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <ClCompile Include="WACommands.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HotKeyCtl.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HotKey.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="gen_hotkeys.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ConfigDlg.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="accelBlock.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="winamp.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="WACommands.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="wa_hotkeys.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="resource.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HotKey.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="gen_hotkeys.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ConfigDlg.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="api__gen_hotkeys.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="accelBlock.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HotKeyCtl.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{b429b35f-cbbb-427f-b618-1e7c2ef4fa72}</UniqueIdentifier> + </Filter> + <Filter Include="Ressource Files"> + <UniqueIdentifier>{d06654b1-494e-468a-9e54-d70525ca2531}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{b03b7dae-2c85-4929-8e46-eb6b06b87635}</UniqueIdentifier> + </Filter> + <Filter Include="Image Files"> + <UniqueIdentifier>{36cdd73d-755e-40a7-945a-f6cad3b9379c}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <Image Include="x.bmp"> + <Filter>Image Files</Filter> + </Image> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="gen_hotkeys.rc"> + <Filter>Ressource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Src/Plugins/General/gen_hotkeys/version.rc2 b/Src/Plugins/General/gen_hotkeys/version.rc2 new file mode 100644 index 00000000..f151f4be --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/version.rc2 @@ -0,0 +1,39 @@ + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// +#include "..\..\..\Winamp/buildType.h" +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,97,0,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 General Purpose Plug-in" + VALUE "FileVersion", "1,97,0,0" + VALUE "InternalName", "Nullsoft Global Hotkeys" + VALUE "LegalCopyright", "Copyright © 2003-2023 Winamp SA" + VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA" + VALUE "OriginalFilename", "gen_hotkeys.dll" + VALUE "ProductName", "Winamp" + VALUE "ProductVersion", STR_WINAMP_PRODUCTVER + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/Src/Plugins/General/gen_hotkeys/wa_hotkeys.h b/Src/Plugins/General/gen_hotkeys/wa_hotkeys.h new file mode 100644 index 00000000..2877c01d --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/wa_hotkeys.h @@ -0,0 +1,91 @@ +#ifndef WA_HOTKEYS +#define WA_HOTKEYS + +/* +** #define IPC_GEN_HOTKEYS_ADD xxxx // pass a genHotkeysAddStruct * struct in data +** +** To get the IPC_GEN_HOTKEYS_ADD IPC number, you need to do this: +** +** genhotkeys_add_ipc=SendMessage(winampWindow,WM_WA_IPC,(WPARAM)&"GenHotkeysAdd",IPC_REGISTER_WINAMP_IPCMESSAGE); +** +** Then you can use: +** +** PostMessage(winampWindow,WM_WA_IPC,(WPARAM)&myGenHotkeysAddStruct,genhotkeys_add_ipc); +*/ + +//flags for the genHotkeysAddStruct struct +#define HKF_BRING_TO_FRONT 0x1 // calls SetForegroundWindow before sending the message +#define HKF_HWND_WPARAM 0x2 // sets wParam with Winamp's window handle +#define HKF_COPY 0x4 // copies returned text to the clipboard (using CF_TEXT) +#define HKF_PLPOS_WPARAM 0x8 // sets wParam with current pledit position +#define HKF_ISPLAYING_WL 0x10 // sets wParam to genHotkeysAddStruct's wParam if playing, lParam if not + // uses IPC_ISPLAYING to check if playing +#define HKF_SHOWHIDE 0x20 // brings Winamp to front or minimizes Winamp if already at front +#define HKF_NOSENDMSG 0x40 // don't send any message to the winamp window + +#define HKF_COPYW 0x80 // copies returned text to the clipboard (using CF_UNICODETEXT) +#define HKF_UNICODE_NAME 0x100 // set this when the 'name' is passed as a unicode string + +#define HKF_DISABLED 0x80000000 + +#include "WinDef.h" + +typedef struct { + char *name; //name that will appear in the Global Hotkeys preferences panel + DWORD flags; //one or more flags from above + UINT uMsg; //message that will be sent to winamp's main window (must always be !=NULL) + WPARAM wParam; //wParam that will be sent to winamp's main window + LPARAM lParam; //lParam that will be sent to winamp's main window + char *id; //unique string to identify this command - case insensitive + HWND wnd; //set the HWND to send message (or 0 for main winamp window) + + int extended[6]; //for future extension - always set to zero! +} genHotkeysAddStruct; + +/* +** Before calling this function you need to setup the genHotkeysAddStruct struct +** +** genHotkeysAddStruct test_key = {0}; // this will make the compiler zero the struct for you +** // though you can do it manually if you want to as well +** +** UINT test_ipc = 0; // this will hold the uMsg value to look for in the assigned window proc +** +** // then call the function to register the hotkey +** AddGlobalHotkey(&test_key,"Playback: Test key","Test_key",&test_ipc); +** +** void AddGlobalHotkey(genHotkeysAddStruct *hotkey, char* name, char* id, int* ipc){ +** UINT genhotkeys_add_ipc = 0; +** hotkey->wnd = 0; +** hotkey->flags = 0; +** hotkey->name = name; +** hotkey->id = id; +** *ipc = hotkey->uMsg = SendMessage(winampWindow,WM_WA_IPC,(WPARAM)&hotkey->id,IPC_REGISTER_WINAMP_IPCMESSAGE); +** +** genhotkeys_add_ipc=SendMessage(winampWindow,WM_WA_IPC,(WPARAM)&"GenHotkeysAdd",IPC_REGISTER_WINAMP_IPCMESSAGE); +** PostMessage(winampWindow,WM_WA_IPC,(WPARAM)hotkey,genhotkeys_add_ipc); +** } +*/ + +/* +** This shows how to detect the registered hotkey message +** then it's upto you what you do +** +** LRESULT CALLBACK WinampWnd(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ +** int ret = 0; +** +** // handles the hotkey for the option :o) +** if(uMsg == test_ipc){ +** // here you can do things needed for the hotkey you registered +** } +** +** // do stuff before the winamp proc has been called +** +** ret = CallWindowProc(WinampProc,hwnd,uMsg,wParam,lParam); +** +** // do other stuff after the winamp proc has been called +** // then return the value from CallWindowProc(..) +** return ret; +** } +*/ + +#endif
\ No newline at end of file diff --git a/Src/Plugins/General/gen_hotkeys/x.bmp b/Src/Plugins/General/gen_hotkeys/x.bmp Binary files differnew file mode 100644 index 00000000..43ebcfc0 --- /dev/null +++ b/Src/Plugins/General/gen_hotkeys/x.bmp |