1 /*
2     Copyright (c) 2009 NetAllied Systems GmbH
3 
4 	  This file is part of G3DWarehouseBrowser.
5 
6     Licensed under the MIT Open Source License,
7     for details please see LICENSE file or the website
8     http://www.opensource.org/licenses/mit-license.php
9 */
10 
11 #include "G3DStableHeaders.h"
12 #include "G3DBrowser.h"
13 #include "G3DOleInPlaceFrame.h"
14 #include "G3DOleInPlaceSite.h"
15 #include "G3DOleClientSite.h"
16 #include "G3DDocHostUiHandler.h"
17 
18 #include <windows.h>
19 #include <commctrl.h>
20 #include <string>
21 
22 namespace G3D
23 {
24 	static const wchar_t* CLASS_NAME = L"Browser Example";
25 	static const wchar_t* BROWSER_CLASS_NAME = L"Browser Object";
26 	static const wchar_t* WINDOW_TITLE = L"G3D Warehouse Collada Browser";
27 	static const wchar_t* HOST_NAME =L"Host Name";
28     static const LPTSTR   HOME = L"http://sketchup.google.com/3dwarehouse/?ctyp=sm&cv=p8.0.4811&hl=en_US";
29 	//static const LPTSTR   HOME = L"http://sketchup.google.com/3dwarehouse/?ctyp=sxample&cv=p8.0.4811&rtyppref=s6&hl=en US";
30 	//static const LPTSTR   HOME = L"http://sketchup.google.com/3dwarehouse/?ctyp=sxample&cv=su_6&rtyppref=s6&hl=en ";
31 
32 
33 
34 	//---------------------------------------------------------------------
35 	Browser* Browser::msSingleton = 0;
36 	//---------------------------------------------------------------------
getSingleton()37 	Browser& Browser::getSingleton()
38 	{
39 		assert(msSingleton);
40 		return *msSingleton;
41 	}
42 	//---------------------------------------------------------------------
getSingletonPtr()43 	Browser* Browser::getSingletonPtr()
44 	{
45 		return msSingleton;
46 	}
47 	//---------------------------------------------------------------------
Browser()48 	Browser::Browser()
49 		: mMainWindow(0)
50 		, mWebBrowser(0)
51 		, mBrowserObject(0)
52 		, inPlaceFrame(0)
53 		, inPlaceSite(0)
54 		, docHostUiHandler(0)
55 		, clientSite(0)
56 	{
57 		assert(msSingleton == 0);
58 		msSingleton = this;
59 	}
60 	//---------------------------------------------------------------------
~Browser()61 	Browser::~Browser()
62 	{
63 		delete inPlaceFrame;
64 		delete inPlaceSite;
65 		delete docHostUiHandler;
66 		delete clientSite;
67 		if ( mWebBrowser )
68 		{
69 			mWebBrowser->Release();
70 		}
71 		if ( mBrowserObject )
72 		{
73 			mBrowserObject->Release();
74 		}
75 		msSingleton = 0;
76 	}
77 	//---------------------------------------------------------------------
openBrowser(HINSTANCE hInstance,const WideString & filePath,HWND parentWindow=HWND_DESKTOP)78 	WideString Browser::openBrowser(HINSTANCE hInstance, const WideString& filePath, HWND parentWindow = HWND_DESKTOP ){
79 		MSG	msg;
80 		HRESULT result = OleInitialize(NULL);
81 
82 		mFilePath = filePath;
83 
84 		if(SUCCEEDED(result))
85 		{
86 			WNDCLASSEX		wc;
87 			// Register the class of our Main window.
88 			ZeroMemory(&wc, sizeof(WNDCLASSEX));
89 			wc.cbSize = sizeof(WNDCLASSEX);
90 			wc.hInstance = hInstance;
91 			wc.lpfnWndProc = windowProc;
92 			wc.lpszClassName = CLASS_NAME;
93 			wc.style = CS_CLASSDC|CS_HREDRAW|CS_VREDRAW|CS_PARENTDC|CS_BYTEALIGNCLIENT|CS_DBLCLKS;
94 			RegisterClassEx(&wc);
95 
96 			// Register the class of our window to host the browser.
97 			wc.lpfnWndProc = browserWindowProc;
98 			wc.lpszClassName = BROWSER_CLASS_NAME;
99 			wc.style = CS_HREDRAW|CS_VREDRAW;
100 			RegisterClassEx(&wc);
101 
102 			// Create a Main window.
103 			mMainWindow = CreateWindowEx(0, CLASS_NAME, WINDOW_TITLE,
104 				WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, parentWindow, NULL, hInstance, 0);
105 			if (mMainWindow)
106 			{
107 				// Create a "Back" button.
108 				msg.hwnd = CreateWindow(L"Button", L"Back",
109 					WS_TABSTOP|BS_PUSHBUTTON|BS_TEXT|WS_CHILD|BS_VCENTER|WS_VISIBLE,
110 					6, 6,				// X, Y position
111 					70, 26,				// Width, Height
112 					mMainWindow,
113 					(HMENU)1001, hInstance, 0);
114 
115 				// Create a "Forward" button.
116 				msg.hwnd = CreateWindow(L"Button", L"Forward",
117 					WS_TABSTOP|BS_PUSHBUTTON|BS_TEXT|WS_CHILD|BS_VCENTER|WS_VISIBLE,
118 					6 + 70 + 10, 6,		// X, Y position
119 					70, 26,				// Width, Height
120 					mMainWindow,
121 					(HMENU)1002, hInstance, 0);
122 
123 				// Create a "Home" button.
124 				msg.hwnd = CreateWindow(L"Button", L"Home",
125 					WS_TABSTOP|BS_PUSHBUTTON|BS_TEXT|WS_CHILD|BS_VCENTER|WS_VISIBLE,
126 					6 + 2*70 + 2*10 , 6,		// X, Y position
127 					70, 26,							// Width, Height
128 					mMainWindow,
129 					(HMENU)1003, hInstance, 0);
130 
131 				// Create a Progress bar
132 				InitCommonControls();
133 				hwndProgress = CreateWindowEx(0, PROGRESS_CLASS,
134 					L"", WS_CHILD | PBS_SMOOTH//| WS_VISIBLE
135 					,6 + 3*70 + 3*10 ,  10,
136 					300, 18,
137 					mMainWindow, NULL,
138 					hInstance, NULL);
139 
140 				// Create a child window to host the browser object.
141 				if ((msg.hwnd = CreateWindowEx(0, BROWSER_CLASS_NAME, 0, WS_CHILD|WS_VISIBLE,
142 					0, 40, 0, 0,
143 					mMainWindow, (HMENU)1000, hInstance, 0)))
144 				{
145 					// Show the Main window.
146 					ShowWindow(mMainWindow, 1);
147 					UpdateWindow(mMainWindow);
148 
149 					VARIANT	myURL;
150 					VariantInit(&myURL);
151 					myURL.vt = VT_BSTR;
152 					myURL.bstrVal = SysAllocString(HOME);
153 					mWebBrowser->Navigate(myURL.bstrVal,0, 0, 0, 0);
154 					VariantClear(&myURL);
155 
156 					// Do a message loop until WM_QUIT.
157 					while (GetMessage(&msg, 0, 0, 0) == 1)
158 					{
159 						TranslateMessage(&msg);
160 						DispatchMessage(&msg);
161 					}
162 				}
163 				else
164 				{
165 					MessageBox(mMainWindow, L"Can't create browser child window!", L"ERROR", MB_OK);
166 				}
167 				DestroyWindow(mMainWindow);
168 			}
169 			DestroyWindow(mMainWindow);
170 			OleUninitialize();
171 		}
172 
173 		if ( mFilePath == filePath )
174 		{
175 			return WideString();
176 		}
177 		else
178 		{
179 			return mFilePath;
180 		}
181 	}
182 	//---------------------------------------------------------------------
windowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)183 	LRESULT CALLBACK  Browser::windowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
184 		Browser* _this = Browser::getSingletonPtr();
185 		switch (uMsg)
186 		{
187 			case WM_CLOSE:
188 				{
189 					DestroyWindow(hwnd);
190 					return(1);
191 				}
192 
193 			case WM_DESTROY:
194 				{
195 					// Post the WM_QUIT message to quit the message loop in WinMain()
196 					PostQuitMessage(0);
197 					return(1);
198 				}
199 
200 			case WM_SIZE:
201 				{
202 					// Resize the browser child window, leaving room for our buttons.
203 					MoveWindow(GetDlgItem(hwnd, 1000), 0, 40, LOWORD(lParam), HIWORD(lParam) - 40, TRUE);
204 					return(0);
205 				}
206 			case WM_ERASEBKGND:
207 				{
208 					HBRUSH	hBrush;
209 					HGDIOBJ	orig;
210 					RECT	rec;
211 					// Erase the background behind the buttons. Note: The browser object takes care
212 					// of completely redrawing its area, so we don't need to erase there.
213 					hBrush = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
214 					GetClientRect(hwnd, &rec);
215 					orig = SelectObject((HDC)wParam, hBrush);
216 					Rectangle((HDC)wParam, 0, 0, rec.right, 40);
217 					SelectObject((HDC)wParam, orig);
218 					return(TRUE);
219 				}
220 			case WM_COMMAND:
221 				{
222 					switch (LOWORD(wParam))
223 					{
224 					case 1001:
225 						{
226 							_this->mWebBrowser->GoBack();
227 							break;
228 						}
229 					case 1002:
230 						{
231 							_this->mWebBrowser->GoForward();
232 							break;
233 						}
234 					case 1003:
235 						{
236 							//mWebBrowser->GoHome();
237 							VARIANT	myURL;
238 							VariantInit(&myURL);
239 							myURL.vt = VT_BSTR;
240 							myURL.bstrVal = SysAllocString(HOME);
241 							_this->mWebBrowser->Navigate(myURL.bstrVal,0, 0, 0, 0);
242 							VariantClear(&myURL);
243 							break;
244 						}
245 					}
246 					break;
247 				}
248 		}
249 		return(DefWindowProc(hwnd, uMsg, wParam, lParam));
250 	}
251 	//---------------------------------------------------------------------
browserWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)252 	LRESULT CALLBACK  Browser::browserWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
253 		Browser* _this = Browser::getSingletonPtr();
254 		switch (uMsg)
255 		{
256 			case WM_SIZE:
257 				{
258 					_this->mWebBrowser->put_Width(LOWORD(lParam));
259 					_this->mWebBrowser->put_Height(HIWORD(lParam));
260 					return(0);
261 				}
262 			case WM_CREATE:
263 				{
264 					IClassFactory* pClassFactory = 0;
265 					HRESULT result = CoGetClassObject(CLSID_WebBrowser, 3, NULL, IID_IClassFactory, (void **)&pClassFactory);
266 					if(SUCCEEDED(result))
267 					{
268 						IOleObject* browserObject = 0;
269 						result = pClassFactory->CreateInstance(0, IID_IOleObject, (void**)&browserObject);
270 						if(SUCCEEDED(result))
271 						{
272 							_this->setBrowserObject(browserObject);
273 							_this->inPlaceFrame = new OleInPlaceFrame(_this->mMainWindow);
274 							_this->inPlaceSite  = new OleInPlaceSite(browserObject, _this->inPlaceFrame, hwnd);
275 							_this->docHostUiHandler = new DocHostUiHandler(_this->hwndProgress, _this->mFilePath);
276 							_this->clientSite = new OleClientSite(_this->inPlaceSite, _this->docHostUiHandler);
277 
278 							RECT rect;
279 							GetClientRect(hwnd, &rect);
280 
281 							_this->mBrowserObject->SetClientSite(_this->clientSite);
282 							_this->mBrowserObject->SetHostNames(HOST_NAME, 0);
283 
284 							// Let browser object know that it is embedded in an OLE container.
285 							if (!OleSetContainedObject(_this->mBrowserObject, TRUE))
286 							{
287 								// Set the display area of our browser control the same as our window's size and actually put the browser object into our window.
288 								if(!_this->mBrowserObject->DoVerb(OLEIVERB_SHOW, NULL, _this->clientSite, -1, hwnd, &rect))
289 								{
290 									IWebBrowser2* webBrowser = 0;
291 									result = _this->mBrowserObject->QueryInterface(IID_IWebBrowser2,(void**)&webBrowser);
292 									if(SUCCEEDED(result))
293 									{
294 										_this->setWebBrowser(webBrowser);
295 									}
296 								}
297 							}
298 						}
299 
300 					}
301 					pClassFactory->Release();
302 					// Success
303 					return(0);
304 				}
305 		}
306 		return(DefWindowProc(hwnd, uMsg, wParam, lParam));
307 	}
308 	//---------------------------------------------------------------------
setBrowserObject(IOleObject * browserObj)309 	void Browser::setBrowserObject( IOleObject* browserObj )
310 	{
311 		mBrowserObject = browserObj;
312 	}
313 	//---------------------------------------------------------------------
setWebBrowser(IWebBrowser2 * webBrowser)314 	void Browser::setWebBrowser( IWebBrowser2* webBrowser )
315 	{
316 		mWebBrowser = webBrowser;
317 	}
318 }
319