mirror of
https://github.com/reactos/reactos.git
synced 2024-08-16 16:39:08 +00:00
290 lines
6.1 KiB
C++
290 lines
6.1 KiB
C++
/*
|
|
* Copyright 2004, 2005 Martin Fuchs
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
|
|
//
|
|
// Explorer clone
|
|
//
|
|
// webchild.cpp
|
|
//
|
|
// Martin Fuchs, 08.02.2004
|
|
//
|
|
|
|
#include <precomp.h>
|
|
|
|
#include "webchild.h"
|
|
|
|
#include <comutil.h>
|
|
|
|
Variant::Variant(const VARIANT& var)
|
|
{
|
|
VariantInit(this);
|
|
CheckError(VariantCopy(this, const_cast<VARIANT*>(&var)));
|
|
}
|
|
|
|
Variant::Variant(const VARIANT* var)
|
|
{
|
|
VariantInit(this);
|
|
CheckError(VariantCopy(this, const_cast<VARIANT*>(var)));
|
|
}
|
|
|
|
Variant::~Variant()
|
|
{
|
|
VariantClear(this);
|
|
}
|
|
|
|
|
|
Variant::operator long() const
|
|
{
|
|
Variant v;
|
|
CheckError(VariantChangeType(&v, (VARIANT*)this, 0, VT_I4));
|
|
return V_I4(&v);
|
|
}
|
|
|
|
Variant::operator bool() const
|
|
{
|
|
Variant v;
|
|
CheckError(VariantChangeType(&v, (VARIANT*)this, 0, VT_BOOL));
|
|
return V_BOOL(&v)? true: false;
|
|
}
|
|
|
|
Variant::operator IDispatch*() const
|
|
{
|
|
Variant v;
|
|
CheckError(VariantChangeType(&v, (VARIANT*)this, 0, VT_DISPATCH));
|
|
return V_DISPATCH(&v);
|
|
}
|
|
|
|
Variant::operator VARIANT_BOOL() const
|
|
{
|
|
Variant v;
|
|
CheckError(VariantChangeType(&v, (VARIANT*)this, 0, VT_BOOL));
|
|
return V_BOOL(&v);
|
|
}
|
|
|
|
|
|
void BStr::assign(BSTR s)
|
|
{
|
|
if (!SysReAllocString(&_p, s))
|
|
THROW_EXCEPTION(E_OUTOFMEMORY);
|
|
}
|
|
|
|
void BStr::assign(const VARIANT& var)
|
|
{
|
|
if (V_VT(&var) == VT_BSTR)
|
|
assign(V_BSTR(&var));
|
|
else {
|
|
Variant v;
|
|
CheckError(VariantChangeType(&v, const_cast<VARIANT*>(&var), 0, VT_BSTR));
|
|
assign(V_BSTR(&v));
|
|
}
|
|
}
|
|
|
|
|
|
BrowserNavigator::BrowserNavigator()
|
|
: _browser_initialized(false)
|
|
{
|
|
}
|
|
|
|
void BrowserNavigator::attach(IWebBrowser* browser)
|
|
{
|
|
_browser = browser;
|
|
}
|
|
|
|
void BrowserNavigator::goto_url(LPCTSTR url)
|
|
{
|
|
if (_browser_initialized)
|
|
_browser->Navigate(BStr(url), NULL, NULL, NULL, NULL);
|
|
else {
|
|
_new_url = url;
|
|
|
|
_browser->Navigate(BStr(L"about:blank"), NULL, NULL, NULL, NULL);
|
|
}
|
|
}
|
|
|
|
void BrowserNavigator::set_html_page(const String& html_txt)
|
|
{
|
|
_new_html_txt = html_txt;
|
|
|
|
goto_url(TEXT("about:blank"));
|
|
}
|
|
|
|
void T2nA_binary(LPCTSTR s, LPSTR d, int len)
|
|
{
|
|
while(len-- > 0)
|
|
*d++ = (unsigned char)*s++;
|
|
}
|
|
|
|
void BrowserNavigator::navigated(LPCTSTR url)
|
|
{
|
|
_browser_initialized = true;
|
|
|
|
bool nav = false;
|
|
|
|
if (!_new_url.empty()) {
|
|
if (!_tcscmp(url,TEXT("about:blank")) && _new_url!=TEXT("about:blank")) {
|
|
_browser->Navigate(BStr(_new_url), NULL, NULL, NULL, NULL);
|
|
++nav;
|
|
}
|
|
|
|
_new_url.erase();
|
|
}
|
|
|
|
if (!nav && !_new_html_txt.empty()) { ///@todo move this into DocumentComplete() ?
|
|
int len = _new_html_txt.length();
|
|
HGLOBAL hHtmlText = GlobalAlloc(GPTR, len);
|
|
|
|
if (!hHtmlText) {
|
|
T2nA_binary(_new_html_txt, (char*)hHtmlText, len);
|
|
_new_html_txt.erase();
|
|
|
|
SIfacePtr<IStream> pStream;
|
|
HRESULT hr = CreateStreamOnHGlobal(hHtmlText, TRUE, &pStream);
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
SIfacePtr<IDispatch> pHtmlDoc;
|
|
CheckError(_browser->get_Document(&pHtmlDoc));
|
|
|
|
SIfacePtr<IPersistStreamInit> pPersistStreamInit;
|
|
pHtmlDoc.QueryInterface(IID_IPersistStreamInit, &pPersistStreamInit);
|
|
|
|
CheckError(pPersistStreamInit->InitNew());
|
|
CheckError(pPersistStreamInit->Load(pStream));
|
|
} else
|
|
GlobalFree(hHtmlText);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
HWND create_webchildwindow(const WebChildWndInfo& info)
|
|
{
|
|
WebChildWindow* pWnd = WebChildWindow::create(info);
|
|
|
|
if (!pWnd)
|
|
return 0;
|
|
|
|
return *pWnd;
|
|
}
|
|
|
|
static const CLSID CLSID_MozillaBrowser =
|
|
{0x1339B54C, 0x3453, 0x11D2, {0x93, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
|
|
|
|
|
WebChildWindow::WebChildWindow(HWND hwnd, const WebChildWndInfo& info)
|
|
: super(hwnd, info),
|
|
web_super(_navigator)
|
|
{
|
|
// first try to create a web control with MS IE's CLASSID
|
|
HRESULT hr = create_control(hwnd, CLSID_WebBrowser, IID_IWebBrowser2);
|
|
|
|
// If this failed, try to use Mozilla's web control
|
|
if (FAILED(hr))
|
|
hr = create_control(hwnd, CLSID_MozillaBrowser, IID_IWebBrowser2);
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
_navigator.attach(_control);
|
|
|
|
_connector = auto_ptr<EventConnector>(new EventConnector(_control, DIID_DWebBrowserEvents2, this));
|
|
|
|
_control->Navigate(BStr(info._path), &vtMissing, &vtMissing, &vtMissing, &vtMissing);
|
|
//browser->Navigate2(&Variant(info._path), &vtMissing, &vtMissing, &vtMissing, &vtMissing);
|
|
}
|
|
}
|
|
|
|
LRESULT WebChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
try {
|
|
switch(nmsg) {
|
|
case WM_ERASEBKGND:
|
|
if (!_control) {
|
|
HDC hdc = (HDC)wparam;
|
|
ClientRect rect(_hwnd);
|
|
|
|
HBRUSH hbrush = CreateSolidBrush(RGB(200,200,235));
|
|
BkMode mode(hdc, TRANSPARENT);
|
|
TextColor color(hdc, RGB(200,40,40));
|
|
FillRect(hdc, &rect, hbrush);
|
|
DrawText(hdc, TEXT("Sorry - no web browser control could be loaded."), -1, &rect, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
|
|
DeleteObject(hbrush);
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
case PM_DISPATCH_COMMAND: {
|
|
if (!_control)
|
|
return FALSE;
|
|
|
|
HRESULT hr = E_FAIL;
|
|
|
|
switch(LOWORD(wparam)) {
|
|
case ID_GO_BACK:
|
|
hr = _control->GoBack();
|
|
break;
|
|
|
|
case ID_GO_FORWARD:
|
|
hr = _control->GoForward();
|
|
break;
|
|
|
|
case ID_GO_UP:
|
|
///@todo
|
|
break;
|
|
|
|
case ID_GO_HOME:
|
|
hr = _control->GoHome();
|
|
break;
|
|
|
|
case ID_GO_SEARCH:
|
|
hr = _control->GoSearch();
|
|
break;
|
|
|
|
case ID_REFRESH:
|
|
hr = _control->Refresh();
|
|
break;
|
|
|
|
case ID_STOP:
|
|
hr = _control->Stop();
|
|
break;
|
|
|
|
default:
|
|
return super::WndProc(nmsg, wparam, lparam);
|
|
}
|
|
|
|
if (FAILED(hr) && hr!=E_FAIL)
|
|
THROW_EXCEPTION(hr);
|
|
|
|
return TRUE;}
|
|
|
|
default:
|
|
return super::WndProc(nmsg, wparam, lparam);
|
|
}
|
|
} catch(COMException& e) {
|
|
HandleException(e, _hwnd);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
String WebChildWindow::jump_to_int(LPCTSTR url)
|
|
{
|
|
_navigator.goto_url(url);
|
|
|
|
return url;
|
|
}
|