(cppwebbrowser)c++ i flash

0

Czy jest możliwość zasymulowania kliknięcia myszki we flashu? *swf ładuję przez CppWebBrowser. SendMessage jakotako nie działa. Są jakieś inne sposoby aby wcisnąć button we flashu? Nie chodzi mi o "fizyczne" (SetMousePos) przestawienie myszki tylko o symulację. Jakieś sugestie?

Pozdrawiam

P.S.
Zna ktoś może jakiś dobry program do edytowania skryptów we flashu?

*q: prev: http:*4programmers.net/Forum/viewtopic.php?id=128579

0

Pewnie że jest sposób.

  1. Znajdź obiekt za pomocą document.getElementById lub iterując tagi z document.all.
  2. skonwertuj znaleziony obiekt do IHTMLObjectElement (obiect->QueryInterface)
  3. 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.
  4. 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;
}
0

Jutro się za to wezmę, ale z tego co przejrzałem ten kod, to widzę że będą problemy ;)

Pozdro

0

ostatni raz jak skutecznie udalo mi sie 'zautmatyzowac' flasha, to skonczylem na keybevent+mouseevent.. ale oczywiscie okno i kontrolka flash'a musialy miec focusa :/ inne proby nie wyszly

0

Jest jakiś cień szansy, że ktoś po kolei opisze o co w tym kodzie chodzi?

Pozdro

0
Ądżej napisał(a)

Jest jakiś cień szansy, że ktoś po kolei opisze o co w tym kodzie chodzi?

Pozdro

myślę, że cień szansy jest, ale nic poza tym ;)

0

Ale ten cień jest b. duży... ;P Ponieważ zależy mi na tym, a z tego kodu dużo nie łapię. :/

0

Ądżej, podaj adres stony z flashem (i który to), albo chociaż jaki ID ma <object>, jego index w dokumencie lub inną wyróżniającą go właściwość wyciągniętą z kodu html.
Wyjaśnianie tego co ten kod robi, pasuje do działu newbie lub samodzielnej nauki. Ogólnie jest to malutki javascript napisany w c++.

FindObject() wyszukuje flasha na stronie.
HandleObject() klika w wybrane miejsce.

0
<base href="http:\\.....">
<div id="g"><embed type="application/x-shockwave-flash" src="file:\\\E:\......../g12.swf" style="" id="g" name="g" bgcolor="#ffffff" quality="high" flashvars="user_id=7250600&amp;profil_id=9127497&amp;login=BMFNowak81&amp;jedenastka=1" height="44" width="360">

O to Ci chodziło?

0

Dla uproszczenia zmień ID tagu embed. Jeżeli będą dwa tagi z jednakowym ID, to getElementById zwróci pierwszy, a żeby dostać się do drugiego, trzeba by dodać dodatkowy kod którego tak się boisz.
W poniższym kodzie użyłem<embed id="flash1"

Po załadowaniu strony (najlepiej w DocumentComplete) wstaw

IHTMLEmbedElement *flash;
if (FindObject(browser, &flash))
{
	EmbedClick(flash, x, y);
	flash->Release();
}

A tu masz resztę, dołącz mshtml.h

BOOL FindObject(TCppWebBrowser *browser, IHTMLEmbedElement **ppv)
{
	BOOL found = false;
	BSTR bstrId;
	IHTMLDocument3 *document;
	IHTMLElement *element = NULL;

	if (!BrowserGetDocument(browser, IID_IHTMLDocument3, (void**)&document))
	{
		// ID flasha
		bstrId = SysAllocString(L"flash1");

		if (!document->getElementById(bstrId, &element) && element)
		{
			found = !element->QueryInterface(IID_IHTMLEmbedElement, (void**)ppv);
			element->Release();
		}
		SysFreeString(bstrId);
		document->Release();
	}
	return found;
}

void EmbedClick(IHTMLEmbedElement *embed, int x, int y)
{
	IOleObject *OleObject;
	IOleInPlaceObjectWindowless *windowless;
	if (!embed->QueryInterface(IID_IOleObject, (void**)&OleObject))
	{
		// OleObject wskazuje na bazową klasę w flash*.ocx

		if (!OleObject->QueryInterface(IID_IOleInPlaceObjectWindowless, (void**)&windowless))
		{
			// klikanie
			LRESULT res;
			LPARAM lParam  = x|(y<<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();
		}
		OleObject->Release();
	}
}

HRESULT BrowserGetDocument(TCppWebBrowser *browser, REFIID riid, void **ppv)
{
	IDispatch *disp = NULL;
	*ppv = NULL;

	HRESULT hr = browser->get_Document(&disp);
	if (!disp)
	{
		hr = E_FAIL;
	}
	else
	{
		hr = disp->QueryInterface(riid, ppv);
		disp->Release();
	}
	return hr;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1