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