Кликнуть в скрытое окно
От: Cannol  
Дата: 24.07.19 10:20
Оценка:
Прошу подсказать, как правильно кликать в скрытое окно!
Есть подобие виртуальной кабины автомобиля и там я моделирую планшет (как электронный гаджет) возле приборной панели. Надо, чтобы веб-браузер был отрисован на экране этого виртуального планшета.
Для этого:

1. Пришлось для браузера создать отдельное 2Д окно, и делаю я его неотображаемым (SW_HIDE, или вот щас WS_EX_TRANSPARENT), в том же потоке:
hWndMain = CreateWindowEx(WS_EX_TRANSPARENT, szWndClassMain, szWndTitleMain, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, wWndWidth, wWndHeight, NULL, NULL, hInst, NULL);

2. Туда вывожу работу браузера (простейший проект на IWebBrowser2, это как "Internet Explorer");

3. Захватываю содержимое этого скрытого окна, используя PrintWindow(),
(При этом, когда SW_HIDE, получается просто чёрный экран. И пришлось, перед тем как сграбить, менять окно на SW_SHOWNORMAL или щас на SW_SHOWNOACTIVATE, а потом сразу возвращать на SW_HIDE.)

4. Полученный Bitmap загружаю в DirectX окно: m_pRenderTarget->DrawBitmap();
До сих пор всё хорошо!

Сейчас который день мучаюсь над другой проблемой:
надо реализовать мышиные клики от пользователя. Т.е. юзер кликает в том DirectX окне по ссылкам на веб-страничке, а фактически всего лишь на Bitmap картинку от неё в DirectX.
И надо из этой DirectX-картинки переслать событие клика на само IWebBrowser2 окно. (А потом снова сграбить новое состояние страницы и показать bitmap в 3D.)
Думалось, есть небось какая-нибудь готовая функция типа webBrowser2->Navigate(хPos, уPos), но увы, такой не нашлось.

Поэтому пришлось транслировать координаты, и отправлять сообщения в то скрытое окно. Перепробовал много вещей, ничто не помогает:
I. Когда окно предварительно делаю активным и видимым (ShowWindow(hwnd, SW_SHOWNOACTIVATE); SetActiveWindow(hwnd)), тогда SetCursorPos() и SendInput() работают хорошо — клик отправляется, браузер меняет страницу, я ее снова граблю и т.д..
II. Когда к этому коду добавляю в самом конце скрытие окна (SW_HIDE), всё перестаёт работать, т.е. браузер больше не получает клики! Очень странно, я ведь событие отправил до вызова SW_HIDE!
Вот конец кода обработки клика:
    ...
    SendInput(1,&input,sizeof(INPUT)); //call SendInput, pass in input to unclick
    ClipCursor(&rcOldClip); // Restore the cursor to its previous area.
    SetCursorPos(ptOld.x, ptOld.y); // Restore previous coordinates of the cursor.
    ShowWindow(hwnd, SW_HIDE);

Вариант I не годится никак, потому что показывать на экране это 2D окно браузера мне никак не надо!

III. Не показывая окна вообще на экран (всегда SW_HIDE) пытаюсь посылать сообщения по-разному (SendMessage/PostMessage) — вообще глухо, ни один вариант не работает. Вот код:
...
else if (byCodeOption == 2)
{
    // Option B1
    SendMessage(hwnd, WM_LBUTTONDOWN, pt.x, pt.y);
    Sleep(10);
    SendMessage(hwnd, WM_LBUTTONUP, pt.x, pt.y);
}
else if (byCodeOption == 4)
{
    // Option B2
    SendMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(pt.x, pt.y));
    Sleep(10);
    SendMessage(hwnd, WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM(pt.x, pt.y));
}
else if (byCodeOption == 6)
{
    // Option C1
    PostMessage(hwnd, WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
    Sleep(5);
    PostMessage(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(pt.x, pt.y));
}
else if (byCodeOption == 8)
{
    // Option C2
    PostMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(pt.x, pt.y));
    Sleep(5);
    PostMessage(hwnd, WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM(pt.x, pt.y));
}
else if (byCodeOption == 10)
{
    // Option C3
    PostMessage(hwnd, WM_LBUTTONDOWN, pt.x, pt.y);
    Sleep(5);
    PostMessage(hwnd, WM_LBUTTONUP, pt.x, pt.y);
}
    // Завершение
    ClipCursor(&rcOldClip); // Restore the cursor to its previous area.
    SetCursorPos(ptOld.x, ptOld.y); // Restore previous coordinates of the cursor.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.