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