Reactos
at master 289 lines 6.3 kB view raw
1/* 2 * Copyright 2004, 2005 Martin Fuchs 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 20 // 21 // Explorer clone 22 // 23 // webchild.cpp 24 // 25 // Martin Fuchs, 08.02.2004 26 // 27 28#include <precomp.h> 29 30#include "webchild.h" 31 32#include <comutil.h> 33 34Variant::Variant(const VARIANT& var) 35{ 36 VariantInit(this); 37 CheckError(VariantCopy(this, const_cast<VARIANT*>(&var))); 38} 39 40Variant::Variant(const VARIANT* var) 41{ 42 VariantInit(this); 43 CheckError(VariantCopy(this, const_cast<VARIANT*>(var))); 44} 45 46Variant::~Variant() 47{ 48 VariantClear(this); 49} 50 51 52Variant::operator long() const 53{ 54 Variant v; 55 CheckError(VariantChangeType(&v, (VARIANT*)this, 0, VT_I4)); 56 return V_I4(&v); 57} 58 59Variant::operator bool() const 60{ 61 Variant v; 62 CheckError(VariantChangeType(&v, (VARIANT*)this, 0, VT_BOOL)); 63 return V_BOOL(&v)? true: false; 64} 65 66Variant::operator IDispatch*() const 67{ 68 Variant v; 69 CheckError(VariantChangeType(&v, (VARIANT*)this, 0, VT_DISPATCH)); 70 return V_DISPATCH(&v); 71} 72 73Variant::operator VARIANT_BOOL() const 74{ 75 Variant v; 76 CheckError(VariantChangeType(&v, (VARIANT*)this, 0, VT_BOOL)); 77 return V_BOOL(&v); 78} 79 80 81void BStr::assign(BSTR s) 82{ 83 if (!SysReAllocString(&_p, s)) 84 THROW_EXCEPTION(E_OUTOFMEMORY); 85} 86 87void BStr::assign(const VARIANT& var) 88{ 89 if (V_VT(&var) == VT_BSTR) 90 assign(V_BSTR(&var)); 91 else { 92 Variant v; 93 CheckError(VariantChangeType(&v, const_cast<VARIANT*>(&var), 0, VT_BSTR)); 94 assign(V_BSTR(&v)); 95 } 96} 97 98 99BrowserNavigator::BrowserNavigator() 100 : _browser_initialized(false) 101{ 102} 103 104void BrowserNavigator::attach(IWebBrowser* browser) 105{ 106 _browser = browser; 107} 108 109void BrowserNavigator::goto_url(LPCTSTR url) 110{ 111 if (_browser_initialized) 112 _browser->Navigate(BStr(url), NULL, NULL, NULL, NULL); 113 else { 114 _new_url = url; 115 116 _browser->Navigate(BStr(L"about:blank"), NULL, NULL, NULL, NULL); 117 } 118} 119 120void BrowserNavigator::set_html_page(const String& html_txt) 121{ 122 _new_html_txt = html_txt; 123 124 goto_url(TEXT("about:blank")); 125} 126 127void T2nA_binary(LPCTSTR s, LPSTR d, int len) 128{ 129 while(len-- > 0) 130 *d++ = (unsigned char)*s++; 131} 132 133void BrowserNavigator::navigated(LPCTSTR url) 134{ 135 _browser_initialized = true; 136 137 bool nav = false; 138 139 if (!_new_url.empty()) { 140 if (!_tcscmp(url,TEXT("about:blank")) && _new_url!=TEXT("about:blank")) { 141 _browser->Navigate(BStr(_new_url), NULL, NULL, NULL, NULL); 142 ++nav; 143 } 144 145 _new_url.erase(); 146 } 147 148 if (!nav && !_new_html_txt.empty()) { ///@todo move this into DocumentComplete() ? 149 int len = _new_html_txt.length(); 150 HGLOBAL hHtmlText = GlobalAlloc(GPTR, len); 151 152 if (!hHtmlText) { 153 T2nA_binary(_new_html_txt, (char*)hHtmlText, len); 154 _new_html_txt.erase(); 155 156 SIfacePtr<IStream> pStream; 157 HRESULT hr = CreateStreamOnHGlobal(hHtmlText, TRUE, &pStream); 158 159 if (SUCCEEDED(hr)) { 160 SIfacePtr<IDispatch> pHtmlDoc; 161 CheckError(_browser->get_Document(&pHtmlDoc)); 162 163 SIfacePtr<IPersistStreamInit> pPersistStreamInit; 164 pHtmlDoc.QueryInterface(IID_IPersistStreamInit, &pPersistStreamInit); 165 166 CheckError(pPersistStreamInit->InitNew()); 167 CheckError(pPersistStreamInit->Load(pStream)); 168 } else 169 GlobalFree(hHtmlText); 170 } 171 } 172} 173 174 175HWND create_webchildwindow(const WebChildWndInfo& info) 176{ 177 WebChildWindow* pWnd = WebChildWindow::create(info); 178 179 if (!pWnd) 180 return 0; 181 182 return *pWnd; 183} 184 185static const CLSID CLSID_MozillaBrowser = 186 {0x1339B54C, 0x3453, 0x11D2, {0x93, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; 187 188 189WebChildWindow::WebChildWindow(HWND hwnd, const WebChildWndInfo& info) 190 : super(hwnd, info), 191 web_super(_navigator) 192{ 193 // first try to create a web control with MS IE's CLASSID 194 HRESULT hr = create_control(hwnd, CLSID_WebBrowser, IID_IWebBrowser2); 195 196 // If this failed, try to use Mozilla's web control 197 if (FAILED(hr)) 198 hr = create_control(hwnd, CLSID_MozillaBrowser, IID_IWebBrowser2); 199 200 if (SUCCEEDED(hr)) { 201 _navigator.attach(_control); 202 203 _connector = auto_ptr<EventConnector>(new EventConnector(_control, DIID_DWebBrowserEvents2, this)); 204 205 _control->Navigate(BStr(info._path), &vtMissing, &vtMissing, &vtMissing, &vtMissing); 206 //browser->Navigate2(&Variant(info._path), &vtMissing, &vtMissing, &vtMissing, &vtMissing); 207 } 208} 209 210LRESULT WebChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) 211{ 212 try { 213 switch(nmsg) { 214 case WM_ERASEBKGND: 215 if (!_control) { 216 HDC hdc = (HDC)wparam; 217 ClientRect rect(_hwnd); 218 219 HBRUSH hbrush = CreateSolidBrush(RGB(200,200,235)); 220 BkMode mode(hdc, TRANSPARENT); 221 TextColor color(hdc, RGB(200,40,40)); 222 FillRect(hdc, &rect, hbrush); 223 DrawText(hdc, TEXT("Sorry - no web browser control could be loaded."), -1, &rect, DT_CENTER|DT_VCENTER|DT_SINGLELINE); 224 DeleteObject(hbrush); 225 } 226 227 return TRUE; 228 229 case PM_DISPATCH_COMMAND: { 230 if (!_control) 231 return FALSE; 232 233 HRESULT hr = E_FAIL; 234 235 switch(LOWORD(wparam)) { 236 case ID_GO_BACK: 237 hr = _control->GoBack(); 238 break; 239 240 case ID_GO_FORWARD: 241 hr = _control->GoForward(); 242 break; 243 244 case ID_GO_UP: 245 ///@todo 246 break; 247 248 case ID_GO_HOME: 249 hr = _control->GoHome(); 250 break; 251 252 case ID_GO_SEARCH: 253 hr = _control->GoSearch(); 254 break; 255 256 case ID_REFRESH: 257 hr = _control->Refresh(); 258 break; 259 260 case ID_STOP: 261 hr = _control->Stop(); 262 break; 263 264 default: 265 return super::WndProc(nmsg, wparam, lparam); 266 } 267 268 if (FAILED(hr) && hr!=E_FAIL) 269 THROW_EXCEPTION(hr); 270 271 return TRUE;} 272 273 default: 274 return super::WndProc(nmsg, wparam, lparam); 275 } 276 } catch(COMException& e) { 277 HandleException(e, _hwnd); 278 } 279 280 return 0; 281} 282 283 284String WebChildWindow::jump_to_int(LPCTSTR url) 285{ 286 _navigator.goto_url(url); 287 288 return url; 289}