SendInput() не производит никакого видимого вывода

У меня проблемы с получением SendInput для получения любого вида вывода. Все структуры определены следующим образом (я не использовал мышь и оборудование):

[StructLayout(LayoutKind.Explicit)]
    public struct INPUT
    {
        [FieldOffset(0)]
        public int type;
        [FieldOffset(8)]
        public MOUSEINPUT mi;
        [FieldOffset(8)]
        public KEYBDINPUT ki;
        [FieldOffset(8)]
        public HARDWAREINPUT hi;
    }

[StructLayout(LayoutKind.Sequential)]
    public struct KEYBDINPUT
    {
        public ushort wVk;
        public ushort wScan;
        public uint dwFlags;
        public uint time;
        public IntPtr dwExtraInfo;
    }

Высылаю ключи следующим образом:

SetForegroundWindow(hProc); // using user32.dll switch to desired process
// send keydown 
INPUT iKeyDown = new INPUT();
KEYBDINPUT sKeysDown = new KEYBDINPUT();
iKeyDown.type = KEYBD_INPUT_TYPE;
iKeyDown.ki = sKeysDown;
sKeysDown.wVk = 0;
sKeysDown.wScan = (ushort)0x1E;
sKeysDown.dwFlags = 0x0008 ;
sKeysDown.time = 0;
sKeysDown.dwExtraInfo = GetMessageExtraInfo();

Я отправляю событие Key Up точно так же, за исключением свойства dwFlags:

sKeysUp.dwFlags = 0x0008 | 0x0002;

Ну наконец то,

INPUT[] aInputs = new INPUT[] { iKeyDown, iKeyUp };
uint result = SendInput(2, aInputs, Marshal.SizeOf(iKeyDown));  // when dll importing, SetLastError = true 
int error = Marshal.GetLastWin32Error();
Debug.WriteLine(result.ToString() + " " + error.ToString());

Результатом этого является отсутствие видимого вывода, переменная результата всегда равна 2 (количество успешных входов), а GetLastWin32Error() возвращает 0 (согласно кодам ошибок, это успех). Есть ли что-то, что мне здесь не хватает? Ваше здоровье!


person AlexanderM    schedule 22.07.2014    source источник
comment
Ваш вызов SetForegroundWindow() не работает. Никогда не игнорируйте возвращаемое значение функций winapi. Требуется дескриптор окна, а не дескриптор процесса.   -  person Hans Passant    schedule 23.07.2014
comment
@HansPassant Я думаю, это тот случай, когда неправильно названа переменная. Я получаю его, используя `FindWindow(null, WINDOW_HEADER_NAME), и это дескриптор окна, а не что-то еще. Он работает как положено, возвращает True. Вероятно, мне следует переименовать эту переменную.   -  person AlexanderM    schedule 23.07.2014
comment
@Lambdaλ MouseInput, KeyboardInput, HardwareInput являются объединением. Посмотрите здесь — msdn.microsoft .com/en-us/library/windows/desktop/   -  person AlexanderM    schedule 23.07.2014
comment
@PsyXandeR Вы все равно делаете это неправильно.   -  person GSerg    schedule 23.07.2014
comment
Вы игнорируете возвращаемые значения вызовов. Нехорошо. Профсоюз должен быть сделан по пути Рэймонда. Намного проще использовать SendKeys. Или автоматизация. Возможно, другому приложению не нравится поддельный ввод. Вы проверили с помощью Блокнота, верно?   -  person David Heffernan    schedule 23.07.2014


Ответы (1)


И я ответил на свой вопрос - я неправильно заполнял структуры. Вместо

INPUT iKeyDown = new INPUT();
KEYBDINPUT sKeysDown = new KEYBDINPUT();
iKeyDown.type = KEYBD_INPUT_TYPE;
iKeyDown.ki = sKeysDown;
sKeysDown.wVk = 0; // etc

я должен был делать

INPUT iKeyDown = new INPUT();
iKeyDown.type = KEYBD_INPUT_TYPE;
iKeyDown.ki.wvK = 0; // etc

вместо. Этот новый KEYBDINPUT() все испортил. Я также поместил объединение Mouse/Keyboard/Hardware в отдельную структуру, как предложил GSerg. Теперь он работает как задумано.

person AlexanderM    schedule 23.07.2014