Link to home
Start Free TrialLog in
Avatar of srbenavrbe
srbenavrbe

asked on

disable alt F4

How do you disable alt f4 ??
Tried this :
if (Key = VK_F4) and (ssAlt in Shift) then Key := 0;
but it does not work...
Avatar of Mike Littlewood
Mike Littlewood
Flag of United Kingdom of Great Britain and Northern Ireland image

Key := #0
ASKER CERTIFIED SOLUTION
Avatar of Mike Littlewood
Mike Littlewood
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Set your KeyPreview property of your main form to true and put that code on the main form keydown event.
This means the main forms key event will trigger before any components.
Avatar of robert_marquardt
robert_marquardt

I think you are barking the wrong tree. You should not block all means of closing your app. Write an OnCloseQuery handler.
But he isnt blocking all means of closing his app, just if the user presses ALT + F4.
He must have the usual exit application options.
Hi srbenavrbe,

you can use OnCloseQuery event to prevent form close

this code may help you:

procedure TfrmPayVoucher.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose := not(frmPayVoucher.BtnSave.Enabled);
  if(not CanClose)then
    Case (MessageDlg('Do you want to save changes?',
            mtInformation,[mbYes,mbNo,mbCancel],0))Of
      mrYes :  frmPayVoucher.BtnSaveClick(Self);
      mrNo  :  begin
                 frmPayVoucher.BtnCancelClick(Self);
                 frmPayVoucher.FormShow(Self);
                 CanClose := True;
               end;
      mrCancel:
    end;
end;

 if the CanClose Parameter equal False the form will not close
else if it's True the form will close

Regards,
Khalid.
Hi srbenavrbe

//The code should look like this:

public
  procedure AppMessage(var Msg: TMSG; var HAndled: Boolean);
end;

{...}

implementation

{...}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnMessage := AppMessage;
end;

procedure TForm1.AppMessage(var Msg: TMSG; var Handled: Boolean);
begin
  // let your application handle all messages initially
  Handled := False;
  case Msg.Message of
    WM_SYSKEYDOWN:
      if Msg.wParam = VK_F4 then
        Handled := True; // don't allow ALT-F4
  end;
end;

Regards
Marko

To "globally disable" alt+f4:

procedure TForm1.Button1Click(Sender: TObject);
begin
RegisterHotKey(handle, 1, mod_alt, vk_f4);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
UnregisterHotKey(handle, 1);
end;

After registering hot key with mod_alt and vk_f4 parameters, windows (any of them) will not be closed after pressing f4 - instead of it your application will receive wm_hotkey message.
Just another way (something like prevarant posted, but with catching only form's messages, not whole application's)


unit Unit1;

interface

uses
  Windows, Messages, Classes, Forms;

type
  TForm1 = class(TForm)
  private
    procedure WndProc (var msg : TMessage); override;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.WndProc;
begin
if (msg.Msg = wm_syskeydown) then begin
  if (msg.wParam = vk_f4) and (msg.lParam and (1 shl 29) <> 0) then msg.Msg := wm_null;
end;
inherited;
end;

end.
srbenavrbe, the way you did it (as I understood)

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if (ssAlt in shift) and (key = vk_f4) then key := 0;
end;


Works fine, but disables 'close' only on pressing alt+f4 (user will still be able to close an application with his mouse).
This works only with onKeyDown event (not with onKeyUp), because form is closed when you press alt+f4, not release them.
You may also work with form's onShortCut event to get similar result as if working with onKeyDown event. onShortCut event occurs before any other with keyboard releated events. If you change 'Handled' variable to true in this event, other events (onKeyDown, onKeyUp, onKeyPress) will not 'see' that a key was pressed.

procedure TForm1.FormShortCut(var Msg: TWMKey; var Handled: Boolean);
begin
if (msg.CharCode = vk_f4) and (msg.KeyData and (1 shl 29) <> 0) then handled := true;
end;

msg.Msg will be the message (usually wm_keydown or wm_keyup) that is received. There's no need to check it in this case.