Можно ли отключить сочетания клавиш для переключения задач в W7 с помощью Delphi?
У моего приложения в течение многих лет был режим, когда клиент может "отключить доступ к ОС". Очевидно, что эта функция идет вразрез (по крайней мере, в том, что касается Windows), но есть установки, где мое приложение является единственной программой, которая когда-либо должна быть доступна оператору машины, и в этом случае такая функция полезна.
Техника, которую я использовал, была построена из нескольких "слоев":
- Скрыть панель задач и кнопку.
- Отключить переключение задач.
- Отключить мои основные системные иконки формы.
Чтобы отключить панель задач, я использовал:
// Get a handle to the taskbar and its button..
Taskbar := FindWindow('Shell_TrayWnd', Nil);
StartButton := FindWindow('Button', Nil);
// Hide the taskbar and button
if Taskbar <> 0 then
ShowWindow( Taskbar, SW_HIDE );
if StartButton <> 0 then
ShowWindow( StartButton, SW_HIDE );
// Set the work area to the whole screen
R := Rect( 0,0,Screen.Width,Screen.Height );
SystemParametersInfo(
SPI_SETWORKAREA,
0,
@R,
0 );
Это работало хорошо и все еще кажется хорошим на W7. Изучение того, как отключить переключение задач несколько лет назад, выявило единственную технику "притворения", что ваше приложение является заставкой (кроме ужасных вещей, таких как переименование приложения в "explorer.exe", загрузка в него и т. Д.):
procedure EnableTaskSwitching( AState : boolean );
// Enables / disables task switching
begin
SystemParametersInfo(
SPI_SCREENSAVERRUNNING,
Cardinal( not AState),
nil,
0 );
end;
Неудивительно, что в W7 это никак не сказывается (я думаю, что это работает в XP и т. Д.). Кто-нибудь знает другой, лучший, способ включения / отключения Alt-Tab (и других специальных клавиш Windows) от работы?
4 ответа
Если найдено решение:
function LowLevelKeyboardProc(nCode: integer; wParam: WPARAM; lParam: LPARAM):
LRESULT; stdcall;
type
PKBDLLHOOKSTRUCT = ^TKBDLLHOOKSTRUCT;
TKBDLLHOOKSTRUCT = record
vkCode: cardinal;
scanCode: cardinal;
flags: cardinal;
time: cardinal;
dwExtraInfo: Cardinal;
end;
PKeyboardLowLevelHookStruct = ^TKeyboardLowLevelHookStruct;
TKeyboardLowLevelHookStruct = TKBDLLHOOKSTRUCT;
const
LLKHF_ALTDOWN = $20;
var
hs: PKeyboardLowLevelHookStruct;
ctrlDown: boolean;
begin
if nCode = HC_ACTION then
begin
hs := PKeyboardLowLevelHookStruct(lParam);
ctrlDown := GetAsyncKeyState(VK_CONTROL) and $8000 <> 0;
if (hs^.vkCode = VK_ESCAPE) and ctrlDown then
Exit(1);
if (hs^.vkCode = VK_TAB) and ((hs^.flags and LLKHF_ALTDOWN) <> 0) then
Exit(1);
if (hs^.vkCode = VK_ESCAPE) and ((hs^.flags and LLKHF_ALTDOWN) <> 0) then
Exit(1);
if (hs^.vkCode = VK_LWIN) or (hs^.vkCode = VK_RWIN) then
Exit(1);
end;
result := CallNextHookEx(0, nCode, wParam, lParam);
end;
procedure TForm1.FormShow(Sender: TObject);
begin
SetWindowsHookEx(WH_KEYBOARD_LL, @LowLevelKeyboardProc, 0, 0);
end;
Это отключает (как вы можете видеть!)
- Ctrl + Esc (показать меню Пуск)
- Alt + Tab (переключатель задач)
- Alt + Esc (переключение задач)
- Win (показать стартовое меню)
- Win + Tab (переключатель задач 3D)
- Win + D, Win + M, Win + Пробел, Win + Стрелки, Win+P, Win+U, Win+E, Win+F, Win+Digit, ...
- Почти любая комбинация, включая ключ Windows (но не все, например, Win+L)
Существует Windows Embedded Standard 7, которую можно упаковать так, чтобы в ней был настоящий режим киоска.
dWinLock также предоставляет решение. IIRC, они устанавливают сервис, который может остановить Ctrl+Alt+Del.