Reactos
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}