Эмуляция нажатия клавиш в стороннем приложении - VB
Формулировка задачи:
Добрый день. Есть тестовое приложение, оно содержит один элемент меню, на котором висит shortcut(Ctrl+L) и командную кнопку. Если я нажимаю комбинацию клавиш Ctrl+L с клавиатуры, то появляется окно сообщения, что нажат пункт меню. Как сделать так, чтобы при нажатии на командную кнопку эмулировалось нажатие Ctrl+L для меню.
Эту задачу удается решить с помощью keybd_event, но необходимо в дальнейшем отправлять комбинацию в функцию окна, использую хэндл окна. Соответственно keybd_event по этой причине не подходит, как не подходит и отправка сообщения wm_command.
По идее, должен работать вариант с отправкой сообщений wm_keydown для каждой клавиши.
Например:
PostMessage хэндл окна, номер сообщения, vkkeycode(vk_control), lParam(содержит repeatcount и scancode)
PostMessage хэндл окна, номер сообщения, vkkeycode(vk_L), lParam(содержит repeatcount и scancode)
Но при этом ноль реакции.
Через spy++ смотрел сообщения клавиатуры. При физическом нажатии так же генерируются два keydown-а, как и при эмуляции через postmessage. Содержимое сообщений идентичны. Но, в обоих случаях так же появляется сообщение wm_char, они отличаются по содержимому wParam, lParam. wm_char я не отправляю, оно генерируется, как я понимаю defwindowproc. Буду признателен и благодарен за решение или направление в нужную сторону, т.к. ситуация тупиковая, на данный момент.
Решение задачи: «Эмуляция нажатия клавиш в стороннем приложении»
textual
Листинг программы
- Private Declare Function FindWindow Lib "user32" _
- Alias "FindWindowA" _
- (ByVal lpClassName As String, _
- ByVal lpWindowName As String) As Long
- Private Declare Function SendMessage Lib "user32" Alias _
- "SendMessageW" (ByVal hwnd As Long, ByVal wMsg As Long, _
- ByVal wParam As Long, lParam As Any) As Long
- 'функция GetMenu определяет форму с нужным меню
- Private Declare Function GetMenu Lib "user32" _
- (ByVal hwnd As Long) As Long
- 'функция GetSubMenu определяет заголовок меню _
- с которым будет идти работа
- Private Declare Function GetSubMenu Lib "user32" _
- (ByVal hMenu As Long, ByVal nPos As Long) As Long
- 'функция GetMenuItemID определяет пункт меню с которым
- 'будет идти работа
- Private Declare Function GetMenuItemID Lib "user32" _
- (ByVal hMenu As Long, ByVal nPos As Long) As Long
- Private Const WM_COMMAND As Long = &H111
- Private Sub Command1_Click()
- Dim hMenu&, hSubMenu&, hMenuItem& 'объявление переменых типом Long
- Dim hwnd As Long
- hwnd = FindWindow(vbNullString, "Target") ' Ищем жертву
- Print hwnd ' это для контроля, потом все Print можно удалить
- 'определяем на какой форме нам нужно меню
- hMenu = GetMenu(hwnd)
- Print hMenu
- 'определяем заголовок, если у Вас есть, например
- 'File и Edit, то индексом задаёте нужный
- hSubMenu = GetSubMenu(hMenu, 0)
- Print hSubMenu
- 'здесь мы определяем, что работать хотим с первым _
- пунктом меню, т.к. индекс равен 0
- hMenuItem = GetMenuItemID(hSubMenu, 0)
- Print hMenuItem
- ' клик по первому пункту
- SendMessage hwnd, WM_COMMAND, hMenuItem, ByVal 0&
- End Sub
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д