|
|
1.1.1.5 root 1: /*
1.1.1.7 root 2: Copyright (c) 2005 TrueCrypt Foundation. All rights reserved.
1.1 root 3:
1.1.1.8 ! root 4: Governed by the TrueCrypt License 2.5 the full text of which is contained
1.1.1.5 root 5: in the file License.txt included in TrueCrypt binary and source code
6: distribution packages.
1.1 root 7: */
8:
9: #include <windows.h>
10: #include "Dlgcode.h"
11: #include "Hotkeys.h"
12: #include "Language.h"
13: #include "Mount.h"
14: #include "Resource.h"
15:
16: #define MAX_KEY_COMB_NAME_LEN 260
17:
18: TCHOTKEY Hotkeys [NBR_HOTKEYS];
19: static TCHOTKEY tmpHotkeys [NBR_HOTKEYS];
20:
21: static int nSelectedHotkeyId;
22: static UINT currentVKeyCode;
23:
24:
25: static void ScanAndProcessKey (UINT *vKeyCode, wchar_t *keyName)
26: {
27: UINT vKey;
28: *vKeyCode = 0;
29:
30: for (vKey = 0; vKey <= 0xFF; vKey++)
31: {
32: if (GetAsyncKeyState (vKey) < 0)
33: {
34: if (GetKeyName (vKey, keyName)) // If the key is allowed and its name has been resolved
35: *vKeyCode = vKey;
36: }
37: }
38: }
39:
40:
41: /* Returns TRUE if the key is allowed and its name is resolved. */
42: BOOL GetKeyName (UINT vKey, wchar_t *keyName)
43: {
44: BOOL result = TRUE;
45:
46: if (vKey >= 0x30 && vKey <= 0x5a)
47: {
48: // ASCII characters
49: wsprintfW (keyName, L"%hc", (char) vKey);
50: }
51: else if (vKey >= 0xE9 && vKey <= 0xF5)
52: {
53: // OEM-specific
54: wsprintfW (keyName, L"OEM-%d", vKey);
55: }
56: else if (vKey >= VK_F1 && vKey <= VK_F24)
57: {
58: // F1-F24
59: wsprintfW (keyName, L"F%d", vKey - VK_F1 + 1);
60: }
61: else if (vKey >= VK_NUMPAD0 && vKey <= VK_NUMPAD9)
62: {
63: // Numpad numbers
64: wsprintfW (keyName, L"%s %d", GetString ("VK_NUMPAD"), vKey - VK_NUMPAD0);
65: }
66: else
67: {
68: switch (vKey)
69: {
70: case VK_MULTIPLY: wsprintfW (keyName, L"%s *", GetString ("VK_NUMPAD")); break;
71: case VK_ADD: wsprintfW (keyName, L"%s +", GetString ("VK_NUMPAD")); break;
72: case VK_SEPARATOR: wsprintfW (keyName, L"%s Separator", GetString ("VK_NUMPAD")); break;
73: case VK_SUBTRACT: wsprintfW (keyName, L"%s -", GetString ("VK_NUMPAD")); break;
74: case VK_DECIMAL: wsprintfW (keyName, L"%s .", GetString ("VK_NUMPAD")); break;
75: case VK_DIVIDE: wsprintfW (keyName, L"%s /", GetString ("VK_NUMPAD")); break;
76: case VK_OEM_1: wcscpy (keyName, L"OEM 1 (';')"); break;
77: case VK_OEM_PLUS: wcscpy (keyName, L"+"); break;
78: case VK_OEM_COMMA: wcscpy (keyName, L","); break;
79: case VK_OEM_MINUS: wcscpy (keyName, L"-"); break;
80: case VK_OEM_PERIOD: wcscpy (keyName, L"."); break;
81: case VK_OEM_2: wcscpy (keyName, L"OEM 2 ('/')"); break;
82: case VK_OEM_3: wcscpy (keyName, L"OEM 3 (`)"); break;
83: case VK_OEM_4: wcscpy (keyName, L"OEM 4 ('[')"); break;
84: case VK_OEM_5: wcscpy (keyName, L"OEM 5 ('\\')"); break;
85: case VK_OEM_6: wcscpy (keyName, L"OEM 6 (']')"); break;
86: case VK_OEM_7: wcscpy (keyName, L"OEM 7 (')"); break;
87: case VK_OEM_8: wcscpy (keyName, L"OEM 8"); break;
88: case VK_OEM_AX: wcscpy (keyName, L"OEM AX"); break;
89: case VK_OEM_102: wcscpy (keyName, L"OEM 102"); break;
90: case VK_ICO_HELP: wcscpy (keyName, L"ICO_HELP"); break;
91: case VK_ICO_00: wcscpy (keyName, L"ICO_00"); break;
92: case VK_ICO_CLEAR: wcscpy (keyName, L"ICO_CLEAR"); break;
93: case VK_ATTN: wcscpy (keyName, L"Attn"); break;
94: case VK_CRSEL: wcscpy (keyName, L"CrSel"); break;
95: case VK_EXSEL: wcscpy (keyName, L"ExSel"); break;
96: case VK_EREOF: wcscpy (keyName, L"Erase EOF"); break;
97: case VK_PA1: wcscpy (keyName, L"PA1"); break;
98: case VK_OEM_CLEAR: wcscpy (keyName, L"OEM Clear"); break;
99:
100: case 0:
101: case 1:
102: case 0xFF:
103: result = FALSE;
104: break;
105:
106: default:
107: {
108: char key[16];
109: wchar_t *desc;
110: sprintf (key, "VKEY_%02X", vKey);
111: desc = GetString (key);
112: if (desc == UnknownString)
113: result = FALSE;
114: else
115: wcsncpy (keyName, desc, MAX_KEY_COMB_NAME_LEN);
116: }
117: }
118: }
119: return result;
120: }
121:
122:
123: static BOOL ShortcutInUse (UINT vKeyCode, UINT modifiers, TCHOTKEY hotkeys[])
124: {
125: int i;
126:
127: for (i = 0; i < NBR_HOTKEYS; i++)
128: {
129: if (hotkeys[i].vKeyCode == vKeyCode && hotkeys[i].vKeyModifiers == modifiers)
130: return TRUE;
131: }
132: return FALSE;
133: }
134:
135:
136: void UnregisterAllHotkeys (HWND hwndDlg, TCHOTKEY hotkeys[])
137: {
138: int i;
139:
140: for (i = 0; i < NBR_HOTKEYS; i++)
141: {
142: if (hotkeys[i].vKeyCode != 0)
143: UnregisterHotKey (hwndDlg, i);
144:
145: }
146: }
147:
148:
1.1.1.5 root 149: BOOL RegisterAllHotkeys (HWND hwndDlg, TCHOTKEY hotkeys[])
1.1 root 150: {
1.1.1.5 root 151: BOOL result = TRUE;
1.1 root 152: int i;
153:
154: for (i = 0; i < NBR_HOTKEYS; i++)
155: {
1.1.1.5 root 156: if (hotkeys[i].vKeyCode != 0
157: && !RegisterHotKey (hwndDlg, i, hotkeys[i].vKeyModifiers, hotkeys[i].vKeyCode))
158: result = FALSE;
1.1 root 159: }
1.1.1.5 root 160:
161: return result;
1.1 root 162: }
163:
164:
165: static void DisplayHotkeyList (HWND hwndDlg)
166: {
167: LVITEMW item;
168: HWND hList = GetDlgItem (hwndDlg, IDC_HOTKEY_LIST);
169: int i;
170: wchar_t ShortcutMod [MAX_KEY_COMB_NAME_LEN];
171: wchar_t ShortcutFinal [MAX_KEY_COMB_NAME_LEN*2];
172: wchar_t Shortcut [MAX_KEY_COMB_NAME_LEN];
173:
174: SendMessage (hList, LVM_DELETEALLITEMS,0, (LPARAM)&item);
175:
176: for (i = 0; i < NBR_HOTKEYS; i++)
177: {
178: memset (&item,0,sizeof(item));
179: item.mask = LVIF_TEXT;
180: item.iItem = i;
181: item.iSubItem = 0;
182:
183: switch (i)
184: {
185:
186: case HK_AUTOMOUNT_DEVICES:
187: item.pszText = GetString ("HK_AUTOMOUNT_DEVICES");
188: break;
189:
190: case HK_DISMOUNT_ALL:
191: item.pszText = GetString ("HK_DISMOUNT_ALL");
192: break;
193:
1.1.1.5 root 194: case HK_WIPE_CACHE:
195: item.pszText = GetString ("HK_WIPE_CACHE");
196: break;
197:
1.1 root 198: case HK_FORCE_DISMOUNT_ALL_AND_WIPE:
199: item.pszText = GetString ("HK_FORCE_DISMOUNT_ALL_AND_WIPE");
200: break;
201:
202: case HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT:
203: item.pszText = GetString ("HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT");
204: break;
205:
206: case HK_MOUNT_FAVORITE_VOLUMES:
207: item.pszText = GetString ("HK_MOUNT_FAVORITE_VOLUMES");
208: break;
209:
210: case HK_SHOW_HIDE_MAIN_WINDOW:
211: item.pszText = GetString ("HK_SHOW_HIDE_MAIN_WINDOW");
212: break;
213:
214: default:
215: item.pszText = L"[?]";
216: }
217:
218: SendMessageW (hList,LVM_INSERTITEMW,0,(LPARAM)&item);
219:
220: item.iSubItem = 1;
221: wcscpy (Shortcut, L"");
222: wcscpy (ShortcutMod, L"");
223:
224: if (GetKeyName (tmpHotkeys[i].vKeyCode, Shortcut))
225: {
226: if (tmpHotkeys[i].vKeyModifiers & MOD_CONTROL)
227: {
228: wcscat (ShortcutMod, GetString ("VK_CONTROL"));
229: wcscat (ShortcutMod, L"+");
230: }
231:
232: if (tmpHotkeys[i].vKeyModifiers & MOD_SHIFT)
233: {
234: wcscat (ShortcutMod, GetString ("VK_SHIFT"));
235: wcscat (ShortcutMod, L"+");
236: }
237:
238: if (tmpHotkeys[i].vKeyModifiers & MOD_ALT)
239: {
240: wcscat (ShortcutMod, GetString ("VK_ALT"));
241: wcscat (ShortcutMod, L"+");
242: }
243:
244: if (tmpHotkeys[i].vKeyModifiers & MOD_WIN)
245: {
246: wcscat (ShortcutMod, GetString ("VK_WIN"));
247: wcscat (ShortcutMod, L"+");
248: }
249:
250: wsprintfW (ShortcutFinal, L"%s%s", ShortcutMod, Shortcut);
251: item.pszText = ShortcutFinal;
252: }
253: else
254: item.pszText = L"";
255:
256: SendMessageW (hList, LVM_SETITEMW, 0, (LPARAM)&item);
257: }
258: }
259:
260:
261:
1.1.1.6 root 262: BOOL CALLBACK HotkeysDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
1.1 root 263: {
264: HWND hList = GetDlgItem (hwndDlg, IDC_HOTKEY_LIST);
1.1.1.5 root 265: HWND hwndMainDlg = hwndDlg;
1.1 root 266: WORD lw = LOWORD (wParam);
267: WORD hw = HIWORD (wParam);
268: static BOOL bKeyScanOn;
269: static BOOL bTPlaySoundOnHotkeyMountDismount;
1.1.1.5 root 270: static BOOL bTDisplayMsgBoxOnHotkeyDismount;
271:
272: while (GetParent (hwndMainDlg) != NULL)
273: {
274: hwndMainDlg = GetParent (hwndMainDlg);
275: }
1.1 root 276:
277: switch (msg)
278: {
279: case WM_INITDIALOG:
280: {
281: LVCOLUMNW col;
1.1.1.5 root 282:
1.1 root 283: bKeyScanOn = FALSE;
284: nSelectedHotkeyId = -1;
285: currentVKeyCode = 0;
286: memcpy (tmpHotkeys, Hotkeys, sizeof(tmpHotkeys));
287:
1.1.1.2 root 288: SendMessageW (hList,LVM_SETEXTENDEDLISTVIEWSTYLE,0,
1.1 root 289: LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_LABELTIP
290: );
291:
292: memset (&col,0,sizeof(col));
293: col.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT;
294: col.pszText = GetString ("ACTION");
1.1.1.6 root 295: col.cx = CompensateXDPI (341);
1.1 root 296: col.fmt = LVCFMT_LEFT;
297: SendMessageW (hList,LVM_INSERTCOLUMNW,0,(LPARAM)&col);
298:
299: col.pszText = GetString ("SHORTCUT");
1.1.1.6 root 300: col.cx = CompensateXDPI (190);
1.1 root 301: col.fmt = LVCFMT_LEFT;
302: SendMessageW (hList,LVM_INSERTCOLUMNW,1,(LPARAM)&col);
303:
304: LocalizeDialog (hwndDlg, "IDD_HOTKEYS_DLG");
305:
306: SetCheckBox (hwndDlg, IDC_HK_MOD_CTRL, TRUE);
307: SetCheckBox (hwndDlg, IDC_HK_MOD_SHIFT, FALSE);
308: SetCheckBox (hwndDlg, IDC_HK_MOD_ALT, TRUE);
309: SetCheckBox (hwndDlg, IDC_HK_MOD_WIN, FALSE);
310:
311: SetCheckBox (hwndDlg, IDC_DISMOUNT_CONFIRM_PLAY_SOUND, bPlaySoundOnHotkeyMountDismount);
312: SetCheckBox (hwndDlg, IDC_DISMOUNT_CONFIRM_MSG_BOX, bDisplayMsgBoxOnHotkeyDismount);
313:
314: bTPlaySoundOnHotkeyMountDismount = bPlaySoundOnHotkeyMountDismount;
315: bTDisplayMsgBoxOnHotkeyDismount = bDisplayMsgBoxOnHotkeyDismount;
316:
317: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE);
318: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), FALSE);
319:
320: DisplayHotkeyList(hwndDlg);
321:
322: SetTimer (hwndDlg, 0xfe, 10, NULL);
323: return 1;
324: }
325:
326: case WM_TIMER:
327: {
328: if (nSelectedHotkeyId > -1)
329: {
330: wchar_t keyName [MAX_KEY_COMB_NAME_LEN];
331: UINT tmpVKeyCode;
332:
333: keyName[0] = 0;
334:
335: ScanAndProcessKey (&tmpVKeyCode, &keyName[0]);
336:
337: if (keyName[0] != 0)
338: {
339: currentVKeyCode = tmpVKeyCode;
340: SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), keyName);
341: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), TRUE);
342: }
343: }
344: return 1;
345: }
346:
347: case WM_COMMAND:
348: case WM_NOTIFY:
349:
350: if (lw == IDC_HOTKEY_KEY && hw == EN_CHANGE)
351: {
352: if (!bKeyScanOn && nSelectedHotkeyId < 0 && GetWindowTextLengthW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY)))
353: SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), L"");
354: }
355:
356: if (msg == WM_NOTIFY && wParam == IDC_HOTKEY_LIST)
357: {
358: if (((LPNMHDR) lParam)->code == LVN_ITEMACTIVATE
359: || ((LPNMHDR) lParam)->code == LVN_ITEMCHANGED && (((LPNMLISTVIEW) lParam)->uNewState & LVIS_FOCUSED))
360: {
361: LVITEM item;
362: memset(&item,0,sizeof(item));
363: nSelectedHotkeyId = ((LPNMLISTVIEW) lParam)->iItem;
364: SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), GetString ("PRESS_A_KEY_TO_ASSIGN"));
365:
366: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), (tmpHotkeys[nSelectedHotkeyId].vKeyCode > 0));
367:
368: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE);
369: bKeyScanOn = TRUE;
370: return 1;
371: }
372: }
373:
374: if (lw == IDC_HOTKEY_ASSIGN)
375: {
1.1.1.6 root 376: BOOL bOwnActiveShortcut = FALSE;
377:
1.1 root 378: if (nSelectedHotkeyId >= 0 && currentVKeyCode != 0)
379: {
380: UINT modifiers = 0;
381: if (GetCheckBox (hwndDlg, IDC_HK_MOD_CTRL))
382: modifiers = MOD_CONTROL;
383:
384: if (GetCheckBox (hwndDlg, IDC_HK_MOD_ALT))
385: modifiers |= MOD_ALT;
386:
387: if (GetCheckBox (hwndDlg, IDC_HK_MOD_SHIFT))
388: modifiers |= MOD_SHIFT;
389:
390: if (GetCheckBox (hwndDlg, IDC_HK_MOD_WIN))
391: modifiers |= MOD_WIN;
392:
393: // Check if it's not already assigned
394: if (ShortcutInUse (currentVKeyCode, modifiers, tmpHotkeys))
395: {
396: Error ("SHORTCUT_ALREADY_IN_USE");
397: return 1;
398: }
399:
400: // Check for reserved system keys
401: switch (currentVKeyCode)
402: {
403: case VK_F1:
404: case VK_F12:
405: /* F1 is help and F12 is reserved for use by the debugger at all times */
406: if (modifiers == 0)
407: {
408: Error ("CANNOT_USE_RESERVED_KEY");
409: return 1;
410: }
411: break;
412: }
413:
1.1.1.6 root 414: bOwnActiveShortcut = ShortcutInUse (currentVKeyCode, modifiers, Hotkeys);
415:
1.1 root 416: // Test if the shortcut can be assigned without errors
1.1.1.6 root 417: if (!bOwnActiveShortcut
418: && !RegisterHotKey (hwndDlg, nSelectedHotkeyId, modifiers, currentVKeyCode))
1.1 root 419: {
420: handleWin32Error(hwndDlg);
421: return 1;
422: }
423: else
424: {
1.1.1.6 root 425: if (!bOwnActiveShortcut && !UnregisterHotKey (hwndDlg, nSelectedHotkeyId))
1.1 root 426: handleWin32Error(hwndDlg);
427:
428: tmpHotkeys[nSelectedHotkeyId].vKeyCode = currentVKeyCode;
429: tmpHotkeys[nSelectedHotkeyId].vKeyModifiers = modifiers;
430:
431: SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), L"");
432: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE);
433: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), FALSE);
434: nSelectedHotkeyId = -1;
435: bKeyScanOn = FALSE;
436: }
437: }
438: DisplayHotkeyList(hwndDlg);
439: return 1;
440: }
441:
442: if (lw == IDC_HOTKEY_REMOVE)
443: {
444: if (nSelectedHotkeyId >= 0)
445: {
446: tmpHotkeys[nSelectedHotkeyId].vKeyCode = 0;
447: tmpHotkeys[nSelectedHotkeyId].vKeyModifiers = 0;
448: SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), L"");
449: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE);
450: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), FALSE);
451: nSelectedHotkeyId = -1;
452: bKeyScanOn = FALSE;
453: DisplayHotkeyList(hwndDlg);
454: }
455: return 1;
456: }
457:
458: if (lw == IDC_RESET_HOTKEYS)
459: {
460: int i;
461:
462: for (i = 0; i < NBR_HOTKEYS; i++)
463: {
464: tmpHotkeys[i].vKeyCode = 0;
465: tmpHotkeys[i].vKeyModifiers = 0;
466: }
467: SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), L"");
468: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE);
469: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), FALSE);
470: nSelectedHotkeyId = -1;
471: bKeyScanOn = FALSE;
472: DisplayHotkeyList(hwndDlg);
473: return 1;
474: }
475:
476: if (lw == IDC_DISMOUNT_CONFIRM_PLAY_SOUND)
477: {
478: bTPlaySoundOnHotkeyMountDismount = GetCheckBox (hwndDlg, IDC_DISMOUNT_CONFIRM_PLAY_SOUND);
479: }
480:
481: if (lw == IDC_DISMOUNT_CONFIRM_MSG_BOX)
482: {
483: bTDisplayMsgBoxOnHotkeyDismount = GetCheckBox (hwndDlg, IDC_DISMOUNT_CONFIRM_MSG_BOX);
484: }
485:
486: if (lw == IDCANCEL || lw == IDCLOSE)
487: {
488: KillTimer (hwndDlg, 0xfe);
489: EndDialog (hwndDlg, IDCANCEL);
490: return 1;
491: }
492:
493: if (lw == IDOK)
494: {
1.1.1.5 root 495: UnregisterAllHotkeys (hwndMainDlg, Hotkeys);
1.1 root 496: memcpy (Hotkeys, tmpHotkeys, sizeof(Hotkeys));
1.1.1.5 root 497: RegisterAllHotkeys (hwndMainDlg, Hotkeys);
1.1 root 498: KillTimer (hwndDlg, 0xfe);
499: bPlaySoundOnHotkeyMountDismount = bTPlaySoundOnHotkeyMountDismount;
500: bDisplayMsgBoxOnHotkeyDismount = bTDisplayMsgBoxOnHotkeyDismount;
501:
502: SaveSettings (hwndDlg);
503: EndDialog (hwndDlg, IDCANCEL);
504: return 1;
505: }
506: return 0;
507:
508: case WM_CLOSE:
509:
510: KillTimer (hwndDlg, 0xfe);
511: EndDialog (hwndDlg, IDCANCEL);
512: return 1;
513: }
514: return 0;
515: }
516:
517:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.