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 34 Variant::Variant(const VARIANT& var) 35 { 36 VariantInit(this); 37 CheckError(VariantCopy(this, const_cast<VARIANT*>(&var))); 38 } 39 40 Variant::Variant(const VARIANT* var) 41 { 42 VariantInit(this); 43 CheckError(VariantCopy(this, const_cast<VARIANT*>(var))); 44 } 45 46 Variant::~Variant() 47 { 48 VariantClear(this); 49 } 50 51 52 Variant::operator long() const 53 { 54 Variant v; 55 CheckError(VariantChangeType(&v, (VARIANT*)this, 0, VT_I4)); 56 return V_I4(&v); 57 } 58 59 Variant::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 66 Variant::operator IDispatch*() const 67 { 68 Variant v; 69 CheckError(VariantChangeType(&v, (VARIANT*)this, 0, VT_DISPATCH)); 70 return V_DISPATCH(&v); 71 } 72 73 Variant::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 81 void BStr::assign(BSTR s) 82 { 83 if (!SysReAllocString(&_p, s)) 84 THROW_EXCEPTION(E_OUTOFMEMORY); 85 } 86 87 void 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 99 BrowserNavigator::BrowserNavigator() 100 : _browser_initialized(false) 101 { 102 } 103 104 void BrowserNavigator::attach(IWebBrowser* browser) 105 { 106 _browser = browser; 107 } 108 109 void 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 120 void BrowserNavigator::set_html_page(const String& html_txt) 121 { 122 _new_html_txt = html_txt; 123 124 goto_url(TEXT("about:blank")); 125 } 126 127 void T2nA_binary(LPCTSTR s, LPSTR d, int len) 128 { 129 while(len-- > 0) 130 *d++ = (unsigned char)*s++; 131 } 132 133 void 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 175 HWND 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 185 static const CLSID CLSID_MozillaBrowser = 186 {0x1339B54C, 0x3453, 0x11D2, {0x93, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; 187 188 189 WebChildWindow::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 210 LRESULT 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 284 String WebChildWindow::jump_to_int(LPCTSTR url) 285 { 286 _navigator.goto_url(url); 287 288 return url; 289 } 290