Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема с SendInput 
:(
    Опции темы
under_sun
Дата 5.11.2008, 22:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 141
Регистрация: 3.10.2007
Где: Ебург

Репутация: нет
Всего: 17



Приветствую.

Следующий код делает окно с дискриптором g_hWnd активным и посылает туда комбинацию клавиш Shift+O:
Код

LPARAM extraInfo = GetMessageExtraInfo();

INPUT keys[2] = { 
    { INPUT_KEYBOARD, { VK_SHIFT, 0, 0, 0, extraInfo } },
    { INPUT_KEYBOARD, { VkKeyScan('О'), 0, 0, 0, extraInfo } }
};

if ( IsIconic ( g_hWnd ) )
    ShowWindow( g_hWnd, SW_SHOWNORMAL );
        
SetForegroundWindow( g_hWnd );
    
SendInput( 2, keys, sizeof( INPUT ) );

Проблема в следующем: если мы посылаем комбинацию этих клавиш, например, в блокнот, то нормально печатается 'O'. Но если затем начинаем там набирать текст, то продолжают печататься заглавные буквы, как-будто Shift продолжает быть в нажатом состоянии.
Если использовать AttachThreadInput( GetWindowThreadProcessId( g_hWnd, NULL), GetCurrentThreadId(), TRUE ), ситуация та же.
Что я делаю не так?

--------------------
TMTOWTDI
PM MAIL ICQ   Вверх
GremlinProg
Дата 6.11.2008, 01:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(under_sun @  6.11.2008,  00:13 Найти цитируемый пост)
то продолжают печататься заглавные буквы, как-будто Shift продолжает быть в нажатом состоянии

так и есть, поскольку код отпускания клавиш отсутствует.
Код

typedef struct tagKEYBDINPUT {
    WORD wVk;
    WORD wScan;
    DWORD dwFlags;
    DWORD time;
    ULONG_PTR dwExtraInfo;
} KEYBDINPUT, *PKEYBDINPUT;

ключевые поля: wVk и dwFlags.
флаг KEYEVENTF_KEYUP отпускает клавишу, если он отсутствует, значит клавиша нажата.
если для обычных клавиш это не так важно, то для управляющих, таких как Ctrl, Shift, Caps и т.п. это существенно.
у тебя получается, что SHIFT залипла.

добавь код, отпускающий шифт.


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
under_sun
Дата 6.11.2008, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 141
Регистрация: 3.10.2007
Где: Ебург

Репутация: нет
Всего: 17



Сделал так:
Код

INPUT keys[2] = { 
    { INPUT_KEYBOARD, { VK_SHIFT, 0, KEYEVENTF_KEYUP, 0, extraInfo } },
    { INPUT_KEYBOARD, { VkKeyScan('O'), 0, 0, 0, extraInfo } }
};

Не знаю почему, но проблема осталась.
Пробовал еще так:
Код

INPUT keys[2] = { 
    { INPUT_KEYBOARD, { VK_SHIFT, 0, KEYEVENTF_KEYUP, 0, extraInfo } },
    { INPUT_KEYBOARD, { VkKeyScan('O'), 0, KEYEVENTF_KEYUP, 0, extraInfo } }
};

Где подвох smile?

--------------------
TMTOWTDI
PM MAIL ICQ   Вверх
GremlinProg
Дата 6.11.2008, 23:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(under_sun @  7.11.2008,  00:23 Найти цитируемый пост)
Где подвох

все там же
Код

INPUT keys[] = { 
    { INPUT_KEYBOARD, { VK_SHIFT, 0, 0, 0, 0 } },
    { INPUT_KEYBOARD, { VkKeyScan('O'), 0, 0, 0, 0 } }
    { INPUT_KEYBOARD, { VK_SHIFT, 0, KEYEVENTF_KEYUP, 0, 0 } },
    { INPUT_KEYBOARD, { VkKeyScan('O'), 0, KEYEVENTF_KEYUP, 0, 0 } }
};



--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
under_sun
Дата 7.11.2008, 00:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 141
Регистрация: 3.10.2007
Где: Ебург

Репутация: нет
Всего: 17



Проверил, все равно Shift залипает. Кроме того надо одну 'O' печатать.
--------------------
TMTOWTDI
PM MAIL ICQ   Вверх
GremlinProg
Дата 7.11.2008, 00:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Код

SendInput( 4, keys, sizeof( INPUT ) );


Добавлено через 3 минуты и 18 секунд
попробуй keybd_event

Добавлено через 11 минут и 32 секунды
ну или 'O' вместо VkKeyScan('O')
Цитата

The VkKeyScan function translates a character to the corresponding virtual-key code and shift state for the current keyboard.



--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
under_sun
Дата 11.11.2008, 19:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 141
Регистрация: 3.10.2007
Где: Ебург

Репутация: нет
Всего: 17



GremlinProg, спасибо. 
С keybd_event заработало. Но я так и не понял причины, почему с SendInput не работает.
--------------------
TMTOWTDI
PM MAIL ICQ   Вверх
dumb
Дата 11.11.2008, 20:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 27
Всего: 158



Цитата(under_sun @  11.11.2008,  20:52 Найти цитируемый пост)
Но я так и не понял причины, почему с SendInput не работает. 
потому что желательна хотя бы минимальная задержка между "нажатием" и "отпусканием". поэтому и между keybd_event обычно Sleep'ы ставят небольшие. а ты все в одном пакете.
PM MAIL   Вверх
GremlinProg
Дата 11.11.2008, 22:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



не, дело не в задержке, смотрим определение союза:
Код

typedef struct tagINPUT { 
  DWORD type; 
  union {MOUSEINPUT mi; 
            KEYBOARDINPUT ki;
            HARDWAREINPUT hi;
           };
  }INPUT, *PINPUT;

typedef struct tagMOUSEINPUT {
    LONG dx;
    LONG dy;
    DWORD mouseData;
    DWORD dwFlags;
    DWORD time;
    ULONG_PTR dwExtraInfo;
} MOUSEINPUT, *PMOUSEINPUT;

typedef struct tagKEYBDINPUT {
    WORD wVk;
    WORD wScan;
    DWORD dwFlags;
    DWORD time;
    ULONG_PTR dwExtraInfo;
} KEYBDINPUT, *PKEYBDINPUT;

суть в том, что в союзе первый член типа MOUSEINPUT, у которого первые два поля типа LONG
в союзах агрегатаов инициализация идет сначала, т.е. первый компонент союза, второй, и т.д., следовательно KEYEVENTF_KEYUP пишется не в поле dwFlags, а в поле mouseData, которое находится по большему смещению. отсюда и залипание клавиш.

вот в таком варианте и SendInput работает
Код

INPUT keys[4];
::memset(keys,0,sizeof(keys));

keys[0].type        = INPUT_KEYBOARD;
keys[0].ki.wVk        = VK_SHIFT;
keys[0].ki.dwFlags    = 0;

keys[1].type        = INPUT_KEYBOARD;
keys[1].ki.wVk        = 'O';
keys[1].ki.dwFlags    = 0;

keys[2].type        = INPUT_KEYBOARD;
keys[2].ki.wVk        = 'O';
keys[2].ki.dwFlags    = KEYEVENTF_KEYUP;

keys[3].type        = INPUT_KEYBOARD;
keys[3].ki.wVk        = VK_SHIFT;
keys[3].ki.dwFlags    = KEYEVENTF_KEYUP;

::SendInput(4,keys,sizeof(keys[0]));

ничего не залипает

Это сообщение отредактировал(а) GremlinProg - 11.11.2008, 22:57


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0499 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.