293 lines
7.3 KiB
C++
293 lines
7.3 KiB
C++
|
#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);
|
||
|
}
|