How to prevent ALT+TAB, CTRL+ALT+DEL, etc.

How can one trap and prevent the ALT+TAB, CTRL+ALT+DEL, etc (ALT+TAB, CTRL+ESC, ALT+F4, ALT+ESC), system keys in Delphi if possible. The method needs to work for Win95/98 and WinNT 4.0.
WillieSwartAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
gallagheConnect With a Mentor Commented:
First off, the code presented below was put together by one  person, but is a collection from many Delphi programmers.

1. Preventing Alt+F4
refer to "FormClose" event

2. For ALT+TAB, CTRL+ALT+DEL, etc (ALT+TAB, CTRL+ESC, ALT+F4,  
   ALT+ESC), system keys  Try the code listed below. Simply
   set the properties at design time to try it. It works for
   me under (D3, Windows95 and D4 under Windows98)

Hope this is a viable solution!
Kevin
=======BEGIN UNIT CODE=========
unit WinAccess;

interface

uses
 Windows, Classes, Controls, Forms, shlobj, shellapi;

type

 TKeyState = (kbOn, kbOff);
 TAccessState = (asVisible, asHiden);
 TWinAccess = class(TComponent)
 private
  SysClasses : array [0..3] of PChar;
  FStartButton : TAccessState;
  FTrayBar : TAccessState;
  FTrayNotify : TAccessState;
  FAppSwitch : TAccessState;
{******************************************************************************}
  FCapsLock : TKeyState;
  FNumLock : TKeyState;
  FScrollLock : TKeyState;
  FSystemKey : TKeyState;
  FHoldCapsLock : Boolean;
  FHoldNumLock : Boolean;
  FHoldScrollLock : Boolean;


  Procedure SetStartButton(v : TAccessState);
  Procedure SetTrayBar(v : TAccessState);
  Procedure SetTrayNotify(v : TAccessState);
  Procedure SetAppSwitch(v : TAccessState);
{******************************************************************************}
  procedure SetCapsLock( value : TKeyState );
  procedure SetNumLock( value : TKeyState );
  procedure SetScrollLock( value : TKeyState );
  procedure SetSystemKey( value : TKeyState );
  procedure SetHoldNumLock(h : Boolean);
  procedure SetHoldCapsLock(h : Boolean);
  procedure SetHoldScrollLock(h : Boolean);
 protected
 public
  constructor Create(AOWner : TComponent); override;
 published
  property StartButton : TAccessState read FStartButton write SetStartButton stored true nodefault;
  property TrayBar : TAccessState read FTrayBar write SetTrayBar stored true nodefault;
  property TrayNotify : TAccessState read FTrayNotify write SetTrayNotify stored true nodefault;
  property AppSwitch : TAccessState read FAppSwitch write SetAppSwitch stored true nodefault;
{******************************************************************************}
  property CapsLock: TKeyState read FCapsLock write SetCapsLock;
  property NumLock: TKeyState read FNumLock write SetNumLock;
  property ScrollLock: TKeyState read FScrollLock write SetScrollLock;
  property SystemKey : TkeyState read FSystemKey write SetSystemKey;
  property HoldNumLock: boolean read FHoldNumLock write SetHoldNumLock;
  property HoldScrollLock: boolean read FHoldScrollLock write SetHoldScrollLock;
  property HoldCapsLock : boolean read FHoldCapsLock write SetHoldCapsLock;
 end;

 procedure Register;
implementation
{$R WinAccess.res}
const
 iTRAYBAR = 0;
 iTRAYNOTIFY = 1;
 iSTARTBUTTON = 2;
 iAPPSWITCHBAR = 3;
var
 HN, HC, HS : Boolean;
 NS, CS, SS : Byte;

{******************************************************************************}

function KeyboardProc(
    code : Integer;      // hook code
    wParam : Integer;      // virtual-key code
    lParam : Integer       // keystroke-message information
) : LRESULT; stdcall;
var
  KeyState : TKeyBoardState;
begin
 if wParam = VK_NUMLOCK then
 begin
  GetKeyboardState(KeyState);
  if HN then
   KeyState[VK_NUMLOCK] := NS;
  if HC then
   KeyState[VK_CAPITAL] := CS;
  if HS then
   KeyState[VK_SCROLL] := SS;
  SetKeyboardState(KeyState);
  Result := 1;
 end
 else
  Result := 0;
end;

{******************************************************************************}

constructor TWinAccess.Create(AOWner : TComponent);
Var
  KeyState : TKeyBoardState;
  OldValue : integer;
begin
  inherited Create(AOWner);
  FHoldCapsLock := false;
  FHoldNumLock := false;
  FHoldScrollLock := false;
  SetWindowsHookEx(
    WH_KEYBOARD,      // type of hook to install
    KeyboardProc,      // address of hook procedure
    HInstance,      // handle of application instance
    0       // identity of thread to install hook for
   );
  GetKeyboardState(KeyState);
  Case KeyState[VK_CAPITAL] of
    1 : SetCapsLock(kbOn);
    0 : SetCapsLock(kbOff);
  end;
  case KeyState[VK_NUMLOCK] of
    1 : SetNumLock(kbOn);
    0 : SetNumLock(kbOff);
  end;
  case KeyState[VK_SCROLL] of
    1 : SetScrollLock(kbOn);
    0 : SetScrollLock(kbOff);
  end;
  SystemParametersInfo( SPI_SCREENSAVERRUNNING, 0, @OldValue, 0);
  { Set the SystemKey to its original value, who can teach me a good way? :) }
  case OldValue of
    1 : SetSystemKey(kbOff);
    0 : SetSystemKey(kbOn);
  end;
  SystemParametersInfo( SPI_SCREENSAVERRUNNING, OldValue, @OldValue, 0);

{******************************************************************************}
 SysClasses[0] := 'Shell_TrayWnd';
 SysClasses[1] := 'TrayNotifyWnd';
 SysClasses[2] := 'Button';
 SysClasses[3] := 'MSTaskSwWClass';
end;

Procedure TWinAccess.SetStartButton(v : TAccessState);
var
 wnd : THandle;
begin
 FStartButton := v;
 wnd := FindWindow(SysClasses[iTRAYBAR],nil);
 wnd := FindWindowEx(wnd,HWND(0),SysClasses[iSTARTBUTTON],nil);
 case v of
  asVisible :
   SetWindowPos(wnd, HWND_TOP,0,0,0,0,SWP_NOZORDER+SWP_NOMOVE+SWP_NOSIZE+SWP_SHOWWINDOW);
  asHiden:
   SetWindowPos(wnd, HWND_TOP,0,0,0,0,SWP_NOZORDER+SWP_NOMOVE+SWP_NOSIZE+SWP_HIDEWINDOW);
 end;
end;

Procedure TWinAccess.SetTrayBar(v : TAccessState);
var
 wnd : THandle;
begin
 FTrayBar := v;
 wnd := FindWindow(SysClasses[iTRAYBAR],nil);
 case v of
  asVisible :
   SetWindowPos(wnd, HWND_TOP,0,0,0,0,SWP_NOZORDER+SWP_NOMOVE+SWP_NOSIZE+SWP_SHOWWINDOW);
  asHiden:
   SetWindowPos(wnd, HWND_TOP,0,0,0,0,SWP_NOZORDER+SWP_NOMOVE+SWP_NOSIZE+SWP_HIDEWINDOW);
 end;
end;

Procedure TWinAccess.SetTrayNotify(v : TAccessState);
var
 wnd : THandle;
begin
 FTrayNotify := v;
 wnd := FindWindow(SysClasses[iTRAYBAR],nil);
 wnd := FindWindowEx(wnd,HWND(0),SysClasses[iTRAYNOTIFY],nil);
 case v of
  asVisible :
   SetWindowPos(wnd, HWND_TOP,0,0,0,0,SWP_NOZORDER+SWP_NOMOVE+SWP_NOSIZE+SWP_SHOWWINDOW);
  asHiden:
   SetWindowPos(wnd, HWND_TOP,0,0,0,0,SWP_NOZORDER+SWP_NOMOVE+SWP_NOSIZE+SWP_HIDEWINDOW);
 end;
end;

Procedure TWinAccess.SetAppSwitch(v : TAccessState);
var
 wnd : THandle;
begin
 FAppSwitch := v;
 wnd := FindWindow(SysClasses[iTRAYBAR],nil);
 wnd := FindWindowEx(wnd,HWND(0),SysClasses[iAPPSWITCHBAR],nil);
 case v of
  asVisible :
   SetWindowPos(wnd, HWND_TOP,0,0,0,0,SWP_NOZORDER+SWP_NOMOVE+SWP_NOSIZE+SWP_SHOWWINDOW);
  asHiden:
   SetWindowPos(wnd, HWND_TOP,0,0,0,0,SWP_NOZORDER+SWP_NOMOVE+SWP_NOSIZE+SWP_HIDEWINDOW);
 end;
end;

{*****************************************************************************}
procedure TWinAccess.SetCapsLock( value : TKeyState );
Var
  KeyState : TKeyBoardState;
begin
  CS := not Byte(value);
  GetKeyboardState(KeyState);
  case value of
    kbOn : KeyState[VK_CAPITAL] := 1;
    kbOff : KeyState[VK_CAPITAL] := 0;
  end;
  SetKeyboardState(KeyState);
  FCapsLock := Value;
end;

procedure TWinAccess.SetNumLock( value : TKeyState );
Var
  KeyState : TKeyBoardState;
begin
  NS := not Byte(value);
  GetKeyboardState(KeyState);
  case value of
    kbOn : KeyState[VK_NUMLOCK] := 1;
    kbOff : KeyState[VK_NUMLOCK] := 0;
  end;
  SetKeyboardState(KeyState);
  FNumLock := value;
end;

procedure TWinAccess.SetScrollLock( value : TKeyState );
Var
  KeyState : TKeyBoardState;
begin
  SS := not Byte(value);
  GetKeyboardState(KeyState);
  case value of
    kbOn : KeyState[VK_SCROLL] := 1;
    kbOff : KeyState[VK_SCROLL] := 0;
  end;
  SetKeyboardState(KeyState);
  FScrollLock := value;
end;

procedure TWinAccess.SetSystemKey( value : TKeyState );
var
  NoUse : integer;
begin
  case value of
    kbOn : SystemParametersInfo( SPI_SCREENSAVERRUNNING, 0, @NoUse, 0);
    kbOff : SystemParametersInfo( SPI_SCREENSAVERRUNNING, 1, @NoUse, 0);
  end;
  FSystemKey := value;
end;

procedure TWinAccess.SetHoldNumLock(h : Boolean);
begin
 FHoldNumLock := h;
 HN := h;
end;

procedure TWinAccess.SetHoldCapsLock(h : Boolean);
begin
 FHoldCapsLock := h;
 HC := h;
end;

procedure TWinAccess.SetHoldScrollLock(h : Boolean);
begin
 FHoldScrollLock := h;
 HS := h;
end;


Procedure Register;
begin
 RegisterComponents('Win32', [TWinAccess]);
end;
end.



0
 
Edo082297Commented:
Hello

Try these procedures, I know they take care of ALT+TAB nicely, but I have not checked the rest, if it works, let me know, I will post an answer. If you have any other questions, post a comment and I will get back to you.

Regards,
Edo

procedure TurnSysKeysOff;
var
  OldVal : LongInt;
begin
  SystemParametersInfo (97, Word (True), @OldVal, 0)
end;

procedure TurnSysKeysBackOn;
var
  OldVal : LongInt;
begin
  SystemParametersInfo (97, Word (False), @OldVal, 0)
end;

0
 
Edo082297Commented:
I should mention that I obtained those routines from UDDF, an excellent Delphi help html file. It is available at:

    http://www.gnomehome.demon.nl/uddf/indexnf.htm

Regards,
Edo

0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
williams2Commented:
You can also download the FAQ with this URL:

http://www.gnomehome.demon.nl/uddf/uddf.zip

Regards,
Williams
0
 
WillieSwartAuthor Commented:
Edo

SystemParametersInfo(97,...) where 97=SPI_SCREENSAVERRUNNING prevent CTRL+ALT+DEL and ALT+TAB key combinations, but unfortunately only in win95.

The Win32 SDK states:
"SPI_SCREENSAVERRUNNING Windows 95: Used internally; applications should not use this flag. Windows NT: Not supported."

Although an applications should not use this flag, this is a nice trick in fooling Windows 95 into thinking that a screen saver is running.

Regards,
Willie
0
 
ZifNabCommented:
Try this :

{Disable ALT-TAB}
  SystemParametersInfo( SPI_SETFASTTASKSWITCH, 1, @Dummy, 0);

Regards, Zif.
0
 
WillieSwartAuthor Commented:
Could not get it to work.

Found the following in the SDK documentation:

SPI_SETFASTTASKSWITCH This flag is obsolete. Previous versions of the system use this flag to enable or disable ALT+TAB fast task switching. For Windows 95, Windows 98, and Windows NT version 4.0, fast task switching is always enabled. See SPI_SETSWITCHTASKDISABLE.

SPI_SETSWITCHTASKDISABLE Windows NT 5.0 and later: Enables or disables ALT+TAB and ALT+ESC task switching. Set the uiParam parameter to 1 to enable the feature, or zero to disable it. By default, task switching is enabled.  

Regards,
Willie
0
 
WillieSwartAuthor Commented:
Adjusted points to 200
0
 
danyszCommented:
you can use this procedure

var
   Dummy : integer;

begin
  Dummy := 0;
  {Disable ALT-TAB}
  SystemParametersInfo( SPI_SETFASTTASKSWITCH, 1, @Dummy, 0);
  {Disable CTRL-ALT-DEL}
  SystemParametersInfo( SPI_SCREENSAVERRUNNING, 1, @Dummy, 0);
end.
0
 
MadshiCommented:
WillieSwart,

the only sure way I know is to write two keyboard device drivers, one for win95/98 and one for winNT...   :-(
It's not as difficult as it sounds. If you're using e.g. Vireo's great driver toolkits, it should be done in a few hours/days. Unfortunately you can't use Delphi for that.

Regards, Madshi.
0
 
kretzschmarCommented:
hi WillieSwart,

there is a free component with source, which will do this work,

http://www.torry.webnorth.com/vcl/system/setkey.zip

meikl
0
 
ZifNabCommented:
danysz, please read the above comments when you answer a question. Zif.
0
 
WillieSwartAuthor Commented:
This technique is not working anymore. See the previous comments.

Regards,
Willie
0
 
ronit051397Commented:
Maybe use hooking. I can send you an example of key hooking. EMail?
0
 
WillieSwartAuthor Commented:
Thanks, I'll appreciate that.

willie@fouriersystems.co.za



0
 
Edo082297Commented:
Hey WillieStewart,

Are you in KaapStad? I would love to get a contract there...

Edo
0
 
dwwangCommented:
I don't think one can disable CTRL+ALT+DELETE in WinNT, or NT will be much more criticized all over the world :)

I think hook won't do the trick either, since Win32SDK said that when CTRL+ALT+DELETE is pressed, all hooks will lost.
0
 
MadshiCommented:
dwwang is right. AFAIK you can't disable Ctrl+Alt+Delete in NT with normal APIs. But again: I think, you CAN do it with writing a keyboard mini driver...
0
 
Alex_KCommented:
Hi!
I think what all users press first 'alt', secon 'ctrl' and last 'del'.
Or other combinations, but not all in one moment.
Well, you may set hook, and read key messages from any windows.
If you read what pressing 2 from 3 this keys, you sending message for all windows, what 'ctrl'(in example) is not pressing in this time. You understand?..... I bad speak english :-)
If ypu dont know why you can set hook, then send me mail to
alex_k@tvk6.krsk.ru
I send small demo for you in answer.....
If you think what this way is not right, then send me mail too, please....
By and be happy :-)
0
All Courses

From novice to tech pro — start learning today.