Jak mogę, korzystając z IWebBrowser2, wysłać kontrolce WebBrowser kod HTML, zamiast url do pliku?
bardzo łatwo:
.
IWebBrowser2 browser
IHTMLDocument2 doc
IHTMLElement elem
/*init browser*/
if SUCCEEDED(browser->get_Document(&doc)){
if SUCCEEDED(doc->get_body(&elem)){
elem->put_innerHTML(bstr_t("<HTML>blah</HTML>"))
elem->Release()
}
doc->Release()
}
return
Próbuję z takim kodem:
IHTMLDocument2* document;
IHTMLElement* element;
webbrowser_interface->get_Document(&document);
document->get_body(&element);
element->put_innerHTML((LPWSTR)code.c_str());
element->Release();
document->Release();
Niestety, gryzie się, że metoda get_Document wymaga IDispatch **:
error C2664: 'IWebBrowser::get_Document' : cannot convert parameter 1 from 'IHTMLDocument2 ** ' to 'IDispatch ** '
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
Jeśli to castuję to na linijce "document->get_body(&element);" jest acces violation.
to dopisz zaraz za get_body(&disp)
disp->QueryInterface(IID_IHTMLElement, &element)
i teraz wsadź text
Problem polegał na tym, że nie miałem w WebBrowserze dokumentu i
disp->QueryInterface(IID_IHTMLElement, &element)
zapisywał w element pusty wskaźnik. Tymczasowo obszedłem to korzystając z funkcji metody Navigate klasy IWebBrowser2 - wyświetlam najpierw google.pl. Jak mogę wstawić pusty dokument do WebBrowsera?
a ten problem znam, ale z innej strony: brak interface browsera zaraz po jego stworzeniu (odpytując objekt z hwnd ze strony IServiceProvider)
Dopiero Navigate() i standardowe GetMessage()... pomaga
Nawiguj na "about:blank", to jest proste, szybkie i likwiduje sporo drobnych problemów.
Tak też zrobiłem, jednak nawet przy "about:blank" muszę poczekać na załadowanie strony. Próbowałem to rozpoznawać, za pomocą get_StatusText, jednakże ta metoda zawsze zapisuje mi pusty string.
while(1)
{
webbrowser_interface->get_StatusText(&Status);
if(Status == L"Done")
{
break;
}
}
Czy to dlatego, ze nie mam ustawionego StatusBara?
VARIANT_BOOL WaitBusy(IWebBrowser2 * WebBrowser, int timeout)
{
VARIANT_BOOL busy;
timeout /= 10;
if (timeout==0) timeout++;
while(timeout>0)
{
timeout--;
WebBrowser->get_Busy(&busy);
if (busy==VARIANT_FALSE) goto WaitBusy_quit;
wait(); // GetMessage()/TranslateMessage()
Sleep(100);
}
WaitBusy_quit:
// busy=VARIANT_TRUE : The control is busy.
// busy=VARIANT_FALSE : The control is not busy
return busy;
}
ewentualne błędy składni załataj :)
Wciąż nie mogę sobie poradzić. Tym razem nie chce pobrać elementu za pomocą IHTMLDocument::get_Body. Jednak gdy sztucznie odczekam chwilkę - przed tą akcją wyświetlę MessageBoxa - wszystko działa. Mój aktualny kod wygląda tak:
//zmienne
IHTMLDocument2* document;
IHTMLElement* element;
IDispatch* temp;
LPWSTR result = L"bla!";
VARIANT_BOOL busy = VARIANT_TRUE;
//odpalamy okienko, wypełniony zostaje wskaźnik webbrowser_interface
Window();
//ładujemy pusty dokument do webbrowsera...
webbrowser_interface->Navigate(L"about:blank", 0, 0, 0, 0);
//...i czekamy na załadowanie się go
do
{
Sleep(500);
webbrowser_interface->get_Busy(&busy);
}
while(busy);
//pobieramy dokument
webbrowser_interface->get_Document(&temp);
if(temp)
{
temp->QueryInterface(IID_IHTMLDocument2, (void**)&document);
temp->Release();
if(document)
{
//pobieramy element
document->get_body(&element);
if(element)
{
//wstawiamy nasz HTML
element->put_innerHTML(result);
element->Release();
}
document->Release();
}
}