Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > имитация нажатия клавиш клавиатуры


Автор: Igoreck 11.3.2008, 11:59
С помощью какой функции  можно сымитировать нажатие клавиш клавиатуры.
Есть приложение на основе диалоговых окон, созданное с помощью  MFC (на VS 2005) . Задача, чтобы при клике мышкой  по экранной кнопке (т. е.  в функции OnBnClickedButton()   )  ,в случае если курсор стоит в EditBox,  стирался символ  - т.е. происходила имитация нажатия кнопки BkSp
Пробовал ф-цию OnKeyDown() – не работает 

Автор: korian 11.3.2008, 15:54
1) а в ручную делать этого нельзя? что-то типа
text = text.Left(text.GetLength() - 1)

2) для имитации нажатия клавиш можна использованть функцию keybd_event или SendInput.
можна еще посылать сообщения WM_KEYDOWN / WM_KEYUP

Автор: Igoreck 11.3.2008, 22:33
чтобы удалять вручную надо точно знать на каком символе в EditBox находится курсор ((  нам же не всегда надо удалять последний 
keybd_event   вроде под XP работать не будет ((   - если я правильно понял что написано в MSDN про нее  -  а  вот за SendInput()  спасиба - вроде то что надо  - только параметры которые надо туда передавать замороченные ( - ща разбираюсь с ее синтаксисом )  
 

Автор: korian 11.3.2008, 22:45
Цитата(Igoreck @  11.3.2008,  21:33 Найти цитируемый пост)
чтобы удалять вручную надо точно знать на каком символе в EditBox находится курсор 

для этого есть CEdit::GetSel

Автор: Igoreck 14.3.2008, 14:33
попробывал воспользоваться функцией SendInput(), ввел следующий код

void FIODlg::OnBnClickedButton50()
{
    // TODO: Add your control notification handler code here


            INPUT input1[1];
            memset (input1, 0, sizeof(input1));
            input1[0].type = INPUT_KEYBOARD;
            input1[0].ki.wVk = VK_BACK;
            SendInput(1, input1, sizeof(INPUT));


}

не работает (((
пробывал в качестве параметра wVk передавать другие значения для букавок (типа 0x31) и цифарок - не помогло,  в чем может быть причина ???  может в том что в момент нажатия кнопки на диалоговом окне фокус находится на кнопке а не на edit box'е ? 

Автор: korian 14.3.2008, 18:57
Цитата(Igoreck @  14.3.2008,  13:33 Найти цитируемый пост)
может в том что в момент нажатия кнопки на диалоговом окне фокус находится на кнопке а не на edit box'е

скорее всего.. проверить не проще чем спрашивать?   smile 
так а чем вам не нравится метод удаления символов по средставм использования CEdit::GetSel?

Автор: Earnest 14.3.2008, 19:37
Конечно в этом: сообщение направляется тому окну, которое в фокусе.
Через CEdit::GetSel можно, но не уверсально - мало ли какие клавиши захочется имитировать - умаешься все писать... Всего-то нужно передать фокус эдиту перед SenInput.
В принципе, можно и без SendInput - просто посылать WM_KEYDOWN, прямо эдиту, тогда можно без SetFocus

Автор: Dmi3ev 15.3.2008, 15:16
например надо нажать numlock
Код

keybd_event( VK_NUMLOCK, 0x45, KEYEVENTF_EXTENDEDKEY | 0, 0 );
keybd_event( VK_NUMLOCK, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);

такое надо?

Автор: Igoreck 16.3.2008, 23:52
а под XP разве функция keybd_event будет работать??? 


The keybd_event function synthesizes a keystroke. The system can use such a synthesized keystroke to generate a WM_KEYUP or WM_KEYDOWN message. The keyboard driver's interrupt handler calls the keybd_event function.

Windows NT/2000/XP/Vista:This function has been superseded. Use SendInput instead.        -   как я понял из описания в MSDN для XP  " эта функция была заменена . Используйте вместо нее SendInput"  -   вроде так  - хотя я не совсем уверен(

Автор: Dmi3ev 17.3.2008, 00:06
Цитата

а под XP разве функция keybd_event будет работать???

у меня работает, проверь! че спрашиваешь? (быстрее самому проверить)
ну как?

Автор: korian 17.3.2008, 01:21
Igoreck,
там написано только то, что если тебя не волнует совместимость с Win9x (и др не входящие в описанный список), то лучше используй SendInput.

Автор: Igoreck 17.3.2008, 17:35
навел фокус на edit box, добавив строчку   

  (CEdit*)GetDlgItem(IDC_EDIT3)->SetFocus();

где IDC_EDIT3 идентификатор моего Edit box' а  :


void FIODlg::OnBnClickedButton50()
{
    // TODO: Add your control notification handler code here


            (CEdit*)GetDlgItem(IDC_EDIT3)->SetFocus();

            INPUT input1[1];
            memset (input1, 0, sizeof(input1));
            input1[0].type = INPUT_KEYBOARD;
            input1[0].ki.wVk = VK_BACK;
            SendInput(1, input1, sizeof(INPUT));


}

не работет((

 попробывал заменить строку 
(CEdit*)GetDlgItem(IDC_EDIT3)->SetFocus();

на
 (CEdit*)m_PacF.SetFocus();   
 где m_PacF переменная управления(control) связанная с  Edit ' ом  - она имеет область видимости public   -    то же не работает (((


может я неправильно навожу фокус??
или указал не все параметры для функции   SendInput()

Автор: korian 17.3.2008, 21:58
Код

INPUT input1[2];
memset (input1, 0, sizeof(input1));

input1[0].type = INPUT_KEYBOARD;
input1[0].ki.wVk = VK_BACK;

input1[1].type = INPUT_KEYBOARD;
input1[1].ki.wVk = VK_BACK;
input1[1].ki.dwFlags = KEYEVENTF_KEYUP;

SendInput(2, input1, sizeof(input1[0]));

Автор: Igoreck 17.3.2008, 22:13
а зачем для кнопки "BK SP"  использовать KEYEVENTF_KEYUP ??   разве это нужно не только для кнопок , которые могут быть в двух положениях - нажато/отпущено   -  типа Caps Lock  ??


а с наведением фокуса я точно правильно делаю ? - мне показалось что косяк опять в фокусе(

Автор: korian 18.3.2008, 00:05
Igoreck, 
у всех кнопок есть состояние нажата/не нажата
caps lock и т.д. плюс к этому имеют еще состояния включено/выключено
нажали на кнопку на клаве - KEY_DOWN
отпустили кнопку на клаве - KEY_UP
с установлением фокуса по типу
GetDlgItem(IDC_EDIT3)->SetFocus(); - проблем не вижу.
кстати вариант
(CEdit*)GetDlgItem(IDC_EDIT3)->SetFocus();
рассматриваеться как 
(CEdit*)(GetDlgItem(IDC_EDIT3)->SetFocus());
насколько я понимаю.
а SetFocus есть и у CWnd, так шо приводить к CEdit смысла большого нету.

Автор: Igoreck 18.3.2008, 13:38
создал простое приложение состоящее из одного диалогового окошка , edit box' а   и  двух кнопок -  там все работает   ))

и фокус наводится любым из 4 способов:

GetDlgItem(IDC_EDIT3)->SetFocus(); 

(CEdit*)GetDlgItem(IDC_EDIT3)->SetFocus();

(CEdit*)m_PacF.SetFocus();   

m_PacF.SetFocus();   

и даже без задания  параметра dwFlags

и функция SendInput() то же работает 

а в общем приложении не работает -  значит ошибка в чем-то другом(((( 

Автор: Igoreck 26.3.2008, 13:01
создал в большом приложении новое диалогвое коно  - там то же заработало)

но возникла проблема - мне надо чтобы в edit box' е   отбражались русские букавки  -  для тех русских букавок, которые размещены на тех же клавишах что и английские - проблем нет - их VK коды я взял из файла winuser.h - а что делать с оставшимися : Б,Ю,Ж,Э,Х,Ъ ???? 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)