svvitch
digital signage player
|
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 }