I have been trying to make SetKeyboardState press keys for an application, kind of just to see if it will work. Originally, I made this, because I thought scanf would block and I needed this to make keypresses

Code:
DWORD WINAPI ThreadRoutine(LPVOID lpParam)
{
    BYTE o[256];
    BYTE n[256];
    
    ::GetKeyboardState(o);
    ::CopyMemory(n, o, sizeof(o));

    n['A'] = 1;

    ::SetKeyboardState(n); // Make changes
    ::SetKeyboardState(o); // Restore old

    return 0;
}

int main(void)
{
    char junk;
    HANDLE hThread;
    
    hThread = ::CreateThread(NULL, 0, ThreadRoutine, NULL, 0, NULL);
	
    scanf("%c", &junk);

    ::WaitForSingleObject(hThread, INFINITE);
    ::CloseHandle(hThread);

    return 0;
}
But MSDN says something about 'the SetKeyboardState function alters the input state of the calling thread', so I guess that would not work? I then tried this with a win32 app that would recieve WM_KEYDOWN messages that might be generated by the API, buit it also fails.

Code:
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
        case WM_CREATE:
            ::SetTimer(hWnd, 0x1000, 100, NULL);

        case WM_TIMER:  
        {    
            BYTE o[256];
            BYTE n[256];
    
            ::GetKeyboardState(o);
            ::CopyMemory(n, o, sizeof(o));

            n['T'] = 1;

            ::SetKeyboardState(n); // Make changes
            ::SetKeyboardState(o); // Restore old

            break;
        }
    
                                
        case WM_DESTROY:

            ::KillTimer(hWnd, 0x1000);
            ::PostQuitMessage(WM_QUIT);
            break;

        case WM_KEYDOWN:

            TCHAR sZ[256];
            wsprintf(sZ, _T("%c"), wParam);

            ::MessageBox
                (hWnd, sZ, sZ, MB_OK);

            break;

        case WM_CLOSE:

            ::DestroyWindow(hWnd);
            break;

        default: return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
    }    
    return 0;
}
Is there something else I should be looking for when using this API?