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
Variant(const VARIANT & var)34 Variant::Variant(const VARIANT& var)
35 {
36 VariantInit(this);
37 CheckError(VariantCopy(this, const_cast<VARIANT*>(&var)));
38 }
39
Variant(const VARIANT * var)40 Variant::Variant(const VARIANT* var)
41 {
42 VariantInit(this);
43 CheckError(VariantCopy(this, const_cast<VARIANT*>(var)));
44 }
45
~Variant()46 Variant::~Variant()
47 {
48 VariantClear(this);
49 }
50
51
operator long() const52 Variant::operator long() const
53 {
54 Variant v;
55 CheckError(VariantChangeType(&v, (VARIANT*)this, 0, VT_I4));
56 return V_I4(&v);
57 }
58
operator bool() const59 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
operator IDispatch*() const66 Variant::operator IDispatch*() const
67 {
68 Variant v;
69 CheckError(VariantChangeType(&v, (VARIANT*)this, 0, VT_DISPATCH));
70 return V_DISPATCH(&v);
71 }
72
operator VARIANT_BOOL() const73 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
assign(BSTR s)81 void BStr::assign(BSTR s)
82 {
83 if (!SysReAllocString(&_p, s))
84 THROW_EXCEPTION(E_OUTOFMEMORY);
85 }
86
assign(const VARIANT & var)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
BrowserNavigator()99 BrowserNavigator::BrowserNavigator()
100 : _browser_initialized(false)
101 {
102 }
103
attach(IWebBrowser * browser)104 void BrowserNavigator::attach(IWebBrowser* browser)
105 {
106 _browser = browser;
107 }
108
goto_url(LPCTSTR url)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
set_html_page(const String & html_txt)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
T2nA_binary(LPCTSTR s,LPSTR d,int len)127 void T2nA_binary(LPCTSTR s, LPSTR d, int len)
128 {
129 while(len-- > 0)
130 *d++ = (unsigned char)*s++;
131 }
132
navigated(LPCTSTR url)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
create_webchildwindow(const WebChildWndInfo & info)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
WebChildWindow(HWND hwnd,const WebChildWndInfo & info)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
WndProc(UINT nmsg,WPARAM wparam,LPARAM lparam)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
jump_to_int(LPCTSTR url)284 String WebChildWindow::jump_to_int(LPCTSTR url)
285 {
286 _navigator.goto_url(url);
287
288 return url;
289 }
290