Прошу подсказать, как правильно кликать в скрытое окно!
Есть подобие виртуальной кабины автомобиля и там я моделирую планшет (как электронный гаджет) возле приборной панели. Надо, чтобы веб-браузер был отрисован на экране этого виртуального планшета.
Для этого:
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.