svvitch
digital signage player
D:/vs_workspace/switch_sf/src/svvitch/IEContent.cpp
Go to the documentation of this file.
00001 #include "IEContent.h"
00002 #ifdef UNICODE
00003 #define FormatMessage FormatMessageW
00004 #define FindResource FindResourceW
00005 #else
00006 #define FormatMessage FormatMessageA
00007 #define FindResource FindResourceA
00008 #endif // !UNICODE
00009 #include <windows.h>
00010 #include <comdef.h>
00011 #include <atlcomcli.h>
00012 #include <comutil.h>
00013 #include <mshtml.h>
00014 #include <Poco/UnicodeConverter.h>
00015 #include "Utils.h"
00016 
00017 typedef HRESULT (__stdcall *DllGetClassObjectFunc)(REFCLSID rclsid, REFIID riid, LPVOID * ppv);
00018 
00019 
00020 IEContent::IEContent(Renderer& renderer, int splitType, float x, float y, float w, float h):
00021     ComContent(renderer, splitType, x, y, w, h), _module(NULL), _classFactory(NULL), _view(NULL)
00022 {
00023     initialize();
00024 }
00025 
00026 IEContent::‾IEContent() {
00027     close();
00028     SAFE_RELEASE(_classFactory);
00029     if (_module) {
00030         FreeLibrary(_module);
00031         _module = NULL;
00032     }
00033 }
00034 
00035 void IEContent::initialize() {
00036     char buf[MAX_PATH + 1];
00037     GetSystemDirectoryA(buf, MAX_PATH  + 1);
00038     string dir(buf);
00039 
00040     string lib(dir + "mshtml.dll");
00041     Poco::File f(lib);
00042     if (f.exists()) {
00043         _module = LoadLibraryA(lib.c_str());
00044         if (_module) {
00045             DllGetClassObjectFunc aDllGetClassObjectFunc = (DllGetClassObjectFunc) GetProcAddress(_module, "DllGetClassObject");
00046             aDllGetClassObjectFunc(CLSID_InternetExplorer, IID_IClassFactory, (void**)&_classFactory);
00047             if (!_classFactory) {
00048                 FreeLibrary(_module);
00049                 _module = NULL;
00050             } else {
00051                 _log.information(Poco::format("load library: %s", lib));
00052             }
00053         }
00054     }
00055 
00056     if (!_module) {
00057         _log.warning("failed not loading IE ActiveX");
00058         return;
00059     }
00060     _phase = 0;
00061 }
00062 
00063 void IEContent::createComComponents() {
00064     HRESULT hr;
00065     if (_module) {
00066         if (_classFactory) {
00067             hr = _classFactory->CreateInstance(NULL, IID_IOleObject, (void**)&_ole);
00068             SAFE_RELEASE(_classFactory);
00069             if FAILED(hr) {
00070                 _log.warning("failed create IOleObject");
00071                 _phase = -1;
00072                 return;
00073             }
00074             _log.information("created class ShockwaveFlash(LoadLibrary)");
00075         } else {
00076             _log.warning("failed create IOleObject");
00077             _phase = -1;
00078             return;
00079         }
00080     } else {
00081         hr = CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_INPROC_SERVER, IID_IOleObject, (void**)&_ole);
00082         if FAILED(hr) {
00083             _log.warning("failed create IOleObject");
00084             _phase = -1;
00085             return;
00086         }
00087         _log.information("created class CLSID_InternetExplorer");
00088     }
00089 
00090     IOleClientSite* clientSite = NULL;
00091     hr = _controlSite->QueryInterface(__uuidof(IOleClientSite), (void**)&clientSite);
00092     if FAILED(hr) {
00093         _log.warning("failed not query IOleClientSite");
00094         _phase = -1;
00095         return;
00096     }
00097     hr = _ole->SetClientSite(clientSite);
00098     if FAILED(hr) {
00099         _log.warning("failed not query IOleObject");
00100         clientSite->Release();  
00101         _phase = -1;
00102         return;
00103     }
00104 
00105     // Set the to transparent window mode
00106     IWebBrowser2* browser = NULL;
00107     hr = _ole->QueryInterface(IID_IWebBrowser2, (LPVOID*)&browser);
00108     if FAILED(hr) {
00109         _log.warning("failed IWebBrowser2");
00110         //clientSite->Release();    
00111         _phase = -1;
00112         return;
00113     }
00114 
00115     wstring url;
00116     Poco::UnicodeConverter::toUTF16(_url, url);
00117     CComVariant empty;
00118     hr = browser->Navigate(_bstr_t(url.c_str()), &empty, &empty, &empty, &empty);
00119     if FAILED(hr) {
00120         _log.warning(Poco::format("failed not navigated: %s", _url));
00121         _phase = -1;
00122         return;
00123     }
00124     //long w, h;
00125     //_browser->get_Width(&w);
00126     //_browser->get_Height(&h);
00127     //_log.information(Poco::format("browser size: %ldx%ld", w, h));
00128 
00129     VARIANT_BOOL busy = VARIANT_FALSE;
00130     do {
00131         hr = browser->get_Busy(&busy);
00132         if FAILED(hr) {
00133             _log.warning("failed get_Busy");
00134             _phase = -1;
00135             return;
00136         }
00137         Sleep(100);
00138     } while (busy == VARIANT_TRUE);
00139 
00140     IDispatchPtr disp = NULL;
00141     hr = browser->get_Document(&disp);
00142     if FAILED(hr) {
00143         _log.warning("failed get_Document");
00144         _phase = -1;
00145         return;
00146     }
00147     IHTMLDocument2* doc = NULL;
00148     hr = disp->QueryInterface(IID_IHTMLDocument2, (void**)&doc);
00149     //hr = disp->QueryInterface(IID_IUnknown, (void**)&_doc);
00150     if FAILED(hr) {
00151         _log.warning("failed quey IHTMLDocument2");
00152         _phase = -1;
00153         return;
00154     }
00155 
00156     // In-place activate the object
00157     //hr = _ole->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, clientSite, 0, NULL, NULL);
00158     //clientSite->Release();    
00159         
00160     //IOleInPlaceObjectWindowless* windowless = NULL;
00161     //hr = _ole->QueryInterface(__uuidof(IOleInPlaceObjectWindowless), (LPVOID*)&windowless);
00162     //if FAILED(hr) {
00163     //  _log.warning("failed not query IOleInPlaceObjectWindowless");
00164     //  _phase = -1;
00165     //  return;
00166     //}
00167 
00168     hr = doc->QueryInterface(IID_IViewObject, (LPVOID*)&_view);   
00169     if FAILED(hr) {
00170         _log.warning("failed not query IViewObject");
00171         _phase = -1;
00172         return;
00173     }
00174     SAFE_RELEASE(doc);
00175     IOleInPlaceObject* inPlaceObject = NULL;     
00176     hr = _ole->QueryInterface(__uuidof(IOleInPlaceObject), (LPVOID*) &inPlaceObject);
00177     if FAILED(hr) {
00178         _log.warning("failed not query IOleInPlaceObject");
00179         _phase = -1;
00180         return;
00181     }
00182     if (inPlaceObject != NULL) {
00183         RECT rect;
00184         SetRect(&rect, 0, 0, _w, _h);
00185         inPlaceObject->SetObjectRects(&rect, &rect);
00186         inPlaceObject->Release();
00187     }
00188 
00189     _log.information("InternetExplorer initialized");
00190     _readCount = 0;
00191     _avgTime = 0;
00192     _phase = 1;
00193 }
00194 
00195 void IEContent::releaseComComponents() {
00196     Poco::ScopedLock<Poco::FastMutex> lock(_lock);
00197     SAFE_RELEASE(_ole);
00198     _phase = 3;
00199     _log.information("flash released");
00200 }
00201 
00202 bool IEContent::open(const MediaItemPtr media, const int offset) {
00203     if (media->files().empty() || media->files().size() <= offset) return false;
00204     MediaItemFile mif = media->files()[offset];
00205     string url;
00206     if (mif.file().find("http://") == 0 || mif.file().find("https://") == 0) {
00207         url = mif.file();
00208     } else {
00209         url = Path(mif.file()).absolute(config().dataRoot).toString();
00210         Poco::File f(url);
00211         if (!f.exists()) {
00212             _log.warning(Poco::format("file not found: %s", url));
00213             return false;
00214         }
00215     }
00216     _url = url;
00217     _phase = 0;
00218 
00219     return ComContent::open(media, offset);
00220 }
00221 
00222 void IEContent::run() {
00223     _log.information("start IE drawing thread");
00224 
00225     PerformanceTimer timer;
00226     while (_playing && _surface && _view) {
00227         if (hasInvalidateRect()) {
00228             Rect rect = popInvalidateRect();
00229             timer.start();
00230             HDC hdc = NULL;
00231             HRESULT hr = _surface->GetDC(&hdc);
00232             if SUCCEEDED(hr) {
00233                 SetMapMode(hdc, MM_TEXT);
00234                 RECTL rectl = {rect.x, rect.y, rect.w, rect.h};
00235                 hr = _view->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdc, NULL, &rectl, NULL, 0);
00236                 if FAILED(hr) {
00237                     _log.warning("failed drawing flash");
00238                     break;
00239                 }
00240                 _surface->ReleaseDC(hdc);
00241                 _readTime = timer.getTime();
00242                 _readCount++;
00243                 if (_readCount > 0) _avgTime = F(_avgTime * (_readCount - 1) + _readTime) / _readCount;
00244             } else {
00245                 _log.warning("failed getDC");
00246             }
00247             Poco::Thread::sleep(0);
00248         } else {
00249             Poco::Thread::sleep(3);
00250         }
00251     }
00252     //SAFE_RELEASE(browser);
00253     //SAFE_RELEASE(view);
00254     //SAFE_RELEASE(windowless);
00255     _log.information("finished IE drawing thread");
00256 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines