Assume you have an MFC application. The solution is to override the virtual function:
virtual BOOL CWinApp::ProcessMessageFilter(int code, LPMSG lpMsg);
The following code demonstrates:
BOOL CMyProgramApp::ProcessMessageFilter(int code, LPMSG lpMsg){ if(WM_SYSKEYDOWN == lpMsg->message) { if(VK_F4 == lpMsg->wParam) { //Eliminate Alt+F4 if(::GetKeyState(VK_MENU) < 0) { //Do nothing return TRUE; //We are processing, not the System } } } return CWinApp::ProcessMessageFilter(code, lpMsg);}
You can also check if the action is from a given dialog or control in that dialog. You can also use the Alt+F4 key combination for other purposes. For instance, you could replace it with a rarely-used key, like Alt+F24, which is not possible from a standard keyboard.
BOOL CMyProgramApp::ProcessMessageFilter(int code, LPMSG lpMsg){ if(m_hwndDialog != NULL) { if((lpMsg->hwnd == m_hwndDialog) || ::IsChild(m_hwndDialog,lpMsg->hwnd)) { if(WM_SYSKEYDOWN == lpMsg->message) { if(VK_F4 == lpMsg->wParam) { //Eliminate Alt+F4 if(::GetKeyState(VK_MENU) < 0) { //Use VK_F24 instead VK_F4, in this way Alt+F4 can be used forother purposes ::PostMessage(lpMsg->hwnd, WM_SYSKEYDOWN, VK_F24,lpMsg->lParam); //We are processing, not the System return TRUE; } } } } } // Default processing of the message. return CWinApp::ProcessMessageFilter(code, lpMsg);}
Note: Only the combinations Alt+F4 and Alt+Shift+F4 are interpreted as System Keys that close the window. The combinations Ctrl+Alt+F4 and Shift+Ctrl+Alt+F4 are not detected, in these cases F4 goes strangely as TAB.