Здравствуйте, 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".