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

 
генерация сообщения о нажатии CTRL+Fx
Sashka
Отправлено: 12.01.2006, 15:41


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

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



Люди! Подсажите как послать в окно сообщение о нажатии клавиш CTRL+F6.
пробовал
SendMessage( hwnd_MainWindow1,
WM_HOTKEY, NULL,
LPARAM( LOWORD(MOD_CONTROL) | HIWORD( VK_F6 ) ) );
не срабатывает...
если посылать сообщения
PostMessage( hwnd_MainWindow1, WM_KEYUP, VK_F6, 0 );
PostMessage( hwnd_MainWindow1, WM_KEYUP, VK_CONTROL, 0 );
тоже не работает.
Может кто сталкивался, подскажите.
AVC
Отправлено: 13.01.2006, 09:08


Ветеран

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



CODE

/* Эмуляция нажатия клавиш в рамках одной триады
// VK_SHIFT(Shiht)  VK_CONTROL(Ctrl)  VK_MENU(Alt)
// VK_CAPITAL  VK_NUMLOCK  VK_SCROLL
unsigned char kbstate [256];
GetKeyboardState(kbstate);
kbstate[VK_SHIFT] = 0x80;  SetKeyboardState(kbstate);
PostMessage(Application->Handle, WM_KEYDOWN, VK_F1, 0);
kbstate[VK_SCROLL] = 0x01; SetKeyboardState(kbstate);
*/
Sashka
Отправлено: 13.01.2006, 11:29


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

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



Инетересный подход! А откуда вы брали значения 0х80 и 0х01 когда присваилвали элементам массива kbstate[VK_SHIFT] и kbstate[VK_SCROLL] ?
Sashka
Отправлено: 13.01.2006, 11:37


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

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



Аааа.. доперло!!! Когда старший бит взведен — клавиша нажата, когда младший бит — клавиша переключилась!
Огромное спасибо!!!
Sashka
Отправлено: 13.01.2006, 12:43


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

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



попробовал, как посоветовали...
не получилось... окно не реагирует почемуто sad.gif
Sashka
Отправлено: 13.01.2006, 15:34


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

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



Во! Нашел как мона это реализовать. Нашел на codenet.ru. Проверил — работает. Привожу пример на случай если кому пригодится:

CODE

  HWND hwnd_CurrWin;
  hwnd_CurrWin = GetForegroundWindow(); // сохраняем дескриптор текущего окна

  if( SetForegroundWindow(hwnd_MainWindow1) ) // Переводим фокус ввода на другое окно
  {
      INPUT inp[4];
      memset(inp, 0, sizeof(inp));

      //Нажимаем Ctrl
      inp[0].type = INPUT_KEYBOARD;
      inp[0].ki.wVk = VK_CONTROL;

      // Нажимаем F6
      inp[1].type = INPUT_KEYBOARD;
      inp[1].ki.wVk = VK_F7;

      // Отпускаем F6
      inp[2].type = INPUT_KEYBOARD;
      inp[2].ki.wVk = VK_F7;
      inp[2].ki.dwFlags = KEYEVENTF_KEYUP;

      // Отпускаем  Ctrl
      inp[3].type = INPUT_KEYBOARD;
      inp[3].ki.wVk = VK_CONTROL;
      inp[3].ki.dwFlags = KEYEVENTF_KEYUP;

      // Посылаем имитацию нажатия в систему
      SendInput(4,inp,sizeof(INPUT));
  }

  SetForegroundWindow( hwnd_CurrWin ); // Возвращаем фокус ввода исходному окну
AVC
Отправлено: 13.01.2006, 17:02


Ветеран

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



PostMessage(Application->Handle, WM_KEYDOWN, VK_F1, 0);
Вы какому окну посылали нажатия? В примере я посылал приложению и там же обрабатывал, а вам, скорее всего, нужно было подставить свое значение.
Ну получилось иначе и ладно. smile.gif

Демонстрационный код (работоспособный)
CODE

// Обработчик событий ПРИЛОЖЕНИЯ
void __fastcall TForm1::AppMessage (tagMSG &msg, bool &handled)
{
if (msg.wParam == VK_F1 && GetKeyState(VK_SHIFT) < 0)
{ Memo1->Lines->Add("shift+F1 is down");
handled = true;
return;
}
}

//---------------------------------------------------------------------------
// Обработчик событьй контрола

void __fastcall TForm1::Memo1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
if (Key == VK_F2)
{ Memo1->Lines->Add("F2 is down (Memo)");
Key = 0x00;
}
}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button6Click(TObject *Sender)
{
TMessageEvent oldOnMessage = Application->OnMessage; // сохранить старый обработчик
Application->OnMessage = AppMessage; // подставить свой обработчик

unsigned char kbstate [256];
GetKeyboardState(kbstate);
kbstate[VK_SHIFT] = 0x80; SetKeyboardState(kbstate);
PostMessage(Application->Handle, WM_KEYDOWN, VK_F1, 0); // послать shiftF1 ПРИЛОЖЕНИЮ

Application->ProcessMessages(); // обработать все события из очереди

kbstate[VK_SHIFT] = 0x00; SetKeyboardState(kbstate);
Application->OnMessage = oldOnMessage; // восстановить старый обработчик

PostMessage(Memo1->Handle, WM_KEYDOWN, VK_F2, 0); // послать F2 окну (контролу Memo)
}


Отредактировано AVC — 13/01/2006, 16:26
Sashka
Отправлено: 13.01.2006, 17:28


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

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



Уважаемый AVC! Я прошу прощения, что не очень точно сформулировал свой вопрос. Мне действительно нужно было сгенерировать сообщение о нажатии клавиш CTRL+F6, но не для своего приложения, а для чужого.
Поэтому в ваш пример я честно подставил дескриптор окна другого приложения, но ничего не произошло, что и толкнуло меня на дальнейшие поиски...
Правда, мне не очень понятно почему не сработало... я думал это достаточно универсальный метод
Guest
Отправлено: 13.01.2006, 17:39


Не зарегистрирован







Вы просмотрели строчку с ограничением
Эмуляция нажатия клавиш в рамках одной триады

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