C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Эмуляция нажатия VK_TAB
olegenty
Отправлено: 30.03.2004, 12:31


Ветеран

Группа: Модератор
Сообщений: 2412



Суть: заказчик, блин, привык переходить от поля к полю по нажатию "Enter" (VK_RETURN). В каждом поле прописывать обработчик OnKeyDown — несерьёзно.
Попробовал написать обработчик для формы в целом, следующего содержания:
CODE

{
   if (Key == VK_RETURN)
   {
       Key = 0;
       SendMessage(Form->ActiveControl->Handle, WM_KEYDOWN, VK_TAB, 0);
   }
}

По идее должно сэмулироваться нажатие на Tab, и произойти переход на след. контрол. В чём моя ошибка?
olegenty
Отправлено: 30.03.2004, 12:32


Ветеран

Группа: Модератор
Сообщений: 2412



свойство формы KeyPreview выставлено
BUBL1n
  Отправлено: 30.03.2004, 12:39


Ученик-кочегар

Группа: Участник
Сообщений: 10



Под CLX я делал так:

CODE

void __fastcall T_MY_DEAR_FORM::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
switch (Key)
{
 case Key_Enter: case Key_Return: case Key_Tab:
 {
  FindNextControl(FocusedControl,true,true,false)->SetFocus();
  break;
 }
}
case Key_Up:
{
 FindNextControl(FocusedControl,false,true,false)->SetFocus(); break;}
}
}
olegenty
Отправлено: 30.03.2004, 13:05


Ветеран

Группа: Модератор
Сообщений: 2412



Спасибо. Работает. Для не CLX это выглядит следующим образом:
CODE

void __fastcall TfmUnitFields::FormKeyDown(TObject *Sender, WORD &Key,
     TShiftState Shift)
{
   switch (Key)
   {
       case VK_RETURN:
           Key = 0;
           FindNextControl(ActiveControl, true, true, true)->SetFocus();
           break;
   }
}
olegenty
Отправлено: 30.03.2004, 13:12


Ветеран

Группа: Модератор
Сообщений: 2412



Поправка:
CODE

void __fastcall TfmUnitFields::FormKeyDown(TObject *Sender, WORD &Key,
    TShiftState Shift)
{
   if (ActiveControl == buOk) return; // Кнопка ОК
   switch (Key)
   ...
olegenty
Отправлено: 30.03.2004, 15:47


Ветеран

Группа: Модератор
Сообщений: 2412



Хрен там
Если активный контрол лежит на панели, то это не работает, ибо метод FindNextControl наследников TWinControl находится в закрытой секции. Блин, а ведь чуть не обрадовался.
Asher
Отправлено: 30.03.2004, 16:18


Мастер участка

Группа: Модератор
Сообщений: 550



Так достань его оттуда. biggrin.gif
заведи класс — наследник TWinControl у которого опубликуй это свойство, а в нужном месте приводи свой указатель к этому классу.
что-то типа
CODE

class TMyPublicWinControl  :public TWinControl
{
public:
 TWinControl* __fastcall FindNextControl(TWinControl* CurControl, bool   GoForward, bool CheckTabStop, bool CheckParent){};
};

TMyPublicWinControl* l_pTemp = dynamic_cast<TMyPublicWinControl*>(указатель на твой контрол);
if (l_pTemp != NULL)
 l_pTemp->FindNextControl(ActiveControl, true, true, true)->SetFocus();


P.S. это если я правильно понял твою проблему biggrin.gif
olegenty
Отправлено: 31.03.2004, 07:04


Ветеран

Группа: Модератор
Сообщений: 2412



Спасибо, я так и сделаю, но хотелось как-нибудь попроще )).
Интересно, а приведётся ли указатель? В общем, попробую и отпишу.
olegenty
Отправлено: 31.03.2004, 08:31


Ветеран

Группа: Модератор
Сообщений: 2412



Извиняюсь, я просто идиот. Последний параметр должен быть false, а я его в true высталял.

CODE

void __fastcall TfmUnitFields::FormKeyDown(TObject *Sender, WORD &Key,
    TShiftState Shift)
{
  if (ActiveControl == buOk) return; // Тут должно быть то, что не должно обрабатываться
  switch (Key)
  {
      case VK_RETURN:
          Key = 0;
          if (TWinControl *pNext = FindNextControl(ActiveControl, true, true, false))
          {
              pNext->SetFocus();
          }
          break;
  }
}


это окончательный рабочий вариант. всем рекомендую чиать доки, а тут сам лоханулся, тем более, что в примере для CLX стоит именно false.
Gedeon
Отправлено: 20.10.2004, 08:43


Ветеран

Группа: Модератор
Сообщений: 1742



Я тут MSDN маленько подчитал и вот что удалось найти
CODE

VOID keybd_event(          BYTE bVk,
   BYTE bScan,
   DWORD dwFlags,
   PTR dwExtraInfo
);

Вот написал для формы маленькую функцию нажимающую кнопки
CODE

void __fastcall TForm1::SendKey(BYTE KeyCode)
{
   // Simulate a key press
        keybd_event( KeyCode,
                     0x45,
                     KEYEVENTF_EXTENDEDKEY | 0,
                     0 );

     // Simulate a key release
        keybd_event( KeyCode,
                     0x45,
                     KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
                     0);

}
//---------------------------------------------------------------------------
//и вызов
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   SendKey(VK_TAB);
}
//---------------------------------------------------------------------------

Ваш пример честно говоря лениво повторять, но думаю работать будет, аналогично можно смотреть
mouse_event для крысы, а также
CODE

UINT SendInput(          UINT nInputs,
   LPINPUT pInputs,
   int cbSize
);


Вот так, век живи — век учись.

Вернуться в Вопросы программирования в C++Builder