locked
Why we need to use the GetKeyboardState function before and after the call to ::SetForegroundWindow(HWND) function? RRS feed

  • Question

  • Hello All,

    We are using the below function to bring the specified window into the foreground.

    I Wanted to know why we need to use the GetKeyboardState before and after the call to ::SetForegroundWindow(hWnd);?

    Below is the code snippet:

    void CMyClassImpl::SetForegroundWindowInternal(HWND hWnd)
    {
        if(!::IsWindow(hWnd)) return;

        BYTE keyState[256] = {0};
        //to unlock SetForegroundWindow we need to imitate Alt pressing
        if(::GetKeyboardState((LPBYTE)&keyState))
        {
            if(!(keyState[VK_MENU] & 0x80))
            {
                ::keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
            }
        }
        ::SetForegroundWindow(hWnd);

        if(::GetKeyboardState((LPBYTE)&keyState))
        {
            if(!(keyState[VK_MENU] & 0x80))
            {
                ::keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
            }
        }
    }

    Could someone please help me to understand this?

    Thanks in advance,

    Sunday, June 21, 2020 6:23 AM

Answers

  • Hello,

    Thank you for posting here.

    >> Why we need to use the GetKeyboardState function before and after the call to ::SetForegroundWindow(HWND) function?

    First of all, the system will limit the process of setting the foreground window. Only when the following conditions are met can we set a process as the foreground window.

    The process is the foreground process.

    The process was started by the foreground process.

    The process received the last input event.

    There is no foreground process.

    The foreground process is being debugged.

    The foreground is not locked (see LockSetForegroundWindow).

    The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).

    No menus are active.

    The system automatically enables calls to SetForegroundWindow if the user presses the ALT key or takes some action that causes the system itself to change the foreground window (for example, clicking a background window).

    So we can use this function to prevent changes by other applications, interrupt the interaction with the user, and ensure that the required process is switched to the foreground. 

    Hope my solution could be helpful.

    Best regards,

    Song Zhu


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, June 24, 2020 2:36 AM

All replies


  • I Wanted to know why we need to use the GetKeyboardState before and after the call to ::SetForegroundWindow(hWnd);?

    You don't need to do that (you can test with Notepad)

    And Task Manager uses SwitchToThisWindow


    • Edited by Castorix31 Sunday, June 21, 2020 7:06 AM
    Sunday, June 21, 2020 7:06 AM
  • Circumventing the Windows API restrictions on SetForegroundWindow is a questionable practice.  Why do you think that these restrictions exist?

    Lets say that a user is busy editing an important document.  The user is not looking at the screen but is reading from the data source and typing.  Without their knowledge, the foreground window switches and they are no longer entering data into their document.   Unaware that the keyboard focus has shifted, they continue typing.  These keystrokes may be ignored by the window that is now in the foreground or could possibly result in some unexpected behavior.  Regardless, some amount of work has been lost and a very unhappy and possibly very angry user is the likely result.

    Think about it.

    Sunday, June 21, 2020 10:51 AM
  • Hello,

    Thank you for posting here.

    >> Why we need to use the GetKeyboardState function before and after the call to ::SetForegroundWindow(HWND) function?

    First of all, the system will limit the process of setting the foreground window. Only when the following conditions are met can we set a process as the foreground window.

    The process is the foreground process.

    The process was started by the foreground process.

    The process received the last input event.

    There is no foreground process.

    The foreground process is being debugged.

    The foreground is not locked (see LockSetForegroundWindow).

    The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).

    No menus are active.

    The system automatically enables calls to SetForegroundWindow if the user presses the ALT key or takes some action that causes the system itself to change the foreground window (for example, clicking a background window).

    So we can use this function to prevent changes by other applications, interrupt the interaction with the user, and ensure that the required process is switched to the foreground. 

    Hope my solution could be helpful.

    Best regards,

    Song Zhu


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, June 24, 2020 2:36 AM