Недавно созданный рабочий стол не получает события клавиатуры

Я создал небольшую программу, которая запускается на новом рабочем столе.

HDESK hDesktop = ::CreateDesktop(strDesktopName.c_str(),
NULL, // Reserved
NULL, // Reserved
0, // DF_ALLOWOTHERACCOUNTHOOK
GENERIC_ALL,
NULL); // lpSecurity
::SetThreadDesktop(hDesktop);

Позже, запустил другое приложение на этом рабочем столе, используя следующие строки:

PROCESS_INFORMATION pi = { 0 };
STARTUPINFO         si = { 0 };

si.cb = sizeof(si);
si.lpDesktop = &strDesktop[0];
if (FALSE == ::CreateProcess(pathModuleName.file_string().c_str(), L"abc def", NULL, NULL,      FALSE, 0, NULL, NULL, &si, &pi))
return false;

DWORD dwWaitRes = ::WaitForSingleObject(pi.hProcess, INFINITE);

pathModuleName это собственное местоположение, полученное GetModuleFileName(NULL),

Вновь созданное приложение получает HWND в другое окно и отправляет оконные сообщения, используя следующие команды:

// bring window to front
::SetForegroundWindow(hwnd);

// set focus so keyboard inputs will be caught
::SetFocus(hwnd);
::keybd_event(VK_MENU, 0x45, KEYEVENTF_EXTENDEDKEY | 0, 0);
...

Так что в основном приложение A на рабочем столе DEFAULT запускается приложение B на рабочем столе X, который получает HWND для другого приложения C началось на том же рабочем столе X.

Моя проблема в том, что события клавиатуры поступают из приложения B на рабочем столе X не запускаются в приложении C, Только если я использую SwitchDesktop(B), затем события запускаются и код выполняется правильно.

Что мне не хватает?

6

Решение

Вы пытаетесь смоделировать пользовательский ввод на рабочем столе, который не активен на физической консоли (экран, мышь, клавиатура), который вряд ли будет работать, и почему SwitchDesktop() заставляет это работать. Согласно документации:

Функция SwitchDesktop

Делает указанный рабочий стол видимым и активирует его. Это позволяет рабочему столу получать входные данные от пользователя.

keybd_event(), mouse_event(), SendInput()все они просто генерируют и сохраняют входные сообщения в той же очереди ввода, в которую физическая мышь / клавиатура публикует свои сообщения. Система ввода не знает разницы между пользовательским вводом и синтезированным вводом при отправке входных сообщений приложениям.

Раймонд Чен затронул это в своем блоге:

Как мне симулировать ввод без SendInput?

SendInput работает на нижнем уровне стека ввода. Это просто бэкдор в тот же механизм ввода, который используют драйверы клавиатуры и мыши, чтобы сообщить диспетчеру окон, что пользователь сгенерировал ввод. Функция SendInput не знает, что будет с входом. Это обрабатывается гораздо более высокими уровнями оконного менеджера, такими как компоненты, которые проверяют ввод мыши, чтобы увидеть, в какое окно сообщение должно быть первоначально доставлено.

Он также опубликовал небольшую диаграмму в другой статье блога, показывающую, где SendInput() сидит относительно входной очереди:

Когда что-то добавляется в очередь, требуется время, чтобы оно вышло из очереди

диаграмма

7

Другие решения


По вопросам рекламы [email protected]