Zrzuty ekranu (screenshots) z kontrolki webBrowser

0

Witam serdecznie.

W chwili obecnej zajmuje się rozwojem programu będącego swego rodzaju 'robotem sieciowym'. Program został napisany w C++ pod Visual Studio 6.0. Natrafiłem niestety na problem, którego nie mogę rozgryźć. Mianowicie klient zażyczył sobie bym po za kodem pobranych/przejrzanych stron, przesyłał mu także ich screenshoty.

Z istotnych uwag: program nie posiada interfejsu. Obraz nie może być przechwytywany z ekranu.
Z tego co pamiętam, w C# istnieje możliwość wydruku grafiki z kontrolki webBrowser. Niestety nie wiem jak się to ma do C++.

Orientujecie się może, jak się do tego zabrać pod C++? Chętnych do pogłowienia się nad tym problemem zapraszam do dyskusji :).

0

zrób wirtualne okno(niewidoczne na ekranie) na który będzie wyświetlona zawartość kontrolki i zrób screena kontekstu tego okna...

Żeby zrobić screena, musi być gdzieś jakaś grafika, WebBrowser musi w jakiś sposób przekazać graficzną treść, bo bez generowania grafiki nie wygeneruje screenu...

0

albo interfejs IThumbnailCapture

http://www.codeproject.com/KB/IP/htmlimagecapture.aspx

0
reichel napisał(a)

albo interfejs IThumbnailCapture
http://www.codeproject.com/KB/IP/htmlimagecapture.aspx

Brawo, o coś takiego właśnie mi chodzi.
Z tym, że... ciężko będzie to wykorzystać do mojej pracy:

  • Kod korzysta z 'afxocc.h' które gryzie się z VC6.0
  • Pobrane strony nie tworzą zrzutów z flash'a (co przy obecnej popularności tej techniki raczej nie usatysfakcjonuje zbytnio klienta ;) ).
  • tego co tam wyczytałem IThumbnailCapture wykrawa strony o konkretnym rozmiarze, podczas gdy moje screeny nie mogą zawierać ani pustej przestani (na dole pod tekstem), ani nie mogą być oczywiście ucięte w połowie. Pewnie ten problem dałoby się jakoś obejść (zmierzyć wielkość obiektu w pamięci), ale przy dwóch powyższych problemach chyba lepiej poświęcić czas na szukanie alternatywy?
crayze napisał(a)

zrób wirtualne okno(niewidoczne na ekranie) na który będzie wyświetlona zawartość kontrolki i zrób screena kontekstu tego okna...

Żeby zrobić screena, musi być gdzieś jakaś grafika, WebBrowser musi w jakiś sposób przekazać graficzną treść, bo bez generowania grafiki nie wygeneruje screenu...

Dokładnie o czymś takim myślałem w pierwszym poście... problem polega jednak na tym, że przy C++, webBrowser nie posiada metod bezpośrednio zapisujących stronę jako grafikę. Niestety nie mam pomysłu jak to obejść. Jakieś sugestie?

0
Seether napisał(a)

Dokładnie o czymś takim myślałem w pierwszym poście... problem polega jednak na tym, że przy C++, webBrowser nie posiada metod bezpośrednio zapisujących stronę jako grafikę. Niestety nie mam pomysłu jak to obejść. Jakieś sugestie?

No jakto, chyba da się wyświetlić webBrowser na oknie [???] , czy kontrolka webBrowser jest już automatycznie jako okno? Pytam bo nie używam tego typu stuff'u

0

Moment. Uporządkuje troszkę temat, i postawie na nowo pytanie:

Program nie otwiera się w oknie. Jest kompilowany jako .dll działający w tle systemu w oparciu o IIS.
Cel jest następujący: Program ma wejść na stronę http://www.wp.pl, pobrać jej kod (to już mam), po czym zapisać ją w całości jako grafikę (jpg/png/gif/bmp/???). Zapisywana ma być cała strona - od górnego bannera, aż po ostatni wiersz strony (wychodzi więc spora bitmapka, ok. 800x3000px).

Czy jest ktoś na siłach doradzić mi w jaki sposób, najlepiej przy pomocy krótkich przykładów (c++), można zapisywać ciągi tekstu jako pliki graficzne?

0

http://msdn.microsoft.com/en-us/library/aa752044(VS.85).aspx#add_WB_toapp

jako, że nie dostałem odpowiedzi na pytanie, sam oblukałem tą kontrolkę, z tego przykładu tworzenia, wygląda na to, że ustawia się jej stan widoczności(widzę tam WS_VISIBLE), czyli okno kontrolki jej wewnętrznie w nią wbudowane, o to mi chodziło...

Rozumiem, że ty skoro masz ją niewidoczną dajesz tam inną wartość?
Ja bym na twoim miejscu przejął uchwyt do jej okna, no i zrobił screena tego okna, IMO ja bym użył GDI+, wspierany zapis w różnych popularnych formatach...
Ale coś tam o flashu wspominałeś, no z tym to będzie problem, w ten sposób na pewno flasha nie zapiszesz(rozumiem, że chodzi ci o animację), no chyba, żeby jakoś pobrać częstotliwość odświeżania flasha i robić screeny co klatkę, ale to i już taka kombinatoryka...

0
crayze napisał(a)

http://msdn.microsoft.com/en-us/library/aa752044(VS.85).aspx#add_WB_toapp
jako, że nie dostałem odpowiedzi na pytanie, sam oblukałem tą kontrolkę

Dzięki, wybacz, umknęło mi.

crayze napisał(a)

Rozumiem, że ty skoro masz ją niewidoczną dajesz tam inną wartość?

Nie, w moim programie w ogóle jej nie używam. Pobieram strumieniem kod danej strony ;).
Tak jak napisałem w pierwszym poście - pamiętam że zapisywanie bitmapek z tej kontrolki jest możliwe w C#, i dlatego, prosząc Was o pomoc, zasugerowałem, że może od tej strony warto byłoby się do tego zabrać :).

crayze napisał(a)

Ja bym na twoim miejscu przejął uchwyt do jej okna, no i zrobił screena tego okna, IMO ja bym użył GDI+, wspierany zapis w różnych popularnych formatach...

Hmmm, kontrolka jest w pewnym sensie oknem, czyli - przy założeniu że owo GDI+ może zapisywać screen okna - jesteśmy o krok od rozwiązania problemu. O duży krok, biorąc pod uwagę, że nigdy nie miałem z tymtym całym GDI+ do czynienia ;).

crayze napisał(a)

Ale coś tam o flashu wspominałeś, no z tym to będzie problem, w ten sposób na pewno flasha nie zapiszesz(rozumiem, że chodzi ci o animację), no chyba, żeby jakoś pobrać częstotliwość odświeżania flasha i robić screeny co klatkę, ale to i już taka kombinatoryka...

Nie no, animacja nie wchodzi w grę. Chodzi raczej o przechwycenie jednej klatki z danej strony i zapisanie jej jako pdf. Z tego co wyczytałem w sieci, wspomniany wyżej pakiet, miał niestety (nie wiem od czego to zależy) problemy ze zrzutem flashowych fragmentów stron (zapisywał je jako białe pola). Jako że są strony pisane w sporej mierze właśnie w flashu, nie mogę wykorzystać tej biblioteki. Zapisane pliki mają być możliwie podobne do obrazu z pierwszej lepszej przeglądarki.

Ot, z każdej strony - jeden jpg.
Robot przewala dziennie 200-400k stron ;].

0

to ja nie wiem, musisz mieć uchwyt okna i tyle..

http://msdn.microsoft.com/en-us/library/ms535407.aspx
Masz uchwyt okna HWND, pobierasz z niego HDC przez GetDC(), i dalej w example'u masz od HDC do pliku, tylko tam widzę jeszcze jakąś metodę FillEclipse(), to bez tego, od razu po DrawImage() z obiektu Graphics do Image możesz brać się za zapisywanie tworzyć enkoder i zapisuwać....

EDIT
aha po wszystkim jeszcze HDC trzeba zwolnić przez ReleaseDC()
aha jeszcze coś, musisz zainicjować GDI+ w programie, tam gdzieś w introduction do GDI+ będzie to, od XP GDI+ jest wbudowane, dla wcześniejszych winów musisz zapoatrzeć się w DLLkę GDI+

0

Użyj funkcji OleDraw, w SPACJA końcu masz dostęp do obiektu IWebBrowser2.

#define _ATL_DLL
#define _ATL_DLL_IMPL

#include <atl\\atldef.h>
#include <atl\\atliface.h>
#include <mshtml.h>
#include <exdisp.h>
#include "RenderHtml.h" // BOOL RenderHtml(HDC dc, int width, int height, LPWSTR url);
#pragma comment(lib,"atl.lib")

GUID _IID_IAxWinHostWindow = {0xB6EA2050, 0x48A, 0x11D1, 0x82, 0xB9, 0x0, 0xC0, 0x4F, 0xB9, 0x94, 0x2E};


BOOL RenderHtml(HDC dc, int width, int height, LPWSTR url)
{
	BOOL success = false;
	OleInitialize(0);

	if (AtlAxWinInit())
	{
		HWND hwnd = CreateWindow(
			TEXT("#32770"),
			0,
			WS_POPUP,
			0, 0, width, height,
			0, 0, GetModuleHandle(0), 0);

		IUnknown *atl;
		if (!AtlAxCreateControl(L"about:blank", hwnd, 0, &atl))
		{
			IAxWinHostWindow *ax;
			if (!atl->QueryInterface(_IID_IAxWinHostWindow, (void**)&ax))
			{
				IWebBrowser2 *browser;
				if (!ax->QueryControl(IID_IWebBrowser2, (void**)&browser))
				{
					browser->Navigate(url,0,0,0,0);

					MessageBox(0,TEXT("click me"),0,0); // czekaj aż strona się załaduje

					RECT rc = {0,0,width, height};
					success = !OleDraw(browser, DVASPECT_CONTENT, dc, &rc);

					browser->Release();
				}
				ax->Release();
			}
			atl->Release();
		}
		DestroyWindow(hwnd);
	}
	OleUninitialize();
	return success;
}

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