Can task-switching keyboard shortcuts be disabled in W7 using Delphi?
MY application has had a mode for years where the customer can 'disable access to the OS'. Obviously this feature goes against the grain (at least as far as Windows is concerned) but there are installations where my App is the only program that should ever be visibile to a machine operator amd in this case such a feature is useful.
The technigue I used was built from several 'layers':
- Hide the taskbar and button.
- Disable task-switching.
- Disable my main form system icons.
To disable the taskbar I used:
// 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 );
This worke开发者_开发问答d well and still seems fine on W7. Researching how to disable task-switching some years ago turned up the only technique of 'pretending' that your App is a screen saver (other than terrible things like renaming your app to 'explorer.exe' and booting into it etc):
procedure EnableTaskSwitching( AState : boolean );
// Enables / disables task switching
begin
SystemParametersInfo(
SPI_SCREENSAVERRUNNING,
Cardinal( not AState),
nil,
0 );
end;
Not surprisingly this seems to have no effect in W7 (I think it works in XP etc). Does anyone know of another, better, way of enabling / disabling Alt-Tab (and other special windows keys) from working?
If found a solution:
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;
This disables (as you can see!)
- Ctrl+Esc (show start menu)
- Alt+Tab (task switch)
- Alt+Esc (task switch)
- Win (show start menu)
- Win+Tab (3D task switch)
- Win+D, Win+M, Win+Space, Win+Arrows, Win+P, Win+U, Win+E, Win+F, Win+Digit, ...
- Almost any combination including the Windows key (but not all, e.g. Win+L)
As David has pointed out, this is called "Kiosk Mode". A couple of good articles (part 1 and part 2) can be found on About.com.
There is Windows Embedded Standard 7 that you can package in a way that has a true kiosk mode.
dWinLock also provides a solution. IIRC, they install a service that can stop Ctrl+Alt+Del.
精彩评论