HotKeyCtl.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. #include "HotKeyCtl.h"
  2. #include "gen_hotkeys.h"
  3. struct HKWND_DATA
  4. {
  5. WNDPROC lpfnEditWndProc;
  6. DWORD dwScanCode;
  7. WORD wMod;
  8. DWORD dwHotKey;
  9. };
  10. LRESULT CALLBACK HotKeyWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  11. #if(_WIN32_WINNT < 0x0500)
  12. #define VK_BROWSER_BACK 0xA6
  13. #define VK_BROWSER_FORWARD 0xA7
  14. #define VK_BROWSER_REFRESH 0xA8
  15. #define VK_BROWSER_STOP 0xA9
  16. #define VK_BROWSER_SEARCH 0xAA
  17. #define VK_BROWSER_FAVORITES 0xAB
  18. #define VK_BROWSER_HOME 0xAC
  19. #define VK_VOLUME_MUTE 0xAD
  20. #define VK_VOLUME_DOWN 0xAE
  21. #define VK_VOLUME_UP 0xAF
  22. #define VK_MEDIA_NEXT_TRACK 0xB0
  23. #define VK_MEDIA_PREV_TRACK 0xB1
  24. #define VK_MEDIA_STOP 0xB2
  25. #define VK_MEDIA_PLAY_PAUSE 0xB3
  26. #define VK_LAUNCH_MAIL 0xB4
  27. #define VK_LAUNCH_MEDIA_SELECT 0xB5
  28. #define VK_LAUNCH_APP1 0xB6
  29. #define VK_LAUNCH_APP2 0xB7
  30. #endif
  31. #ifndef VK_SLEEP
  32. #define VK_SLEEP 0x5F
  33. #endif
  34. UINT wmHKCtlSet;
  35. UINT wmHKCtlGet;
  36. int SubclassEditBox(HWND hwEdit)
  37. {
  38. if (!IsWindow(hwEdit))
  39. return 0;
  40. if (!wmHKCtlSet)
  41. wmHKCtlSet = RegisterWindowMessage("gen_hotkeys HotKeyCTL set");
  42. if (!wmHKCtlGet)
  43. wmHKCtlGet = RegisterWindowMessage("gen_hotkeys HotKeyCTL get");
  44. HKWND_DATA *hkwnd_data = new HKWND_DATA;
  45. if (!hkwnd_data)
  46. return 0;
  47. memset(hkwnd_data, 0, sizeof(HKWND_DATA));
  48. hkwnd_data->lpfnEditWndProc = (WNDPROC)(LONG_PTR)SetWindowLongPtrW(hwEdit, GWLP_WNDPROC, (LONGX86)(LONG_PTR)HotKeyWndProc);
  49. SetWindowLongPtr(hwEdit, GWLP_USERDATA, (LONGX86)(LONG_PTR) hkwnd_data);
  50. return 1;
  51. }
  52. void HotKeySetText(HWND hwHK, HKWND_DATA *hkwnd_data)
  53. {
  54. if (!IsWindow(hwHK) || !hkwnd_data)
  55. return;
  56. wchar_t szKeyName[1024] = L"";
  57. wchar_t *p = szKeyName;
  58. DWORD dwSize = sizeof(szKeyName);
  59. DWORD dwLen = 0;
  60. WORD wMod;
  61. if (hkwnd_data->dwHotKey)
  62. wMod = HIBYTE(hkwnd_data->dwHotKey);
  63. else
  64. wMod = hkwnd_data->wMod;
  65. if(wMod & HOTKEYF_WIN) {
  66. // GetKeyNameText gives us Left/Right Windows but RegisterHotKey doesn't seperate the two
  67. //GetKeyNameText(MAKELPARAM(0, MapVirtualKey(VK_LWIN, 0)) | (1 << 24), p, dwSize);
  68. // so we use just "Winkey" to avoid confusion
  69. WASABI_API_LNGSTRINGW_BUF(IDS_GHK_WINKEY_STR,p,dwSize);
  70. dwLen = lstrlenW(szKeyName);
  71. StringCchCatW(p, dwSize, L" + ");
  72. dwSize -= dwLen + 3;
  73. p = szKeyName + dwLen + 3;
  74. }
  75. if(wMod & HOTKEYF_CONTROL) {
  76. GetKeyNameTextW(MAKELONG(0, MapVirtualKey(VK_CONTROL, 0)), p, dwSize);
  77. dwLen = lstrlenW(szKeyName);
  78. StringCchCatW(p, dwSize, L" + ");
  79. dwSize -= dwLen + 3;
  80. p = szKeyName + dwLen + 3;
  81. }
  82. if(wMod & HOTKEYF_SHIFT) {
  83. GetKeyNameTextW(MAKELONG(0, MapVirtualKey(VK_SHIFT, 0)), p, dwSize);
  84. dwLen = lstrlenW(szKeyName);
  85. StringCchCatW(p, dwSize, L" + ");
  86. dwSize -= dwLen + 3;
  87. p = szKeyName + dwLen + 3;
  88. }
  89. if(wMod & HOTKEYF_ALT) {
  90. GetKeyNameTextW(MAKELONG(0, MapVirtualKey(VK_MENU, 0)), p, dwSize);
  91. dwLen = lstrlenW(szKeyName);
  92. StringCchCatW(p, dwSize, L" + ");
  93. dwSize -= dwLen + 3;
  94. p = szKeyName + dwLen + 3;
  95. }
  96. if(hkwnd_data->dwHotKey)
  97. {
  98. switch (LOBYTE(hkwnd_data->dwHotKey))
  99. {
  100. case VK_BROWSER_BACK:
  101. WASABI_API_LNGSTRINGW_BUF(IDS_BROWSER_BACK,p,dwSize);
  102. break;
  103. case VK_BROWSER_FORWARD:
  104. WASABI_API_LNGSTRINGW_BUF(IDS_BROWSER_FORWARD,p,dwSize);
  105. break;
  106. case VK_BROWSER_REFRESH:
  107. WASABI_API_LNGSTRINGW_BUF(IDS_BROWSER_REFRESH,p,dwSize);
  108. break;
  109. case VK_BROWSER_STOP:
  110. WASABI_API_LNGSTRINGW_BUF(IDS_BROWSER_STOP,p,dwSize);
  111. break;
  112. case VK_BROWSER_SEARCH:
  113. WASABI_API_LNGSTRINGW_BUF(IDS_BROWSER_SEARCH,p,dwSize);
  114. break;
  115. case VK_BROWSER_FAVORITES:
  116. WASABI_API_LNGSTRINGW_BUF(IDS_BROWSER_FAVOURITES,p,dwSize);
  117. break;
  118. case VK_BROWSER_HOME:
  119. WASABI_API_LNGSTRINGW_BUF(IDS_BROWSER_HOME,p,dwSize);
  120. break;
  121. case VK_VOLUME_MUTE:
  122. WASABI_API_LNGSTRINGW_BUF(IDS_VOLUME_MUTE,p,dwSize);
  123. break;
  124. case VK_VOLUME_DOWN:
  125. WASABI_API_LNGSTRINGW_BUF(IDS_VOLUME_DOWN,p,dwSize);
  126. break;
  127. case VK_VOLUME_UP:
  128. WASABI_API_LNGSTRINGW_BUF(IDS_VOLUME_UP,p,dwSize);
  129. break;
  130. case VK_MEDIA_NEXT_TRACK:
  131. WASABI_API_LNGSTRINGW_BUF(IDS_NEXT_TRACK,p,dwSize);
  132. break;
  133. case VK_MEDIA_PREV_TRACK:
  134. WASABI_API_LNGSTRINGW_BUF(IDS_PREVIOUS_TRACK,p,dwSize);
  135. break;
  136. case VK_MEDIA_STOP:
  137. WASABI_API_LNGSTRINGW_BUF(IDS_STOP,p,dwSize);
  138. break;
  139. case VK_MEDIA_PLAY_PAUSE:
  140. WASABI_API_LNGSTRINGW_BUF(IDS_PLAY_PAUSE,p,dwSize);
  141. break;
  142. case VK_LAUNCH_MAIL:
  143. WASABI_API_LNGSTRINGW_BUF(IDS_LAUNCH_MAIL,p,dwSize);
  144. break;
  145. case VK_LAUNCH_MEDIA_SELECT:
  146. WASABI_API_LNGSTRINGW_BUF(IDS_LAUNCH_MEDIA_SELECT,p,dwSize);
  147. break;
  148. case VK_LAUNCH_APP1:
  149. WASABI_API_LNGSTRINGW_BUF(IDS_LAUCH_APP1,p,dwSize);
  150. break;
  151. case VK_LAUNCH_APP2:
  152. WASABI_API_LNGSTRINGW_BUF(IDS_LAUCH_APP2,p,dwSize);
  153. break;
  154. case VK_SLEEP:
  155. WASABI_API_LNGSTRINGW_BUF(IDS_SLEEP,p,dwSize);
  156. break;
  157. case VK_PAUSE:
  158. WASABI_API_LNGSTRINGW_BUF(IDS_PAUSE,p,dwSize);
  159. break;
  160. default:
  161. GetKeyNameTextW(hkwnd_data->dwScanCode, p, dwSize);
  162. if (!*p)
  163. StringCchPrintfW(p, 1024, L"0x%X", hkwnd_data->dwScanCode);
  164. break;
  165. }
  166. }
  167. else
  168. szKeyName[dwLen] = 0;
  169. SetWindowTextW(hwHK, szKeyName);
  170. SendMessageW(hwHK, EM_SETSEL, lstrlenW(szKeyName), lstrlenW(szKeyName));
  171. }
  172. LRESULT CALLBACK HotKeyWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  173. {
  174. HKWND_DATA *hkwnd_data = (HKWND_DATA *)(LONG_PTR)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  175. HKWND_DATA hkwnd_data_local;
  176. if (uMsg == wmHKCtlSet)
  177. {
  178. int extflag = 0;
  179. if (HIBYTE(wParam) & HOTKEYF_EXT)
  180. extflag = (1 << 24);
  181. hkwnd_data->dwHotKey = (unsigned long)wParam;
  182. hkwnd_data->dwScanCode = MAKELPARAM(0, MapVirtualKey(LOBYTE(wParam), 0)) | extflag;
  183. //hkwnd_data->wMod = HIBYTE(wParam);
  184. HotKeySetText(hwnd, hkwnd_data);
  185. return 0;
  186. }
  187. else if (uMsg == wmHKCtlGet)
  188. {
  189. return hkwnd_data->dwHotKey;
  190. }
  191. switch (uMsg)
  192. {
  193. case WM_KEYDOWN:
  194. case WM_SYSKEYDOWN:
  195. {
  196. hkwnd_data->dwHotKey = 0;
  197. switch (wParam)
  198. {
  199. case VK_SHIFT:
  200. hkwnd_data->wMod |= HOTKEYF_SHIFT;
  201. break;
  202. case VK_CONTROL:
  203. hkwnd_data->wMod |= HOTKEYF_CONTROL;
  204. break;
  205. case VK_MENU:
  206. hkwnd_data->wMod |= HOTKEYF_ALT;
  207. break;
  208. case VK_LWIN:
  209. case VK_RWIN:
  210. hkwnd_data->wMod |= HOTKEYF_WIN;
  211. break;
  212. default:
  213. hkwnd_data->dwScanCode = (unsigned long)lParam;
  214. if (lParam & (1 << 24)) // extended bit
  215. hkwnd_data->wMod |= HOTKEYF_EXT;
  216. else
  217. hkwnd_data->wMod &= ~HOTKEYF_EXT;
  218. hkwnd_data->dwHotKey = MAKEWORD(wParam, hkwnd_data->wMod);
  219. break;
  220. }
  221. HotKeySetText(hwnd, hkwnd_data);
  222. return 1;
  223. }
  224. case WM_KEYUP:
  225. case WM_SYSKEYUP:
  226. {
  227. switch (wParam)
  228. {
  229. case VK_SHIFT:
  230. hkwnd_data->wMod &= ~HOTKEYF_SHIFT;
  231. break;
  232. case VK_CONTROL:
  233. hkwnd_data->wMod &= ~HOTKEYF_CONTROL;
  234. break;
  235. case VK_MENU:
  236. hkwnd_data->wMod &= ~HOTKEYF_ALT;
  237. break;
  238. case VK_LWIN:
  239. case VK_RWIN:
  240. hkwnd_data->wMod &= ~HOTKEYF_WIN;
  241. break;
  242. }
  243. HotKeySetText(hwnd, hkwnd_data);
  244. return 1;
  245. }
  246. case WM_CHAR:
  247. case WM_PASTE:
  248. return 0;
  249. case WM_DESTROY:
  250. if (hkwnd_data)
  251. {
  252. SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR) hkwnd_data->lpfnEditWndProc);
  253. SetWindowLongPtr(hwnd, GWLP_USERDATA, 0);
  254. hkwnd_data_local = *hkwnd_data;
  255. delete hkwnd_data;
  256. hkwnd_data = &hkwnd_data_local;
  257. }
  258. break;
  259. }
  260. return CallWindowProc(hkwnd_data->lpfnEditWndProc, hwnd, uMsg, wParam, lParam);
  261. }