I want to override the normal keypress event Alt+F4 in my application.
I am using borland builder 6.
i wrote a fn for Application->OnMessage = msghandler;
In this handler I am checking for the Key State of the Alt & F4 & then if the key is pressed I am calling some fns. This works fine. But when I press Alt+F4 the function gets called a lot of times if the key is pressed normally. I want my fn to be called only once. Is the way that I have handled correct or should i try to handle this in some other way? Please help!!!

here is my code

msghandler(tagMSG &message, bool &handled)
{
   short shRet;
   shRet = GetAsyncKeyState(VK_MENU);
   bool bVal = (shRet >> 1)&& 1;
   short key = GetAsyncKeyState(VK_F4);
   bool keyState = (key >> 1)&& 1;

   if(bVal == true && keyState == true)
   {
      handled = true;
      // I am calling my fns here which has to be called on press of Alt+F4
   }
}

Dani AI

Generated

Short answer: the repeated calls are normal (keyboard auto-repeat) and the reliable fix is to handle the Windows key message and ignore repeats, or to intercept the close command instead of polling keys with GetAsyncKeyState. ’s Application->OnMessage + GetAsyncKeyState approach will see the key held down repeatedly; Windows also posts repeated WM_SYSKEYDOWN/WM_KEYDOWN messages while a key is held. See the WM_SYSKEYDOWN docs and GetAsyncKeyState behavior for details. (learn.microsoft.com)

Practical, low-risk options (examples use C++Builder/VCL):

  • Message-based, once-per-press: use Application->OnMessage and check for WM_SYSKEYDOWN (or WM_KEYDOWN for non-ALT combos). Inspect lParam’s previous-key-state bit (bit 30) to only act on the first down transition and then set Handled = true to swallow the message so the default close doesn’t happen.
void __fastcall TForm1::AppMessage(tagMSG &Msg, bool &Handled)
{
  if (Msg.message == WM_SYSKEYDOWN && Msg.wParam == VK_F4) {
    if ((Msg.lParam & (1UL << 30)) == 0) { // first keydown, not autorepeat
      DoMyAltF4Action();
    }
    Handled = true; // prevent default close
  }
}

The previous-key-state / autorepeat behavior is described in the Windows keyboard-message docs. (learn.microsoft.com)

  • Intercept the close command: Alt+F4 is translated to a system close command, so you can handle WM_SYSCOMMAND (SC_CLOSE) or use the form’s OnCloseQuery to run your function and cancel closing when appropriate. OnCloseQuery is the VCL-friendly place to allow/cancel a close without fighting low-level msg flow. Example patterns:
void __fastcall TForm1::WndProc(Messages::TMessage &Message)
{
  if (Message.Msg == WM_SYSCOMMAND && ((Message.WParam & 0xFFF0) == SC_CLOSE)) {
    DoMyAltF4Action();
    Message.Result = 0; // swallow
    return;
  }
  TForm::WndProc(Message);
}

or

void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose)
{
  DoMyAltF4Action();
  CanClose = false; // block closing if that is the intent
}

See the WM_SYSCOMMAND and VCL OnCloseQuery documentation for details. (learn.microsoft.com)

A UX note (echoing ): users expect Alt+F4 to close an app. Only override it in tightly controlled scenarios; prefer OnCloseQuery if you need to prompt or cancel close, and use the lParam previous-state test when you really need a single-call on key press (it also covers Alt+arrow combos since those are syskeys).

Recommended Answers

All 2 Replies

Alt-F4 is used by the system to terminate an application. Users expect this. (Don't do things that users don't expect.)

You might want to look at the OnClose and OnCanClose events if you just want to do cleanup before the application terminates or to prevent the application from terminating under some circumstances.

Be warned, though. Programs that can't be stopped make people very angry.

Good luck.

Alt-F4 is used by the system to terminate an application. Users expect this. (Don't do things that users don't expect.)

You might want to look at the OnClose and OnCanClose events if you just want to do cleanup before the application terminates or to prevent the application from terminating under some circumstances.

Be warned, though. Programs that can't be stopped make people very angry.

Good luck.

True one must not not manipulate the Alt+F4. But in a particular scenario, I want to override that key press to call some other function. At this particular scenario I do not want my application to be closed, instead perform my function. Also I am using the Alt+Arrow keys to call my functions which cause the same scenario which I have mentioned in my earlier post.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.