bool CDeskBand::FindPaths() { m_currentDirectory.clear(); m_selectedItems.clear(); m_bFilesSelected = false; m_bFolderSelected = false; if (m_pSite == NULL) return false; IServiceProvider * pServiceProvider; if (SUCCEEDED(m_pSite->QueryInterface(IID_IServiceProvider, (LPVOID*)&pServiceProvider))) { IShellBrowser * pShellBrowser; if (SUCCEEDED(pServiceProvider->QueryService(SID_SShellBrowser, IID_IShellBrowser, (LPVOID*)&pShellBrowser))) { IShellView * pShellView; if (SUCCEEDED(pShellBrowser->QueryActiveShellView(&pShellView))) { IFolderView * pFolderView; if (SUCCEEDED(pShellView->QueryInterface(IID_IFolderView, (LPVOID*)&pFolderView))) { // hooray! we got the IFolderView interface! // that means the explorer is active and well :) // but we also need the IShellFolder interface because // we need its GetCurFolder() method IPersistFolder2 * pPersistFolder; if (SUCCEEDED(pFolderView->GetFolder(IID_IPersistFolder2, (LPVOID*)&pPersistFolder))) { LPITEMIDLIST folderpidl; if (SUCCEEDED(pPersistFolder->GetCurFolder(&folderpidl))) { // we have the current folder TCHAR buf[MAX_PATH] = {0}; // find the path of the folder if (SHGetPathFromIDList(folderpidl, buf)) { m_currentDirectory = buf; } // if m_currentDirectory is empty here, that means // the current directory is a virtual path IShellFolder * pShellFolder; if (SUCCEEDED(pPersistFolder->QueryInterface(IID_IShellFolder, (LPVOID*)&pShellFolder))) { // if there was a new folder created but not found to set into editing mode, // we try here to do that if (!m_newfolderPidls.empty()) { int nCount2 = 0; IShellFolder * pShellFolder; if (SUCCEEDED(pPersistFolder->QueryInterface(IID_IShellFolder, (LPVOID*)&pShellFolder))) { if (SUCCEEDED(pFolderView->ItemCount(SVGIO_ALLVIEW, &nCount2))) { for (int i=0; i<nCount2; ++i) { LPITEMIDLIST pidl; pFolderView->Item(i, &pidl); bool bFound = false; for (std::vector<LPITEMIDLIST>::iterator it = m_newfolderPidls.begin(); it != m_newfolderPidls.end(); ++it) { HRESULT hr = pShellFolder->CompareIDs(0, pidl, *it); if (HRESULT_CODE(hr) == 0) { // this item was there before, so it's not the new folder CoTaskMemFree(*it); m_newfolderPidls.erase(it); bFound = true; break; } } if (!bFound) { pShellView->SelectItem(pidl, SVSI_EDIT); } CoTaskMemFree(pidl); } } if ((nCount2)||(m_newfolderTimeoutCounter-- <= 0)) { m_newfolderTimeoutCounter = 0; for (std::vector<LPITEMIDLIST>::iterator it = m_newfolderPidls.begin(); it != m_newfolderPidls.end(); ++it) { CoTaskMemFree(*it); } m_newfolderPidls.clear(); } pShellFolder->Release(); } } // find all selected items IEnumIDList * pEnum; if (SUCCEEDED(pFolderView->Items(SVGIO_SELECTION, IID_IEnumIDList, (LPVOID*)&pEnum))) { LPITEMIDLIST pidl; WCHAR buf[MAX_PATH] = {0}; ULONG fetched = 0; ULONG attribs = 0; do { pidl = NULL; if (SUCCEEDED(pEnum->Next(1, &pidl, &fetched))) { if (fetched) { // the pidl we get here is relative! attribs = SFGAO_FILESYSTEM|SFGAO_FOLDER; if (SUCCEEDED(pShellFolder->GetAttributesOf(1, (LPCITEMIDLIST*)&pidl, &attribs))) { if (attribs & SFGAO_FILESYSTEM) { // create an absolute pidl with the pidl we got above LPITEMIDLIST abspidl = CPidl::Append(folderpidl, pidl); if (abspidl) { if (SHGetPathFromIDList(abspidl, buf)) { m_selectedItems[std::wstring(buf)] = attribs; if (m_currentDirectory.empty()) { // remove the last part of the path of the selected item WCHAR * pSlash = _tcsrchr(buf, '\\'); if (pSlash) *pSlash = 0; m_currentDirectory = std::wstring(buf); } } CoTaskMemFree(abspidl); } if (attribs & SFGAO_FOLDER) m_bFolderSelected = true; else m_bFilesSelected = true; } } } CoTaskMemFree(pidl); } } while(fetched); pEnum->Release(); } pShellFolder->Release(); } CoTaskMemFree(folderpidl); } pPersistFolder->Release(); } pFolderView->Release(); } pShellView->Release(); } pShellBrowser->Release(); } pServiceProvider->Release(); } return ((!m_currentDirectory.empty()) || (!m_selectedItems.empty())); }
// // IServiceProvider HRESULT STDMETHODCALLTYPE CRScriptCore::QueryService( REFGUID guidService, REFIID riid, void **ppv) { if (!ppv) return E_POINTER; HRESULT hr = E_NOINTERFACE; #ifdef __IRubyWrapper_INTERFACE_DEFINED__ if (m_listServiceProvider.size() > 0) { IServiceProvider* p = m_listServiceProvider.front(); hr = p->QueryService(guidService, riid, ppv); } else { *ppv = NULL; if (InlineIsEqualGUID(guidService, SID_GetCaller) || InlineIsEqualGUID(guidService, IID_IActiveScriptSite)) { IActiveScriptSite* pSite = GetSite(); if (pSite) { hr = pSite->QueryInterface(riid, ppv); } pSite->Release(); } else if (m_pProv) { hr = m_pProv->QueryService(guidService, riid, ppv); } } #endif return hr; }
// // IActiveScript // HRESULT STDMETHODCALLTYPE CRScriptCore::SetScriptSite( /* [in] */ IActiveScriptSite __RPC_FAR *pass) { if (!pass) return E_POINTER; if (m_pSite) return E_UNEXPECTED; MakeScope(); pass->AddRef(); m_pSite = pass; #ifdef __IRubyWrapper_INTERFACE_DEFINED__ if (m_dwSafety & INTERFACE_USES_SECURITY_MANAGER) { IServiceProvider* pProv = NULL; HRESULT hr = m_pSite->QueryInterface(IID_IServiceProvider, (void**)&pProv); if (hr == S_OK) { IInternetHostSecurityManager* pScm = NULL; hr = pProv->QueryService(SID_SInternetHostSecurityManager, IID_IInternetHostSecurityManager, (void**)&pScm); if (hr == S_OK) { BYTE b[_MAX_PATH]; DWORD dw(sizeof(b)); hr = pScm->GetSecurityId(b, &dw, 0); m_pScM = pScm; } m_pProv = pProv; } } #endif return S_OK; }
void GetExplorerWindows(std::vector<PairHwndPath>& windows, BOOL needPaths) { IShellWindows *psw; if(SUCCEEDED(CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_ALL, IID_IShellWindows, (void**)&psw))) { VARIANT v; V_VT(&v) = VT_I4; IDispatch* pdisp; for(V_I4(&v) = 0; psw->Item(v, &pdisp) == S_OK; V_I4(&v)++) { IWebBrowserApp *pwba; if(SUCCEEDED(pdisp->QueryInterface(IID_IWebBrowserApp, (void**)&pwba))) { PairHwndPath pair; if(SUCCEEDED(pwba->get_HWND((LONG_PTR*)&pair.hwnd))) { IServiceProvider *psp; if(needPaths && SUCCEEDED(pwba->QueryInterface(IID_IServiceProvider, (void**)&psp))) { IShellBrowser *psb; if(SUCCEEDED(psp->QueryService(SID_STopLevelBrowser, IID_IShellBrowser, (void**)&psb))) { IShellView *psv; if(SUCCEEDED(psb->QueryActiveShellView(&psv))) { IFolderView *pfv; if(SUCCEEDED(psv->QueryInterface(IID_IFolderView, (void**)&pfv))) { IPersistFolder2 *ppf2; if(SUCCEEDED(pfv->GetFolder(IID_IPersistFolder2, (void**)&ppf2))) { LPITEMIDLIST pidlFolder; if(SUCCEEDED(ppf2->GetCurFolder(&pidlFolder))) { if(!SHGetPathFromIDList(pidlFolder, pair.path)) { IShellFolder* psf; LPCITEMIDLIST pidlLast; if(SUCCEEDED(SHBindToParent(pidlFolder, IID_IShellFolder, (void**)&psf, &pidlLast))) { STRRET strret; if(SUCCEEDED(psf->GetDisplayNameOf(pidlLast, 0x8000, &strret))) { StrRetToBuf(&strret, pidlLast, pair.path, MAX_PATH); } else { pair.path[0] = 0; } psf->Release(); } } CoTaskMemFree(pidlFolder); } ppf2->Release(); } pfv->Release(); } psv->Release(); } psb->Release(); } psp->Release(); } windows.push_back(pair); } pwba->Release(); } pdisp->Release(); } psw->Release(); } }
void GeckoVBufBackend_t::versionSpecificInit(IAccessible2* pacc) { // Defaults. this->shouldDisableTableHeaders = false; this->hasEncodedAccDescription = false; IServiceProvider* serv = NULL; if (pacc->QueryInterface(IID_IServiceProvider, (void**)&serv) != S_OK) return; IAccessibleApplication* iaApp = NULL; if (serv->QueryService(IID_IAccessibleApplication, IID_IAccessibleApplication, (void**)&iaApp) != S_OK) { serv->Release(); return; } serv->Release(); BSTR toolkitName = NULL; if (iaApp->get_toolkitName(&toolkitName) != S_OK) { iaApp->Release(); return; } if(toolkitName) { this->toolkitName = std::wstring(toolkitName, SysStringLen(toolkitName)); } BSTR toolkitVersion = NULL; if (iaApp->get_toolkitVersion(&toolkitVersion) != S_OK) { iaApp->Release(); SysFreeString(toolkitName); return; } iaApp->Release(); iaApp = NULL; if (wcscmp(toolkitName, L"Gecko") == 0) { if (wcsncmp(toolkitVersion, L"1.", 2) == 0) { if (wcsncmp(toolkitVersion, L"1.9.2.", 6) == 0) { // Gecko 1.9.2.x. // Retrieve the digits for the final part of the main version number. wstring verPart; for (wchar_t* c = &toolkitVersion[6]; iswdigit(*c); c++) verPart += *c; if (_wtoi(verPart.c_str()) <= 10) { // Gecko <= 1.9.2.10 will crash if we try to retrieve headers on some table cells, so disable them. this->shouldDisableTableHeaders = true; } } // Gecko 1.x uses accDescription to encode position info as well as the description. this->hasEncodedAccDescription = true; } } SysFreeString(toolkitName); SysFreeString(toolkitVersion); }
void CRScriptCore::PopServiceProvider() { IServiceProvider* p = NULL; s_crit.Lock(); if (m_listServiceProvider.size() > 0) { p = m_listServiceProvider.front(); m_listServiceProvider.pop_front(); } s_crit.Unlock(); if (p) p->Release(); }
IPDDomDocPagination* getDocPagination(IAccessible* pacc, VARIANT& varChild) { IServiceProvider* servProv; if (pacc->QueryInterface(IID_IServiceProvider, (void**)&servProv) != S_OK) return NULL; IPDDomNode* domNode = getPDDomNode(varChild, servProv); servProv->Release(); if (!domNode) return NULL; IPDDomDocPagination* ret; if (domNode->QueryInterface(IID_IPDDomDocPagination, (void**)&ret) != S_OK) ret = NULL; domNode->Release(); return ret; }
HRESULT GetVirtualDesktopManager(IVirtualDesktopManagerInternal** ppDesktopManagerInternal) { ::CoInitializeEx(NULL, COINIT_MULTITHREADED); IServiceProvider* pServiceProvider = nullptr; HRESULT hr = ::CoCreateInstance( CLSID_ImmersiveShell, NULL, CLSCTX_LOCAL_SERVER, __uuidof(IServiceProvider), (PVOID*)&pServiceProvider); if (SUCCEEDED(hr)) { hr = pServiceProvider->QueryService(CLSID_VirtualDesktopAPI_Unknown, ppDesktopManagerInternal); pServiceProvider->Release(); } return hr; }
void ieambulant_display_message(int level, const char* message) { USES_CONVERSION; HRESULT hr = E_FAIL; if ( ! s_site) return; IServiceProvider* pISP = NULL; hr = s_site->QueryInterface(IID_IServiceProvider, (void **)&pISP); if ( ! SUCCEEDED(hr)) return; // get IWebBrowser2 IWebBrowser2* pIWebBrowser2 = NULL; hr = pISP->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void **)&pIWebBrowser2); pISP->Release(); if ( ! SUCCEEDED(hr) || pIWebBrowser2 == NULL) return; IDispatch *pIDispatchDocument = NULL; hr = pIWebBrowser2->get_Document(&pIDispatchDocument); pIWebBrowser2->Release(); if ( ! SUCCEEDED(hr) || pIDispatchDocument == NULL) return; // get IHTMLDocument2 IHTMLDocument2* pIHTMLDocument2 = NULL; hr = pIDispatchDocument->QueryInterface(IID_IHTMLDocument2, (void **)&pIHTMLDocument2); pIDispatchDocument->Release(); if ( ! SUCCEEDED(hr) || pIHTMLDocument2 == NULL) return; // get IHTMLWindow2 IHTMLWindow2* pIHTMLWindow2 = NULL; hr = pIHTMLDocument2->get_parentWindow(&pIHTMLWindow2); pIHTMLDocument2->Release(); if ( ! SUCCEEDED(hr) || pIHTMLWindow2 == NULL) return; CString Cstr_message(message); BSTR BSTR_message = Cstr_message.AllocSysString(); pIHTMLWindow2->put_status(BSTR_message); SysFreeString(BSTR_message); pIHTMLWindow2->Release(); }
// @pymethod <o PyIInternetSecurityManager>|internet|CoInternetCreateSecurityManager| static PyObject *PyCoInternetCreateSecurityManager(PyObject *self, PyObject *args) { CHECK_IE_PFN(CoInternetCreateSecurityManager); PyObject *obprov; DWORD reserved; if (!PyArg_ParseTuple(args, "Oi", &obprov, // &pyparm <o PyIServiceProvider>|serviceProvider|| &reserved)) // @pyparm int|reserved|| return NULL; IServiceProvider *prov; if (!PyCom_InterfaceFromPyInstanceOrObject(obprov, IID_IServiceProvider, (void **)&prov, TRUE /* bNoneOK */)) return NULL; HRESULT hr; IInternetSecurityManager *sm = 0; PY_INTERFACE_PRECALL; hr = (*pfnCoInternetCreateSecurityManager)(prov, &sm, reserved); prov->Release(); PY_INTERFACE_POSTCALL; if (FAILED(hr)) return PyCom_BuildPyException(hr); return PyCom_PyObjectFromIUnknown(sm, IID_IInternetSecurityManager, FALSE); }
HRESULT Cieambulant::get_document_url() { // here the <url> is obtained from the <PARAM name="src" value="<url>"/> element // and joined with the base url. // also the the value of <PARAM name="autostart" value="<true|false>"/> is retrieved. HRESULT hr = E_FAIL; if ( ! m_site) return hr; IServiceProvider* pISP = NULL; hr = m_site->QueryInterface(IID_IServiceProvider, (void **)&pISP); if ( ! SUCCEEDED(hr)) return hr; IWebBrowser2* pIWebBrowser2 = NULL; hr = pISP->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void **)&pIWebBrowser2); if ( ! SUCCEEDED(hr)) return hr; BSTR BSTR_base_url; hr = pIWebBrowser2->get_LocationURL(&BSTR_base_url); if ( ! SUCCEEDED(hr)) return hr; std::string std_string_base_url = CComBSTR_to_std_string (BSTR_base_url); SysFreeString(BSTR_base_url); m_base_url = ambulant::net::url::from_url(std_string_base_url); m_url = ambulant::net::url::from_url(CComBSTR_to_std_string(m_bstrSrc)); std::string std_string_autostart = CComBSTR_to_std_string(m_bstrAutostart); if (std_string_autostart == "false" || std_string_autostart == "FALSE") m_autostart = false; return S_OK; }
AdobeAcrobatVBufStorage_controlFieldNode_t* AdobeAcrobatVBufBackend_t::fillVBuf(int docHandle, IAccessible* pacc, VBufStorage_buffer_t* buffer, AdobeAcrobatVBufStorage_controlFieldNode_t* parentNode, VBufStorage_fieldNode_t* previousNode, AdobeAcrobatVBufStorage_controlFieldNode_t* oldNode, TableInfo* tableInfo, wstring* pageNum ) { int res; LOG_DEBUG(L"Entered fillVBuf, with pacc at "<<pacc<<L", parentNode at "<<parentNode<<L", previousNode "<<previousNode); nhAssert(buffer); //buffer can't be NULL nhAssert(!parentNode||buffer->isNodeInBuffer(parentNode)); //parent node must be in buffer nhAssert(!previousNode||buffer->isNodeInBuffer(previousNode)); //Previous node must be in buffer VBufStorage_fieldNode_t* tempNode; //all IAccessible methods take a variant for childID, get one ready VARIANT varChild; varChild.vt=VT_I4; varChild.lVal=0; IServiceProvider* servprov = NULL; LOG_DEBUG(L"calling IAccessible::QueryInterface with IID_IServiceProvider"); if((res=pacc->QueryInterface(IID_IServiceProvider,(void**)(&servprov)))!=S_OK) { LOG_DEBUG(L"IAccessible::QueryInterface returned "<<res); return NULL; } LOG_DEBUG(L"IServiceProvider at "<<servprov); // GET ID int ID = getAccID(servprov); nhAssert(ID); //Make sure that we don't already know about this object -- protect from loops if(buffer->getControlFieldNodeWithIdentifier(docHandle,ID)!=NULL) { LOG_DEBUG(L"A node with this docHandle and ID already exists, returning NULL"); servprov->Release(); return NULL; } //Add this node to the buffer LOG_DEBUG(L"Adding Node to buffer"); AdobeAcrobatVBufStorage_controlFieldNode_t* oldParentNode = parentNode; parentNode = static_cast<AdobeAcrobatVBufStorage_controlFieldNode_t*>(buffer->addControlFieldNode(parentNode, previousNode, new AdobeAcrobatVBufStorage_controlFieldNode_t(docHandle, ID, true))); nhAssert(parentNode); //new node must have been created previousNode=NULL; LOG_DEBUG(L"Added node at "<<parentNode); // Get role with accRole long role = 0; LOG_DEBUG(L"Get role with accRole"); { wostringstream s; VARIANT varRole; VariantInit(&varRole); if((res=pacc->get_accRole(varChild,&varRole))!=S_OK) { LOG_DEBUG(L"accRole returned code "<<res); s<<0; } else if(varRole.vt==VT_BSTR) { LOG_DEBUG(L"Got role string of " << varRole.bstrVal); s << varRole.bstrVal; } else if(varRole.vt==VT_I4) { LOG_DEBUG(L"Got role of " << varRole.lVal); s << varRole.lVal; role = varRole.lVal; } parentNode->addAttribute(L"IAccessible::role",s.str().c_str()); VariantClear(&varRole); } // Get states with accState LOG_DEBUG(L"get states with IAccessible::get_accState"); varChild.lVal=0; VARIANT varState; VariantInit(&varState); if((res=pacc->get_accState(varChild,&varState))!=S_OK) { LOG_DEBUG(L"pacc->get_accState returned "<<res); varState.vt=VT_I4; varState.lVal=0; } int states=varState.lVal; VariantClear(&varState); LOG_DEBUG(L"states is "<<states); //Add each state that is on, as an attrib for(int i=0;i<32;++i) { int state=1<<i; if(state&states) { wostringstream nameStream; nameStream<<L"IAccessible::state_"<<state; parentNode->addAttribute(nameStream.str().c_str(),L"1"); } } IPDDomNode* domNode = getPDDomNode(varChild, servprov); IPDDomElement* domElement = NULL; LOG_DEBUG(L"Trying to get IPDDomElement"); if (domNode && (res = domNode->QueryInterface(IID_IPDDomElement, (void**)(&domElement))) != S_OK) { LOG_DEBUG(L"QueryInterface to IPDDomElement returned " << res); domElement = NULL; } BSTR stdName = NULL; int textFlags = 0; BSTR tempBstr = NULL; if (domElement) { // Get stdName. if ((res = domElement->GetStdName(&stdName)) != S_OK) { LOG_DEBUG(L"IPDDomElement::GetStdName returned " << res); stdName = NULL; } if (stdName) { parentNode->addAttribute(L"acrobat::stdname", stdName); if (wcscmp(stdName, L"Span") == 0 || wcscmp(stdName, L"Link") == 0 || wcscmp(stdName, L"Quote") == 0) { // This is an inline element. parentNode->isBlock=false; } } // Get language. if (domElement->GetAttribute(L"Lang", NULL, &tempBstr) == S_OK && tempBstr) { parentNode->language = tempBstr; SysFreeString(tempBstr); } // Determine whether the text has underline or strikethrough. if (domElement->GetAttribute(L"TextDecorationType", L"Layout", &tempBstr) == S_OK && tempBstr) { if (wcscmp(tempBstr, L"Underline") == 0) textFlags |= TEXTFLAG_UNDERLINE; else if (wcscmp(tempBstr, L"LineThrough") == 0) textFlags |= TEXTFLAG_STRIKETHROUGH; SysFreeString(tempBstr); } } // If this node has no language, inherit it from its parent node. if (parentNode->language.empty()) { if (oldParentNode) parentNode->language = oldParentNode->language; // If this node was updated, we're rendering into a temporary buffer, // so try getting the parent from the old node. else if (oldNode && oldNode->getParent()) parentNode->language = static_cast<AdobeAcrobatVBufStorage_controlFieldNode_t*>(oldNode->getParent())->language; } //Get the child count int childCount=0; // We don't want to descend into lists and combo boxes. // Besides, Acrobat reports the child count, but the children can't be accessed. if (role != ROLE_SYSTEM_LIST && role != ROLE_SYSTEM_COMBOBOX) { LOG_DEBUG(L"get childCount with IAccessible::get_accChildCount"); if((res=pacc->get_accChildCount((long*)(&childCount)))!=S_OK) { LOG_DEBUG(L"pacc->get_accChildCount returned "<<res); childCount=0; } } LOG_DEBUG(L"childCount is "<<childCount); bool deletePageNum = false; if (!pageNum && (pageNum = this->getPageNum(domNode))) deletePageNum = true; #define addAttrsToTextNode(node) { \ node->addAttribute(L"language", parentNode->language); \ if (pageNum) \ node->addAttribute(L"page-number", *pageNum); \ } // Handle tables. if (role == ROLE_SYSTEM_TABLE) { tableInfo = new TableInfo; tableInfo->tableID = ID; tableInfo->curRowNumber = 0; tableInfo->curColumnNumber = 0; wostringstream s; s << ID; parentNode->addAttribute(L"table-id", s.str()); if (domElement && domElement->GetAttribute(L"Summary", L"Table", &tempBstr) == S_OK && tempBstr) { if (tempNode = buffer->addTextFieldNode(parentNode, previousNode, tempBstr)) { addAttrsToTextNode(tempNode); previousNode = tempNode; } SysFreeString(tempBstr); } } else if (role == ROLE_SYSTEM_ROW) { ++tableInfo->curRowNumber; tableInfo->curColumnNumber = 0; } else if (role == ROLE_SYSTEM_CELL || role == ROLE_SYSTEM_COLUMNHEADER || role == ROLE_SYSTEM_ROWHEADER) { ++tableInfo->curColumnNumber; handleColsSpannedByPrevRows(*tableInfo); wostringstream s; s << tableInfo->tableID; parentNode->addAttribute(L"table-id", s.str()); s.str(L""); s << tableInfo->curRowNumber; parentNode->addAttribute(L"table-rownumber", s.str()); s.str(L""); int startCol = tableInfo->curColumnNumber; s << startCol; parentNode->addAttribute(L"table-columnnumber", s.str()); if (domElement && domElement->GetAttribute(L"Headers", L"Table", &tempBstr) == S_OK && tempBstr) { // This node has explicitly defined headers. // Some of the referenced nodes might not be rendered yet, // so handle these later. // Note that IPDDomNode::GetFromID() doesn't work, but even if it did, // retrieving header info this way would probably be a bit slow. tableInfo->nodesWithExplicitHeaders.push_back(make_pair(parentNode, tempBstr)); SysFreeString(tempBstr); } else { map<int, wstring>::const_iterator headersIt; // Add implicit column headers for this cell. if ((headersIt = tableInfo->columnHeaders.find(startCol)) != tableInfo->columnHeaders.end()) parentNode->addAttribute(L"table-columnheadercells", headersIt->second); // Add implicit row headers for this cell. if ((headersIt = tableInfo->rowHeaders.find(tableInfo->curRowNumber)) != tableInfo->rowHeaders.end()) parentNode->addAttribute(L"table-rowheadercells", headersIt->second); } // The last row spanned by this cell. // This will be updated below if there is a row span. int endRow = tableInfo->curRowNumber; if (domElement) { if (domElement->GetAttribute(L"ColSpan", L"Table", &tempBstr) == S_OK && tempBstr) { parentNode->addAttribute(L"table-columnsspanned", tempBstr); tableInfo->curColumnNumber += max(_wtoi(tempBstr) - 1, 0); SysFreeString(tempBstr); } if (domElement->GetAttribute(L"RowSpan", L"Table", &tempBstr) == S_OK && tempBstr) { parentNode->addAttribute(L"table-rowsspanned", tempBstr); // Keep trakc of how many rows after this one are spanned by this cell. int span = _wtoi(tempBstr) - 1; if (span > 0) { // The row span needs to be recorded for each spanned column. for (int col = startCol; col <= tableInfo->curColumnNumber; ++col) tableInfo->columnRowSpans[col] = span; endRow += span; } SysFreeString(tempBstr); } } if (role == ROLE_SYSTEM_COLUMNHEADER || role == ROLE_SYSTEM_ROWHEADER) { int headerType = 0; if (domElement && domElement->GetAttribute(L"Scope", L"Table", &tempBstr) == S_OK && tempBstr) { if (wcscmp(tempBstr, L"Column") == 0) headerType = TABLEHEADER_COLUMN; else if (wcscmp(tempBstr, L"Row") == 0) headerType = TABLEHEADER_ROW; else if (wcscmp(tempBstr, L"Both") == 0) headerType = TABLEHEADER_COLUMN | TABLEHEADER_ROW; SysFreeString(tempBstr); } if (!headerType) headerType = (role == ROLE_SYSTEM_COLUMNHEADER) ? TABLEHEADER_COLUMN : TABLEHEADER_ROW; if (headerType & TABLEHEADER_COLUMN) { // Record this as a column header for each spanned column. s.str(L""); s << docHandle << L"," << ID << L";"; for (int col = startCol; col <= tableInfo->curColumnNumber; ++col) tableInfo->columnHeaders[col] += s.str(); } if (headerType & TABLEHEADER_ROW) { // Record this as a row header for each spanned row. s.str(L""); s << docHandle << L"," << ID << L";"; for (int row = tableInfo->curRowNumber; row <= endRow; ++row) tableInfo->rowHeaders[row] += s.str(); } if (domElement && domElement->GetID(&tempBstr) == S_OK && tempBstr) { // Record the id string and associated header info for use when handling explicitly defined headers. TableHeaderInfo& headerInfo = tableInfo->headersInfo[tempBstr]; headerInfo.uniqueId = ID; headerInfo.type = headerType; SysFreeString(tempBstr); } } } // Iterate through the children. if (childCount > 0) { LOG_DEBUG(L"Allocate memory to hold children"); VARIANT* varChildren; if((varChildren=(VARIANT*)malloc(sizeof(VARIANT)*childCount))==NULL) { LOG_DEBUG(L"Error allocating varChildren memory"); if (stdName) SysFreeString(stdName); return NULL; } LOG_DEBUG(L"Fetch children with AccessibleChildren"); if((res=AccessibleChildren(pacc,0,childCount,varChildren,(long*)(&childCount)))!=S_OK) { LOG_DEBUG(L"AccessibleChildren returned "<<res); childCount=0; } LOG_DEBUG(L"got "<<childCount<<L" children"); for(int i=0;i<childCount;++i) { LOG_DEBUG(L"child "<<i); if(varChildren[i].vt==VT_DISPATCH) { LOG_DEBUG(L"QueryInterface dispatch child to IID_IAccesible"); IAccessible* childPacc=NULL; if((res=varChildren[i].pdispVal->QueryInterface(IID_IAccessible,(void**)(&childPacc)))!=S_OK) { LOG_DEBUG(L"varChildren["<<i<<L"].pdispVal->QueryInterface to IID_iAccessible returned "<<res); childPacc=NULL; } if(childPacc) { if (this->isXFA) { // HACK: If this is an XFA document, we must call WindowFromAccessibleObject() so that AccessibleObjectFromEvent() will work for this node. HWND tempHwnd; WindowFromAccessibleObject(childPacc, &tempHwnd); } LOG_DEBUG(L"calling filVBuf with child object "); if ((tempNode = this->fillVBuf(docHandle, childPacc, buffer, parentNode, previousNode, NULL, tableInfo, pageNum))!=NULL) { previousNode=tempNode; } else { LOG_DEBUG(L"Error in calling fillVBuf"); } LOG_DEBUG(L"releasing child IAccessible object"); childPacc->Release(); } } VariantClear(&(varChildren[i])); } LOG_DEBUG(L"Freeing memory holding children"); free(varChildren); } else { // No children, so this is a leaf node. if (!this->isXFA && !stdName) { // Non-XFA leaf nodes with no stdName are inline. parentNode->isBlock=false; } // Get the name. BSTR name = NULL; if (states & STATE_SYSTEM_FOCUSABLE && (res = pacc->get_accName(varChild, &name)) != S_OK) { LOG_DEBUG(L"IAccessible::get_accName returned " << res); name = NULL; } if(name && SysStringLen(name) == 0) { SysFreeString(name); name = NULL; } bool useNameAsContent = role == ROLE_SYSTEM_LINK || role == ROLE_SYSTEM_PUSHBUTTON || role == ROLE_SYSTEM_RADIOBUTTON || role == ROLE_SYSTEM_CHECKBUTTON || role == ROLE_SYSTEM_GRAPHIC; if (name && !useNameAsContent) { parentNode->addAttribute(L"name", name); // Render the name before this node, // as the label is often not a separate node and thus won't be rendered into the buffer. // We can't do this if this node is being updated, // but in this case, the name has already been rendered before anyway. if (oldParentNode && (tempNode = buffer->addTextFieldNode(oldParentNode, parentNode->getPrevious(), name))) addAttrsToTextNode(tempNode); } // Hereafter, tempNode is the text node (if any). tempNode = NULL; if (role == ROLE_SYSTEM_RADIOBUTTON || role == ROLE_SYSTEM_CHECKBUTTON) { // Acrobat renders "Checked"/"Unchecked" as the text for radio buttons/check boxes, which is not what we want. // Render the name (if any) as the text for radio buttons and check boxes. if (name && (tempNode = buffer->addTextFieldNode(parentNode, previousNode, name))) addAttrsToTextNode(tempNode); } else tempNode = renderText(buffer, parentNode, previousNode, domNode, domElement, useNameAsContent, parentNode->language, textFlags, pageNum); if (tempNode) { // There was text. previousNode = tempNode; } if (name) SysFreeString(name); if (!tempNode && states & STATE_SYSTEM_FOCUSABLE) { // This node is focusable, but contains no text. // Therefore, add it with a space so that the user can get to it. if (tempNode = buffer->addTextFieldNode(parentNode, previousNode, L" ")) { addAttrsToTextNode(tempNode); previousNode=tempNode; } } } // Finalise tables. if ((role == ROLE_SYSTEM_CELL || role == ROLE_SYSTEM_COLUMNHEADER || role == ROLE_SYSTEM_ROWHEADER) && parentNode->getLength() == 0) { // Always render a space for empty table cells. previousNode=buffer->addTextFieldNode(parentNode,previousNode,L" "); addAttrsToTextNode(previousNode); parentNode->isBlock=false; } else if (role == ROLE_SYSTEM_TABLE) { nhAssert(tableInfo); for (list<pair<AdobeAcrobatVBufStorage_controlFieldNode_t*, wstring>>::iterator it = tableInfo->nodesWithExplicitHeaders.begin(); it != tableInfo->nodesWithExplicitHeaders.end(); ++it) fillExplicitTableHeadersForCell(*it->first, docHandle, it->second, *tableInfo); wostringstream s; s << tableInfo->curRowNumber; parentNode->addAttribute(L"table-rowcount", s.str()); s.str(L""); s << tableInfo->curColumnNumber; parentNode->addAttribute(L"table-columncount", s.str()); delete tableInfo; } if (deletePageNum) delete pageNum; if (stdName) SysFreeString(stdName); if (domElement) { LOG_DEBUG(L"Releasing IPDDomElement"); domElement->Release(); } if (domNode) { LOG_DEBUG(L"Releasing IPDDomNode"); domNode->Release(); } LOG_DEBUG(L"Releasing IServiceProvider"); servprov->Release(); #undef addAttrsToTextNode LOG_DEBUG(L"Returning node at "<<parentNode); return parentNode; }
void CDeskBand::Rename(HWND hwnd, const std::map<std::wstring, ULONG>& items) { // fill the list of selected file/foldernames m_filelist.clear(); if (items.size() > 1) { for (std::map<std::wstring, ULONG>::const_iterator it = items.begin(); it != items.end(); ++it) { size_t pos = it->first.find_last_of('\\'); if (pos != std::wstring::npos) { m_filelist.insert(it->first.substr(pos+1)); } } } else if (items.size() == 1) { for (std::map<std::wstring, ULONG>::const_iterator it = items.begin(); it != items.end(); ++it) { size_t pos = it->first.find_last_of('\\'); if (pos != std::wstring::npos) { m_filelist.insert(it->first.substr(pos+1)); } } } else { // no files or only one file were selected. // use all files and folders in the current folder instead IServiceProvider * pServiceProvider = NULL; if (SUCCEEDED(GetIServiceProvider(hwnd, &pServiceProvider))) { IShellBrowser * pShellBrowser; if (SUCCEEDED(pServiceProvider->QueryService(SID_SShellBrowser, IID_IShellBrowser, (LPVOID*)&pShellBrowser))) { IShellView * pShellView; if (SUCCEEDED(pShellBrowser->QueryActiveShellView(&pShellView))) { IFolderView * pFolderView; if (SUCCEEDED(pShellView->QueryInterface(IID_IFolderView, (LPVOID*)&pFolderView))) { // hooray! we got the IFolderView interface! // that means the explorer is active and well :) // but we also need the IShellFolder interface because // we need its GetCurFolder() method IPersistFolder2 * pPersistFolder; if (SUCCEEDED(pFolderView->GetFolder(IID_IPersistFolder2, (LPVOID*)&pPersistFolder))) { LPITEMIDLIST folderpidl; if (SUCCEEDED(pPersistFolder->GetCurFolder(&folderpidl))) { // we have the current folder TCHAR buf[MAX_PATH] = {0}; // find the path of the folder if (SHGetPathFromIDList(folderpidl, buf)) { m_currentDirectory = buf; } // if m_currentDirectory is empty here, that means // the current directory is a virtual path IShellFolder * pShellFolder; if (SUCCEEDED(pPersistFolder->QueryInterface(IID_IShellFolder, (LPVOID*)&pShellFolder))) { // find all selected items IEnumIDList * pEnum; if (SUCCEEDED(pFolderView->Items(SVGIO_ALLVIEW, IID_IEnumIDList, (LPVOID*)&pEnum))) { LPITEMIDLIST pidl; WCHAR buf[MAX_PATH] = {0}; ULONG fetched = 0; ULONG attribs = 0; do { pidl = NULL; if (SUCCEEDED(pEnum->Next(1, &pidl, &fetched))) { if (fetched) { // the pidl we get here is relative! attribs = SFGAO_FILESYSTEM|SFGAO_FOLDER; if (SUCCEEDED(pShellFolder->GetAttributesOf(1, (LPCITEMIDLIST*)&pidl, &attribs))) { if (attribs & SFGAO_FILESYSTEM) { // create an absolute pidl with the pidl we got above LPITEMIDLIST abspidl = CPidl::Append(folderpidl, pidl); if (abspidl) { if (SHGetPathFromIDList(abspidl, buf)) { std::wstring p = buf; size_t pos = p.find_last_of('\\'); if (pos != std::wstring::npos) { m_filelist.insert(p.substr(pos+1)); } } CoTaskMemFree(abspidl); } } } } CoTaskMemFree(pidl); } } while(fetched); pEnum->Release(); } pShellFolder->Release(); } CoTaskMemFree(folderpidl); } pPersistFolder->Release(); } pFolderView->Release(); } pShellView->Release(); } pShellBrowser->Release(); } pServiceProvider->Release(); } } // show the rename dialog m_bDialogShown = TRUE; CRenameDlg dlg(hwnd); dlg.SetFileList(m_filelist); if (dlg.DoModal(g_hInst, IDD_RENAMEDLG, hwnd, NULL) == IDOK) { try { const std::tr1::wregex regCheck(dlg.GetMatchString(), dlg.GetRegexFlags()); NumberReplaceHandler handler(dlg.GetReplaceString()); // start renaming the files IServiceProvider * pServiceProvider = NULL; if (SUCCEEDED(GetIServiceProvider(hwnd, &pServiceProvider))) { IShellBrowser * pShellBrowser; if (SUCCEEDED(pServiceProvider->QueryService(SID_SShellBrowser, IID_IShellBrowser, (LPVOID*)&pShellBrowser))) { IShellView * pShellView; if (SUCCEEDED(pShellBrowser->QueryActiveShellView(&pShellView))) { IFolderView * pFolderView; if (SUCCEEDED(pShellView->QueryInterface(IID_IFolderView, (LPVOID*)&pFolderView))) { // hooray! we got the IFolderView interface! // that means the explorer is active and well :) // but we also need the IShellFolder interface because // we need its GetDisplayNameOf() method IPersistFolder2 * pPersistFolder; if (SUCCEEDED(pFolderView->GetFolder(IID_IPersistFolder2, (LPVOID*)&pPersistFolder))) { IShellFolder * pShellFolder; if (SUCCEEDED(pPersistFolder->QueryInterface(IID_IShellFolder, (LPVOID*)&pShellFolder))) { // our next task is to enumerate all the // items in the folder view and select those // which match the text in the edit control int nCount = 0; if (SUCCEEDED(pFolderView->ItemCount(SVGIO_ALLVIEW, &nCount))) { for (int i=0; i<nCount; ++i) { LPITEMIDLIST pidl; if (SUCCEEDED(pFolderView->Item(i, &pidl))) { STRRET str; if (SUCCEEDED(pShellFolder->GetDisplayNameOf(pidl, // SHGDN_FORPARSING needed to get the extensions even if they're not shown SHGDN_INFOLDER|SHGDN_FORPARSING, &str))) { TCHAR dispname[MAX_PATH]; StrRetToBuf(&str, pidl, dispname, _countof(dispname)); std::wstring replaced; try { std::wstring sDispName = dispname; // check if the item is in the list of selected items if (m_filelist.find(sDispName) != m_filelist.end()) { replaced = std::tr1::regex_replace(sDispName, regCheck, dlg.GetReplaceString()); replaced = handler.ReplaceCounters(replaced); if (replaced.compare(sDispName)) { ITEMIDLIST * pidlrenamed; pShellFolder->SetNameOf(NULL, pidl, replaced.c_str(), SHGDN_FORPARSING|SHGDN_INFOLDER, &pidlrenamed); // if the rename was successful, select the renamed item if (pidlrenamed) pFolderView->SelectItem(i, SVSI_CHECK|SVSI_SELECT); } } } catch (std::exception) { } } CoTaskMemFree(pidl); } } } pShellFolder->Release(); } pPersistFolder->Release(); } pFolderView->Release(); } pShellView->Release(); } pShellBrowser->Release(); } pServiceProvider->Release(); } } catch (std::exception) { } } m_bDialogShown = FALSE; }
HRESULT HandleNoRightsEx( HRESULT hrStatus, WM_GET_LICENSE_DATA * pLicenseData ) { HRESULT hr = S_OK; BOOL fMonitoring = FALSE; BSTR bstrURL = NULL; if((NULL == pLicenseData) || (NULL == pLicenseData->wszLocalFilename)) { return E_INVALIDARG; } if (FAILED(hrStatus) && (NS_E_DRM_NO_RIGHTS != hrStatus)) { Msg(TEXT("Unable to obtain proper license!! Aborting playback...\r\n")); hr = hrStatus; return hr; } if( TRUE ) { IServiceProvider *pServiceProvider; JIF(g_pReader->QueryInterface(IID_IServiceProvider, (void **) &pServiceProvider)); JIF(pServiceProvider->QueryService(IID_IWMDRMReader, IID_IWMDRMReader, (void **) &g_pDRMReader)); pServiceProvider->Release(); // do silent license acquisition hr = g_pDRMReader->AcquireLicense(TRUE); if (FAILED(hr)) { Msg(TEXT("AcquireLicense Failed! hr=0x%x\n"), hr); SAFE_RELEASE(g_pDRMReader); return hr; } } else // non-silent acquisition { // convert wszs to bstrs so we can pass them to core bstrURL = SysAllocString(pLicenseData->wszLocalFilename); if (!bstrURL) { hr = E_OUTOFMEMORY; } else { // start license monitoring hr = g_pDRMReader->MonitorLicenseAcquisition(); if (FAILED(hr)) { // wmp explicitly ignores hr here g_pDRMReader->CancelMonitorLicenseAcquisition(); } else { fMonitoring = true; } SysFreeString(bstrURL); } } SAFE_RELEASE(g_pDRMReader); return hr; }
// IExecuteCommandApplicationHostEnvironment IFACEMETHODIMP GetValue(AHE_TYPE *aLaunchType) { Log(L"IExecuteCommandApplicationHostEnvironment::GetValue()"); *aLaunchType = AHE_DESKTOP; mIsDesktopRequest = true; if (!mUnkSite) { Log(L"No mUnkSite."); return S_OK; } HRESULT hr; IServiceProvider* pSvcProvider = NULL; hr = mUnkSite->QueryInterface(IID_IServiceProvider, (void**)&pSvcProvider); if (!pSvcProvider) { Log(L"Couldn't get IServiceProvider service from explorer. (%X)", hr); return S_OK; } IExecuteCommandHost* pHost = NULL; // If we can't get this it's a conventional desktop launch hr = pSvcProvider->QueryService(SID_ExecuteCommandHost, IID_IExecuteCommandHost, (void**)&pHost); if (!pHost) { Log(L"Couldn't get IExecuteCommandHost service from explorer. (%X)", hr); SafeRelease(&pSvcProvider); return S_OK; } SafeRelease(&pSvcProvider); EC_HOST_UI_MODE mode; if (FAILED(pHost->GetUIMode(&mode))) { Log(L"GetUIMode failed."); SafeRelease(&pHost); return S_OK; } // 0 - launched from desktop // 1 - ? // 2 - launched from tile interface Log(L"GetUIMode: %d", mode); if (!IsDefaultBrowser()) { mode = ECHUIM_DESKTOP; } if (mode == ECHUIM_DESKTOP) { Log(L"returning AHE_DESKTOP"); SafeRelease(&pHost); return S_OK; } SafeRelease(&pHost); if (!IsDX10Available()) { Log(L"returning AHE_DESKTOP because DX10 is not available"); *aLaunchType = AHE_DESKTOP; mIsDesktopRequest = true; } else { Log(L"returning AHE_IMMERSIVE"); *aLaunchType = AHE_IMMERSIVE; mIsDesktopRequest = false; } return S_OK; }
bool CDeskBand::Filter(LPTSTR filter) { bool bReturn = false; IServiceProvider * pServiceProvider; if (SUCCEEDED(m_pSite->QueryInterface(IID_IServiceProvider, (LPVOID*)&pServiceProvider))) { IShellBrowser * pShellBrowser; if (SUCCEEDED(pServiceProvider->QueryService(SID_SShellBrowser, IID_IShellBrowser, (LPVOID*)&pShellBrowser))) { IShellView * pShellView; if (SUCCEEDED(pShellBrowser->QueryActiveShellView(&pShellView))) { IFolderView * pFolderView; if (SUCCEEDED(pShellView->QueryInterface(IID_IFolderView, (LPVOID*)&pFolderView))) { // hooray! we got the IFolderView interface! // that means the explorer is active and well :) IShellFolderView * pShellFolderView; if (SUCCEEDED(pShellView->QueryInterface(IID_IShellFolderView, (LPVOID*)&pShellFolderView))) { // the first thing we do is to deselect all already selected entries pFolderView->SelectItem(NULL, SVSI_DESELECTOTHERS); // but we also need the IShellFolder interface because // we need its GetDisplayNameOf() method IPersistFolder2 * pPersistFolder; if (SUCCEEDED(pFolderView->GetFolder(IID_IPersistFolder2, (LPVOID*)&pPersistFolder))) { LPITEMIDLIST curFolder; pPersistFolder->GetCurFolder(&curFolder); if (ILIsEqual(m_currentFolder, curFolder)) { CoTaskMemFree(curFolder); } else { CoTaskMemFree(m_currentFolder); m_currentFolder = curFolder; for (size_t i=0; i<m_noShows.size(); ++i) { CoTaskMemFree(m_noShows[i]); } m_noShows.clear(); } IShellFolder * pShellFolder; if (SUCCEEDED(pPersistFolder->QueryInterface(IID_IShellFolder, (LPVOID*)&pShellFolder))) { // our next task is to enumerate all the // items in the folder view and select those // which match the text in the edit control bool bUseRegex = (filter[0] == '\\'); try { const std::tr1::wregex regCheck(&filter[1], std::tr1::regex_constants::icase | std::tr1::regex_constants::ECMAScript); } catch (std::exception) { bUseRegex = false; } if (!bUseRegex) { // force the filter to lowercase TCHAR * pString = filter; while (*pString) { *pString = _totlower(*pString); pString++; } } int nCount = 0; if (SUCCEEDED(pFolderView->ItemCount(SVGIO_ALLVIEW, &nCount))) { pShellFolderView->SetRedraw(FALSE); HWND listView = GetListView32(pShellView); LRESULT viewType = 0; if (listView) { // inserting items in the list view if the list view is set to // e.g., LV_VIEW_LIST is painfully slow. So save the current view // and set it to LV_VIEW_DETAILS (which is much faster for inserting) // and restore the view after we're done. viewType = SendMessage(listView, LVM_GETVIEW, 0, 0); SendMessage(listView, LVM_SETVIEW, LV_VIEW_DETAILS, 0); } std::vector<LPITEMIDLIST> noShows; for (int i=0; i<nCount; ++i) { LPITEMIDLIST pidl; if (SUCCEEDED(pFolderView->Item(i, &pidl))) { if (CheckDisplayName(pShellFolder, pidl, filter, bUseRegex)) { // remove now shown items which are in the no-show list // this is necessary since we don't get a notification // if the shell refreshes its view for (std::vector<LPITEMIDLIST>::iterator it = m_noShows.begin(); it != m_noShows.end(); ++it ) { if (HRESULT_CODE(pShellFolder->CompareIDs(SHCIDS_CANONICALONLY, *it, pidl))==0) { m_noShows.erase(it); break; } } CoTaskMemFree(pidl); } else { UINT puItem = 0; if (pShellFolderView->RemoveObject(pidl, &puItem) == S_OK) { i--; nCount--; noShows.push_back(pidl); } } } } // now add all those items again which were removed by a previous filter string // but don't match this new one //pShellFolderView->SetObjectCount(5000, SFVSOC_INVALIDATE_ALL|SFVSOC_NOSCROLL); for (size_t i=0; i<m_noShows.size(); ++i) { LPITEMIDLIST pidlNoShow = m_noShows[i]; if (CheckDisplayName(pShellFolder, pidlNoShow, filter, bUseRegex)) { m_noShows.erase(m_noShows.begin() + i); i--; UINT puItem = (UINT)i; pShellFolderView->AddObject(pidlNoShow, &puItem); CoTaskMemFree(pidlNoShow); } } for (size_t i=0; i<noShows.size(); ++i) { m_noShows.push_back(noShows[i]); } if (listView) { SendMessage(listView, LVM_SETVIEW, viewType, 0); } pShellFolderView->SetRedraw(TRUE); } pShellFolder->Release(); } pPersistFolder->Release(); } pShellFolderView->Release(); } pFolderView->Release(); } pShellView->Release(); } pShellBrowser->Release(); } pServiceProvider->Release(); } return bReturn; }
/** * Saves a rendering of the current site by its host container as a PNG file. * This implementation is derived from IECapt. * * @param outputFile the file to save the PNG output as * @link http://iecapt.sourceforge.net/ */ STDMETHODIMP CCoSnapsie::saveSnapshot( BSTR outputFile, BSTR frameId, LONG drawableScrollWidth, LONG drawableScrollHeight, LONG drawableClientWidth, LONG drawableClientHeight, LONG drawableClientLeft, LONG drawableClientTop, LONG frameBCRLeft, LONG frameBCRTop) { HRESULT hr; HWND hwndBrowser; CComPtr<IOleClientSite> spClientSite; CComQIPtr<IServiceProvider> spISP; CComPtr<IWebBrowser2> spBrowser; CComPtr<IDispatch> spDispatch; CComQIPtr<IHTMLDocument2> spDocument; CComPtr<IHTMLWindow2> spScrollableWindow; CComQIPtr<IViewObject2> spViewObject; CComPtr<IHTMLStyle> spStyle; CComQIPtr<IHTMLElement2> spScrollableElement; CComVariant documentHeight; CComVariant documentWidth; CComVariant viewportHeight; CComVariant viewportWidth; GetSite(IID_IUnknown, (void**)&spClientSite); if (spClientSite == NULL) { Error(L"There is no site."); return E_FAIL; } spISP = spClientSite; if (spISP == NULL) { Error(L"Unable to convert client site to service provider."); return E_FAIL; } // from http://support.microsoft.com/kb/257717 hr = spISP->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void **)&spBrowser); if (FAILED(hr)) { // if we can't query the client site for IWebBrowser2, we're probably // in an HTA. Obtain the IHTMLWindow2 interface pointer by directly // querying the client site's service provider. // http://groups.google.com/group/microsoft.public.vc.language/browse_thread/thread/f8987a31d47cccfe/884cb8f13423039e CComPtr<IHTMLWindow2> spWindow; hr = spISP->QueryService(IID_IHTMLWindow2, &spWindow); if (FAILED(hr)) { Error("Failed to obtain IHTMLWindow2 from service provider"); return E_FAIL; } hr = spWindow->get_document(&spDocument); if (FAILED(hr)) { Error("Failed to obtain IHTMLDocument2 from window"); return E_FAIL; } CComQIPtr<IOleWindow> spOleWindow = spDocument; if (spOleWindow == NULL) { Error("Failed to obtain IOleWindow from document"); return E_FAIL; } hr = spOleWindow->GetWindow(&hwndBrowser); if (FAILED(hr)) { Error("Failed to obtain HWND from OLE window"); return E_FAIL; } hwndBrowser = GetAncestor(hwndBrowser, GA_ROOTOWNER); } else { hr = spBrowser->get_HWND((long*)&hwndBrowser); if (FAILED(hr)) { Error("Failed to get HWND for browser (is this a frame?)"); return E_FAIL; } ie = GetAncestor(hwndBrowser, GA_ROOTOWNER); CComPtr<IDispatch> spDispatch; hr = spBrowser->get_Document(&spDispatch); if (FAILED(hr)) return E_FAIL; spDocument = spDispatch; if (spDocument == NULL) return E_FAIL; IServiceProvider* pServiceProvider = NULL; if (SUCCEEDED(spBrowser->QueryInterface( IID_IServiceProvider, (void**)&pServiceProvider))) { IOleWindow* pWindow = NULL; if (SUCCEEDED(pServiceProvider->QueryService( SID_SShellBrowser, IID_IOleWindow, (void**)&pWindow))) { if (SUCCEEDED(pWindow->GetWindow(&hwndBrowser))) { hwndBrowser = FindWindowEx(hwndBrowser, NULL, _T("Shell DocObject View"), NULL); if (hwndBrowser) { hwndBrowser = FindWindowEx(hwndBrowser, NULL, _T("Internet Explorer_Server"), NULL); } } pWindow->Release(); } pServiceProvider->Release(); } } // Nobody else seems to know how to get IViewObject2?! // http://starkravingfinkle.org/blog/2004/09/ spViewObject = spDocument; if (spViewObject == NULL) { Error(L"Unable to convert document to view object."); return E_FAIL; } CComQIPtr<IHTMLDocument5> spDocument5; spDocument->QueryInterface(IID_IHTMLDocument5, (void**)&spDocument5); if (spDocument5 == NULL) { Error(L"Snapsie requires IE6 or greater."); return E_FAIL; } CComBSTR compatMode; spDocument5->get_compatMode(&compatMode); // In non-standards-compliant mode, the BODY element represents the canvas. if (compatMode == L"BackCompat") { CComPtr<IHTMLElement> spBody; spDocument->get_body(&spBody); if (NULL == spBody) { return E_FAIL; } spBody->getAttribute(CComBSTR("scrollHeight"), 0, &documentHeight); spBody->getAttribute(CComBSTR("scrollWidth"), 0, &documentWidth); spBody->getAttribute(CComBSTR("clientHeight"), 0, &viewportHeight); spBody->getAttribute(CComBSTR("clientWidth"), 0, &viewportWidth); } // In standards-compliant mode, the HTML element represents the canvas. else { CComQIPtr<IHTMLDocument3> spDocument3; spDocument->QueryInterface(IID_IHTMLDocument3, (void**)&spDocument3); if (NULL == spDocument3) { Error(L"Unable to get IHTMLDocument3 handle from document."); return E_FAIL; } // The root node should be the HTML element. CComPtr<IHTMLElement> spRootNode; spDocument3->get_documentElement(&spRootNode); if (NULL == spRootNode) { Error(L"Could not retrieve root node."); return E_FAIL; } CComPtr<IHTMLHtmlElement> spHtml; spRootNode->QueryInterface(IID_IHTMLHtmlElement, (void**)&spHtml); if (NULL == spHtml) { Error(L"Root node is not the HTML element."); return E_FAIL; } spRootNode->getAttribute(CComBSTR("scrollHeight"), 0, &documentHeight); spRootNode->getAttribute(CComBSTR("scrollWidth"), 0, &documentWidth); spRootNode->getAttribute(CComBSTR("clientHeight"), 0, &viewportHeight); spRootNode->getAttribute(CComBSTR("clientWidth"), 0, &viewportWidth); } // Figure out how large to make the window. It's not sufficient to just use the dimensions of the scrolled // viewport because the browser chrome occupies space that must be accounted for as well. RECT ieWindowRect; GetWindowRect(ie, &ieWindowRect); int ieWindowWidth = ieWindowRect.right - ieWindowRect.left; int ieWindowHeight = ieWindowRect.bottom - ieWindowRect.top; RECT contentClientRect; GetClientRect(hwndBrowser, &contentClientRect); int contentClientWidth = contentClientRect.right - contentClientRect.left; int contentClientHeight = contentClientRect.bottom - contentClientRect.top; int chromeWidth = ieWindowWidth - contentClientWidth; int chromeHeight = 2 * (ieWindowHeight - contentClientHeight); int imageHeight = documentHeight.intVal; int imageWidth = documentWidth.intVal; maxWidth = imageWidth + chromeWidth; maxHeight = imageHeight + chromeHeight; long originalHeight, originalWidth; spBrowser->get_Height(&originalHeight); spBrowser->get_Width(&originalWidth); // The resize message is being ignored if the window appears to be maximized. There's likely a // way to bypass that. My ghetto way is to unmaximize the window, then move on with setting // the window to the dimensions we really want. This is okay because we revert back to the // original dimensions afterward. BOOL isMaximized = IsZoomed(ie); if (isMaximized) { ShowWindow(ie, SW_SHOWNORMAL); } // Get the path to this DLL so we can load it up with LoadLibrary. TCHAR dllPath[_MAX_PATH]; GetModuleFileName((HINSTANCE) &__ImageBase, dllPath, _MAX_PATH); // Get the path to the Windows hook we use to allow resizing the window greater than the virtual screen resolution. HINSTANCE hinstDLL = LoadLibrary(dllPath); HOOKPROC hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "CallWndProc"); if (hkprcSysMsg == NULL) PrintError(L"GetProcAddress"); // Install the Windows hook. nextHook = SetWindowsHookEx(WH_CALLWNDPROC, hkprcSysMsg, hinstDLL, 0); if (nextHook == 0) PrintError(L"SetWindowsHookEx"); spBrowser->put_Height(maxHeight); spBrowser->put_Width(maxWidth); // Capture the window's canvas to a DIB. CImage image; image.Create(imageWidth, imageHeight, 24); CImageDC imageDC(image); hr = PrintWindow(hwndBrowser, imageDC, PW_CLIENTONLY); if (FAILED(hr)) { Error(L"PrintWindow"); } // I'm not sure if PrintWindow captures alpha blending or not. OleDraw does, but I was having // issues with sizing the browser correctly between quirks and standards modes to capture everything we need. // //RECT rcBounds = { 0, 0, imageWidth, imageHeight }; //hr = OleDraw(spViewObject, DVASPECT_DOCPRINT, imageDC, &rcBounds); //if (FAILED(hr)) //{ // Error(L"OleDraw"); //} UnhookWindowsHookEx(nextHook); // Restore the browser to the original dimensions. if (isMaximized) { ShowWindow(ie, SW_MAXIMIZE); } else { spBrowser->put_Height(originalHeight); spBrowser->put_Width(originalWidth); } hr = image.Save(CW2T(outputFile)); if (FAILED(hr)) { PrintError(L"Failed saving image."); return E_FAIL; } return hr; }
STDMETHODIMP ExplorerBar::SetSite( IUnknown *inPunkSite ) { AFX_MANAGE_STATE( AfxGetStaticModuleState() ); HRESULT err; // Release the old interfaces. if( mWebBrowser ) { mWebBrowser->Release(); mWebBrowser = NULL; } if( mSite ) { mSite->Release(); mSite = NULL; } // A non-NULL site means we're setting the site. Otherwise, the site is being released (done above). if( !inPunkSite ) { err = S_OK; goto exit; } // Get the parent window. IOleWindow * oleWindow; mParentWindow = NULL; err = inPunkSite->QueryInterface( IID_IOleWindow, (LPVOID *) &oleWindow ); require( SUCCEEDED( err ), exit ); err = oleWindow->GetWindow( &mParentWindow ); oleWindow->Release(); require_noerr( err, exit ); require_action( mParentWindow, exit, err = E_FAIL ); // Get the IInputObject interface. err = inPunkSite->QueryInterface( IID_IInputObjectSite, (LPVOID *) &mSite ); require( SUCCEEDED( err ), exit ); check( mSite ); // Get the IWebBrowser2 interface. IOleCommandTarget * oleCommandTarget; err = inPunkSite->QueryInterface( IID_IOleCommandTarget, (LPVOID *) &oleCommandTarget ); require( SUCCEEDED( err ), exit ); IServiceProvider * serviceProvider; err = oleCommandTarget->QueryInterface( IID_IServiceProvider, (LPVOID *) &serviceProvider ); oleCommandTarget->Release(); require( SUCCEEDED( err ), exit ); err = serviceProvider->QueryService( SID_SWebBrowserApp, IID_IWebBrowser2, (LPVOID *) &mWebBrowser ); serviceProvider->Release(); require( SUCCEEDED( err ), exit ); // Create the main window. err = SetupWindow(); require_noerr( err, exit ); exit: return( err ); }