Здравствуйте.
Необходимо отрисовать в текстуру страничку с HTML и обрабатывать события от мыши. На страничке могут находиться
flash контролы.
Я реализовал скрытое child окно с IWebBrowser, получаю IViewObject рисую в DC, копирую в текстуру, тут все нормально, работает.
Но! есть серьёзная проблема с событиями от мыши в flash контроле.
Они не всегда срабатывают (через раз и хуже), как будто флеш еще где-то сам опрашивает мышь.
Пробывал:
— передавать события через SendMessage,
— через IOleInPlaceObjectWindowless:
void IEWindow::OnMouseEvent(UINT msg, WPARAM wp, LPARAM lp)
{
IDispatch *disp = 0;
_browser->get_Document(&disp);
if (disp)
{
IHTMLDocument2 *html = 0;
disp->QueryInterface(__uuidof(IHTMLDocument2), (void**)&html);
if (html)
{
POINT curpos;
GetCursorPos(&curpos);
ScreenToClient(_parentHWND, &curpos);
IHTMLElement *elem = 0;
html->elementFromPoint(curpos.x, curpos.y, &elem);
if (elem)
{
IOleInPlaceObjectWindowless *wl = 0;
elem->QueryInterface(__uuidof(IOleInPlaceObjectWindowless ), (void**)&wl);
if (wl)
{
LRESULT lr = 0;
wl->OnWindowMessage(msg, wp, lp, &lr);
wl->Release();
}
elem->Release();
}
html->Release();
}
disp->Release();
}
но это не помогает
Я много гуглил и искал тут, данная проблема возникает довольно часто, но я так и не нашел нормального решения.
Прошу Вашей помощи!
Здравствуйте, frankinshtein, Вы писали:
F>Здравствуйте.
F>Необходимо отрисовать в текстуру страничку с HTML и обрабатывать события от мыши. На страничке могут находиться flash контролы.
F>Я реализовал скрытое child окно с IWebBrowser, получаю IViewObject рисую в DC, копирую в текстуру, тут все нормально, работает.
F>Но! есть серьёзная проблема с событиями от мыши в flash контроле.
F>Они не всегда срабатывают (через раз и хуже), как будто флеш еще где-то сам опрашивает мышь.
У меня недавно была похожая проблема. У меня MFC-приложение со скрытым окном CHtmlView, тоже на страничке находится Flash. Тоже пробовал с SendMessage, ничего не получалось. В итоге пришёл к такому работающему варианту:
BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam)
{
static TCHAR szText[MAX_PATH];
CPtrList* pLstWindows = (CPtrList*) lParam;
GetClassName(hwnd, szText, MAX_PATH);
if (lstrcmp(szText, _T("MacromediaFlashPlayerActiveX")) == 0)
pLstWindows->AddTail(hwnd);
return TRUE;
}
BOOL ClickFlash(HWND hMainWnd, int x, int y)
{
CPtrList lstWindows;
HWND hFlashWnd, hWnd;
CRect rect;
MSG msg;
POSITION pos;
int S, Smax = 0;
EnumChildWindows(hMainWnd, EnumChildProc, (LPARAM) &lstWindows);
if (lstWindows.IsEmpty())
return FALSE;
// Find the main flash window
pos = lstWindows.GetHeadPosition();
while (pos != NULL)
{
hWnd = (HWND) lstWindows.GetNext(pos);
::GetWindowRect(hWnd, rect);
S = rect.Width() * rect.Height();
if (S > Smax)
{
Smax = 0;
hFlashWnd = hWnd;
}
}
if (x == -1 || y == -1)
{
::GetWindowRect(hFlashWnd, rect);
x = rect.Width() / 2;
y = rect.Height() / 2;
}
msg.hwnd = hFlashWnd;
msg.message = WM_MOUSEMOVE;
msg.wParam = 0;
msg.lParam = (x & 0xFFFF) | ((y & 0xFFFF) << 16);
msg.time = 0;
msg.pt.x = 0;
msg.pt.y = 0;
DispatchMessage(&msg);
msg.hwnd = hFlashWnd;
msg.message = WM_MOUSEACTIVATE;
msg.wParam = (WPARAM) theApp.m_pMainWnd->m_hWnd;
msg.lParam = (HTCLIENT & 0xFFFF) | ((WM_LBUTTONDOWN & 0xFFFF) << 16);
msg.time = 0;
msg.pt.x = 0;
msg.pt.y = 0;
DispatchMessage(&msg);
msg.hwnd = hFlashWnd;
msg.message = WM_SETCURSOR;
msg.wParam = (WPARAM) hFlashWnd;
msg.lParam = (HTCLIENT & 0xFFFF) | ((WM_MOUSEMOVE & 0xFFFF) << 16);
msg.time = 0;
msg.pt.x = 0;
msg.pt.y = 0;
DispatchMessage(&msg);
msg.hwnd = hFlashWnd;
msg.message = WM_LBUTTONDOWN;
msg.wParam = MK_LBUTTON;
msg.lParam = (x & 0xFFFF) | ((y & 0xFFFF) << 16);
msg.time = 0;
msg.pt.x = 0;
msg.pt.y = 0;
DispatchMessage(&msg);
msg.hwnd = hFlashWnd;
msg.message = WM_LBUTTONUP;
msg.wParam = 0;
msg.lParam = (x & 0xFFFF) | ((y & 0xFFFF) << 16);
msg.time = 0;
msg.pt.x = 0;
msg.pt.y = 0;
DispatchMessage(&msg);
msg.hwnd = hFlashWnd;
msg.message = WM_SETCURSOR;
msg.wParam = (WPARAM) hFlashWnd;
msg.lParam = (HTCLIENT & 0xFFFF) | ((WM_MOUSEMOVE & 0xFFFF) << 16);
msg.time = 0;
msg.pt.x = 0;
msg.pt.y = 0;
DispatchMessage(&msg);
msg.hwnd = hFlashWnd;
msg.message = WM_MOUSEMOVE;
msg.wParam = 0;
msg.lParam = 0;
msg.time = 0;
msg.pt.x = 0;
msg.pt.y = 0;
DispatchMessage(&msg);
return TRUE;
}
В ClickFlash передаётся хэндл окна CHtmlView. Далее ищутся дочерние окна, у которых класс окна "MacromediaFlashPlayerActiveX". Далее из них выбирается нужное окно и посылаются мышинные сообщения.
Нужно отметить, что такой приём не на всех сайтах срабатывает. Иногда есть только главное окно "InternetExplorer_Server", а отдельных окон для флэша нет. Здесь уже придётся перебирать все объекты, искать среди них флэш и сообщение посылать окну "InternetExplorer_Server".
Огромное спасибо!!! Работает!!!
Вот так сделал (основной код как в 1 моем посте):
wl->OnWindowMessage(WM_MOUSEMOVE, 0, lp, &lr);
wl->OnWindowMessage(WM_LBUTTONDOWN, wp, lp, &lr);
wl->OnWindowMessage(WM_LBUTTONUP, wp, lp, &lr);
Хотя, это все равно не честный способ, хотелось бы узнать настояйщий корректный метод, где нормально будут обрабатываться все события.