Pewnie że jest sposób.
- Znajdź obiekt za pomocą document.getElementById lub iterując tagi z document.all.
- skonwertuj znaleziony obiekt do IHTMLObjectElement (obiect->QueryInterface)
- dobierz się do samego obiektu: (IHTMLObjectElement)object->get_object, metoda ta zwróci IDispatch który należy skonwertować do IOleInPlaceObjectWindowless za pomocą metody QueryInterface.
- użyj metody OnWindowMessage kolejno z identyfikatorami: WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_LBUTTONUP.
WM_MOUSEMOVE okazało się konieczne podczas testów z flashem.
Oto mój kod iterujący:
- w timerze szukam pierwszego załadowanego flasha. Jeśli znajdę, to zatrzymujętimer i skaczę do HandleObject() gdzie klikam button na wskazanej pozycji.
#define UNICODE
#include <exdisp.h>
#include <mshtml.h>
#include "CWebPage.h"
LRESULT CALLBACK DlgProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
void Navigate(LPWSTR url);
void HandleObject(IHTMLObjectElement *object);
BOOL FindObject(IHTMLObjectElement **ppv);
HRESULT CollectionGetItem(IHTMLElementCollection *all, int index, REFIID iid, void **ppv);
HRESULT BrowserGetDocument(IHTMLDocument2 **ppv);
HRESULT BrowserGetAll(IHTMLElementCollection **ppv);
IWebBrowser2 *browser;
HWND g_hwnd;
int __stdcall WinMain(HINSTANCE _hinstance,HINSTANCE,LPSTR,int)
{
OleInitialize(0);
HWND hwnd = CreateWindow(TEXT("#32770"),
TEXT("clicking on IHTMLObjectElement"),
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, 0,0, _hinstance, 0);
SetWindowLong(hwnd, GWL_WNDPROC, (LONG)DlgProc);
SendMessage(hwnd, WM_CREATE, 0, 0);
MSG msg;
while (GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg) ;
DispatchMessage(&msg) ;
}
OleUninitialize();
return 0;
}
LRESULT CALLBACK DlgProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
g_hwnd = hwnd;
// stwórz browser
EmbedBrowserObject(hwnd, &browser);
browser->put_Silent(VARIANT_TRUE);
// testowana przeze mnie strona z flashem
Navigate(L"http://topirek.posadzdrzewo.pl/");
// dla prostoty: timer zamiast IDispatch
SetTimer(hwnd, 1000, 2000, 0);
break;
case WM_TIMER:
if (wParam == 1000)
{
IHTMLObjectElement *object;
// szukaj pierwszego <OBJECT> do skutku
if (FindObject(&object))
{
KillTimer(hwnd, 1000);
// znaleziono, wyślij mu WM_MOUSE*
HandleObject(object);
}
}
break;
case WM_SIZE:
ResizeBrowser(hwnd, LOWORD(lParam), HIWORD(lParam));
break;
case WM_CLOSE:
browser->Release();
UnEmbedBrowserObject(hwnd);
DestroyWindow(hwnd);
PostQuitMessage(0);
break;
default:
return DefDlgProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
void Navigate(LPWSTR url)
{
BSTR bstrURL = SysAllocString(url);
browser->Navigate(bstrURL, 0,0,0,0);
SysFreeString(bstrURL);
}
// szuka pierwszego lepszego <OBJECT>
BOOL FindObject(IHTMLObjectElement **ppv)
{
BOOL ok = false;
IHTMLElementCollection *all;
if (!BrowserGetAll(&all))
{
long count;
all->get_length(&count);
for (int allindex=0; allindex<count; allindex++)
{
IHTMLObjectElement *object;
if (!CollectionGetItem(all, allindex, IID_IHTMLObjectElement, (void**)&object))
{
long ReadyState;
object->get_readyState(&ReadyState);
if (ReadyState == 4) // kompletnie załadowany
{
ok = true;
object->QueryInterface(IID_IHTMLObjectElement, (void**)ppv);
// przerwij for {}
allindex = count;
}
object->Release();
}
}
all->Release();
}
return ok;
}
void HandleObject(IHTMLObjectElement *object)
{
// dobieramy się do <OBJECT>
IDispatch *disp = NULL;
if (!object->get_object(&disp) && disp)
{
IOleInPlaceObjectWindowless *windowless;
if (!disp->QueryInterface(IID_IOleInPlaceObjectWindowless, (void**)&windowless))
{
// klikamy button Ranking na pozycji 918,163
LRESULT res;
LPARAM lParam = 918|(163<<16);
windowless->OnWindowMessage(WM_MOUSEMOVE, 0, lParam, &res);
windowless->OnWindowMessage(WM_LBUTTONDOWN, MK_LBUTTON, lParam, &res);
windowless->OnWindowMessage(WM_LBUTTONUP, MK_LBUTTON, lParam, &res);
windowless->Release();
}
disp->Release();
}
}
HRESULT CollectionGetItem(IHTMLElementCollection *all, int index, REFIID iid, void **ppv)
{
VARIANT vName;
VARIANT vIndex;
vName.vt = VT_I4;
vIndex.vt = VT_EMPTY;
vName.intVal = index;
if (!all) return E_INVALIDARG;
IDispatch *pDisp = NULL;
HRESULT hr = all->item(vName, vIndex, &pDisp);
if (!pDisp) hr = E_FAIL;
if (!hr) {
hr = pDisp->QueryInterface(iid, (void**)ppv);
pDisp->Release();
}
return hr;
}
HRESULT BrowserGetDocument(IHTMLDocument2 **ppv)
{
IDispatch *disp = NULL;
*ppv = NULL;
HRESULT hr = browser->get_Document(&disp);
if (!disp)
{
hr = E_FAIL;
}
else
{
hr = disp->QueryInterface(IID_IHTMLDocument2, (void**)ppv);
disp->Release();
}
return hr;
}
HRESULT BrowserGetAll(IHTMLElementCollection **ppv)
{
IHTMLDocument2 *document;
*ppv = NULL;
HRESULT hr = BrowserGetDocument(&document);
if (!hr)
{
hr = document->get_all(ppv);
document->Release();
if (!*ppv)
{
hr = E_FAIL;
}
}
return hr;
}