windows - Kan task-switching tastaturgenveje være deaktiveret i W7 ved hjælp af Delphi?

Indlæg af Hanne Mølgaard Plasc

Problem



Min ansøgning har haft en tilstand i mange år, hvor kunden kan 'deaktivere adgang til operativsystemet'. Selvfølgelig går denne funktion mod kornet (i det mindste hvad angår Windows), men der er installationer, hvor min app er det eneste program, der nogensinde skulle være visibilt til en maskinoperatør, og i dette tilfælde er en sådan funktion nyttig.


Teknikken jeg brugte blev bygget af flere 'lag':



  1. Skjul proceslinjen og knappen.

  2. Deaktiver opgaveudskiftning.

  3. Deaktiver mine hovedformatsystemikoner.



For at deaktivere proceslinjen, jeg brugte:


// 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 );


Dette fungerede godt og synes stadig fint på W7.
Undersøgelse af, hvordan du deaktiverer opgaveafbrydelser for nogle år siden, blev den eneste teknik til at 'foregive', at din App er en pauseskærm (bortset fra forfærdelige ting som omdøber din app til 'explorer.exe' og opstart i den osv.):


procedure EnableTaskSwitching( AState : boolean );
// Enables / disables task switching
begin
  SystemParametersInfo(
    SPI\_SCREENSAVERRUNNING,
    Cardinal( not AState),
    nil,
    0 );
end;


Ikke overraskende synes dette ikke at have nogen effekt i W7 (jeg tror det virker i XP osv.).
Er der nogen der kender til en anden, bedre måde at aktivere/deaktivere Alt-Tab (og andre specielle Windows-nøgler) fra at arbejde?

Bedste reference


Hvis der findes en løsning:


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;


Dette deaktiverer (som du kan se!)



  • Ctrl + Esc (vis startmenu)

  • Alt + Tab (opgavekontakt)

  • Alt + Esc (opgavekontakt)

  • Vind (vis startmenu)

  • Vind + Tab (3D-opgavekontakt)

  • Win + D, Win + M, Win + Space, Win + Pile, Win + P, Win + U, Win + E, Win + F, Win + Digit, ...

  • Næsten enhver kombination, herunder Windows-nøglen (men ikke alle, fx Win + L)


Andre referencer 1


Som David har påpeget, kaldes dette 'Kiosk Mode'. Et par gode artikler (del 1 og del 2) findes på About.com. [4] [5]

Andre referencer 2


Der er Windows Embedded Standard 7, som du kan pakke på en måde, der har en ægte kiosk-tilstand. [6]

Andre referencer 3


dWinLock giver også en løsning. IIRC, installerer de en tjeneste, der kan stoppe Ctrl + Alt + Del. [7]